Migrate @cratis/components to PrimeReact 11 - #107
Conversation
Preserve in-progress migration of @cratis/components to PrimeReact 11: foundation (ESM-only packaging, @primereact/core provider, @primeuix/themes Storybook theming, tokens), the compositional Dialog stack, all 12 CommandForm fields, and the Select-based Dropdown wrapper. This is an intentional checkpoint commit: the not-yet-migrated widgets (DataTable, SchemaEditor, ObjectContentEditor, TimeMachine, Tooltip, Stepper) still reference removed v10 paths, so `tsc -b` reports 85 errors confined to those files. Remaining phases (5-9) follow in subsequent commits that each restore a clean build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 5 of the PrimeReact 11 migration. - Rebuild CommandStepper on the v11 compositional Stepper (Stepper.Root/List/Step/Header/Number/Title/Separator/Panels/Panel), driven by a controlled `value` + `onValueChange`. - Add a Cratis-owned StepperPanel marker to replace the removed `primereact/stepperpanel`; the stepper reads each panel's header and children to build the step list and content panels. - Replace the leaked `StepperCustomizationProps = Pick<StepperProps,…>` with a wrapper-owned type; drop the v10-only orientation/headerPosition/ start/end slots that have no v11 equivalent. - Re-express the per-step red/green error indicator directly on each Stepper.Number's style instead of the v10 pt.stepperpanel.number hook. - Switch StepperCommandDialog off raw PrimeDialog onto the Cratis Dialog wrapper, and convert every Button to v11 children + variant. - Add an additive `dismissable` prop to the Cratis Dialog so a custom-footer wizard keeps its header-close affordance. - Update the stepper stories and the four StepperCommandDialog specs to the v11 component shapes (Cratis Dialog + Stepper parts + children Buttons). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 6 of the PrimeReact 11 migration.
- Rebuild Common/Tooltip on PrimeReact 11's compositional Tooltip
(Root/Trigger/Portal/Positioner/Popup), portaled to the document body so
it is no longer clipped by overflow containers — the reason the old code
reached for the (now removed) data-pr-tooltip directive. Public API
(content/position/children) is preserved; content is now optional so
`content={condition ? text : undefined}` renders the child with no tooltip,
and a trigger className is accepted for full-width children.
- Migrate SchemaEditor/NameCell off the removed data-pr-tooltip directive to
the Tooltip wrapper.
- Add a Tooltip Storybook story.
The remaining data-pr-tooltip consumers (TypeCell, SchemaEditor,
ObjectContentEditor) also depend on other removed v11 APIs (Dropdown, Button
props, DataTable, Menubar, Calendar), so their tooltip migration ships with
their full-file rebuilds in the DataTable and remaining-wrapper phases.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 7 (part 1) of the PrimeReact 11 migration. PrimeReact 11's DataTable is a fully headless compositional table (Root only provides context; the scaffold is built by hand) and the monolithic v10 props are gone. Rebuild the Cratis data tables on it: - Add DataTableCore, a shared query-agnostic table that reads `<Column>` children and renders the v11 headless Root/Table/THead/TBody/Cell scaffold, including sortable headers and an empty-state body. Rows come in via `data` (v11 renamed the old `value` prop, which now means the sort field). - Translate v11's key-based selection (`Record<String(row[dataKey]), boolean>`) back to the row-object selection API callers expect, via a new DataTableSelectionChangeEvent replacing the removed DataTableSelectionSingleChangeEvent. - Add a Cratis Column marker replacing the removed `primereact/column`, and a small TablePaginator (PrimeReact 11's Paginator is a headless slot; paging is still driven by Arc's paging hook). - Rebuild DataTableForQuery and DataTableForObservableQuery on DataTableCore + TablePaginator, preserving their public props (selection, dataKey, globalFilterFields, scrollable, pt/unstyled). Per-column filter-menu UI (which no column in the library opted into) is not carried over. - Retype pt/ptOptions off the v11 DataTableRootProps; export Column and the new event/filter types; update the two DataTable stories. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 7 (part 2) of the PrimeReact 11 migration. - Add ActionMenubar, a small command toolbar that replaces the removed PrimeReact Menubar. PrimeReact 11 has no menubar and NavigationMenu is built for navigation, not command actions, so a focused button bar driven by the same `model` shape is the better fit for these action bars. - Migrate DataPage onto ActionMenubar and the headless DataTables, replacing the removed DataTableSelectionSingleChangeEvent / DataTableFilterMeta / DataTableProps types with the Cratis equivalents, and re-export Column from the DataPage subpath. - Rebuild SchemaEditor on DataTableCore + ActionMenubar + the Cratis Tooltip wrapper, and convert its and TypeCell's buttons to PrimeReact 11 (children + variant/iconOnly), TypeCell's dropdowns to the Cratis Dropdown, and both files' tooltips off the removed data-pr-tooltip directive. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 8 of the PrimeReact 11 migration. - ObjectContentEditor: move its boolean/number/date/long-text editors onto the PrimeReact 11 compositional Checkbox and InputNumber, the renamed Textarea (was InputTextarea), and the shared DatePickerInput (was the removed primereact/calendar), and its info-icon tooltip onto the Cratis Tooltip wrapper (off the removed data-pr-tooltip directive). - Extract DatePickerInput, a wrapper-owned Date value/onChange picker that assembles the compositional DatePicker once, and refactor CalendarField to reuse it instead of duplicating the ~45-line composition. - ObjectNavigationalBar: convert its back button to a PrimeReact 11 icon button (children + iconOnly) wrapped in the Cratis Tooltip. - TimeMachine/EventsView: rebuild the Timeline on the v11 compositional Timeline (Root + Event/Separator/Marker/Connector/Content) mapping each event into the parts, replacing the removed monolithic value/content/marker props. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 9 of the PrimeReact 11 migration. - Fix the rollup config still referencing the removed `cjsPath` in the ESM-only build's plugin wiring, which crashed `yarn build`. - Stop destructuring the compat-only `resizable` prop in the Dialog (it has no effect on PrimeReact 11's headless dialog), clearing an unused-var lint error. - Correct the `Common/Tooltip` mock path in four Toolbar specs — it was off by one directory level, so the mock never intercepted the real Tooltip; harmless while Tooltip was CSS-only, but the PrimeReact 11 Tooltip needs a provider and the real component now throws in server-rendered specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 9 of the PrimeReact 11 migration.
- Bump @cratis/components to 0.2.0 for the breaking ESM-only packaging and
API changes (label the PR major per the framework backward-compat policy).
- README: replace the removed `primereact/resources/themes/*/theme.css`
imports with the PrimeReact 11 `@primeuix/themes` preset applied via
`CratisComponentsProvider theme={{ preset }}`, and note the unstyled-first
default.
- .ai docs/skills: point `Column` imports at `@cratis/components/DataPage`
and `StepperPanel` at `@cratis/components/CommandDialog` (the removed
`primereact/column` / `primereact/stepperpanel`), and replace the removed
`primereact/menubar` list-page example with a Button toolbar plus a pointer
to DataPage's action bar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase 9 of the PrimeReact 11 migration. Update the Storybook-only Tailwind pt preset to PrimeReact 11 component keys: rename dropdown → select (with the v11 value/dropdown/popup/option slots), inputtextarea → textarea, and drop the menubar preset (Menubar was removed; the Cratis action bar is a Button toolbar styled through the button slot). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A `<Column selectionMode="single" />` column rendered an empty cell after the headless rebuild — row-click selection worked, but the per-row radio the v10 DataTable drew was gone. Render a radio that reflects the selected row so the selection column keeps its familiar affordance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PrimeReact 11's compositional Stepper dropped the v10 orientation / start / end / headerPosition props, and the earlier migration removed them from the Cratis wrapper. Reimplement them over the compositional parts so the wizard keeps full capability parity (and works regardless of theme): - orientation="vertical" lays the step list out as a stacked column beside the panels (CSS keyed on the wrapper's orientation class); horizontal stays the default. - headerPosition="bottom" renders the panels above the step-header row. - start / end render arbitrary content before / after the stepper (e.g. a logo or title). Threaded through CommandStepper and StepperCommandDialog, plus a Vertical story. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PrimeReact 11's headless DataTable manages filter state and applies the actual row filtering (client-side, like sorting), but renders none of the v10 filterDisplay="menu" chrome. Rebuild that chrome and add a search box: - Add ColumnFilterMenu: a filter icon per filterable column header that opens a popover (primereact/popover) with a match-mode selector, a typed value input (text / number / date / boolean), and Clear / Apply — wired to the headless DataTable.Filter render-prop, with the popover's open state bound to the filter's overlay state so the draft re-seeds correctly. - Column gains filter / filterField / filterPlaceholder / dataType / showFilterMatchModes; DataTableCore controls the filters state, seeds it from defaultFilters, and renders a filter menu for any column with `filter`. - Add an optional global search box (shown when globalFilterFields is set) that filters across those fields — a capability the v10 table did not surface. - Wire defaultFilters through both query tables; demonstrate in the DataTableForQuery and DataPage stories. Restores full v10 filtering parity and then some. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Show "X–Y of Z" in the paginator when the total record count and page size are available, so users see where they are in the full result set — a detail the minimal first/prev/next/last paginator lacked. Both query tables pass it through from the Arc paging result. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ProgressBar) Add a Display component group with token-consistent Cratis wrappers over PrimeReact 11's Tag, Badge, Chip (compositional), Skeleton, Avatar (compositional), and ProgressBar (compositional): - Tag / Badge — colored status + count indicators (severity tones) for tables, lists, and detail views. - Chip — labeled, optionally removable pills. - Skeleton — loading placeholders to pair with query isPerforming. - Avatar — image with initials/icon fallback. - ProgressBar — determinate/indeterminate progress. Exposed as the `@cratis/components/Display` subpath, with an overview story. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Notifications group built on PrimeReact 11's headless Toaster/Toast: - Toaster: the single app-wide toast host — mount one <Toaster /> near the app root. Reads the live toasts from the module-level store and renders each with a per-severity icon, title, description, and an auto-wired close button; the auto-dismiss timer is handled by the primitives. Ships baseline token-based styling (severity-colored cards) so notifications look right before a theme preset is applied. - toast: the imperative API (toast.success/info/warn/error/promise/dismiss), callable from anywhere including outside React. - toastCommandResult: surfaces an Arc ICommandResult as a toast, mapping the granular flags to severities — success, not-authorized (warn), validation (error with per-field messages), and exceptions (generic error; stack traces are never shown). The Arc-native way to give command feedback outside a CommandDialog. Exposed as the `@cratis/components/Notifications` subpath, with a story. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Round out the CommandForm field catalog with three more first-class fields, each wired through asCommandFormField so they participate in validation and change tracking like the built-ins: - PasswordField — a masked password input with a show/hide toggle (string). - ToggleSwitchField — a boolean on/off switch, the toggle counterpart of CheckboxField. - RatingField — a star-rating input (number). Exported from @cratis/components/CommandForm, with a bound story. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@einari — ready for your review. 👀 This is the PrimeReact 10 → 11 migration of
The one strategic thing I'd value your call on is licensing (full details in the PR description): PrimeReact 11 gates the styled All gates are green ( Not merging — over to you for feedback. 🙏 |
- MIGRATION.md: a v0.1 → v0.2 upgrade guide for consuming apps — the ESM-only note, the removed-import find-and-replace table (column/stepperpanel/menubar/ dropdown), the selection-event rename, the theming change (preset or the upcoming Cratis baseline theme), and the licensing summary. - Extract the data-table selection translation (selectionKeysForRow / rowFromSelectionKeys) and the paginator range formatter (paginatorRange) into pure, testable helpers, and use them from DataTableCore / TablePaginator. - Add BDD specs: toastCommandResult across every result outcome (success, suppressed, unauthorized, validation with per-field messages, exceptions with no leaked stack trace), the selection key↔row translation, and the paginator range boundaries. 209 specs pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PrimeReact 11's good-looking styled presets are gated behind a PrimeUI license, which left the license-free (unstyled) path looking plain. Add a token-based baseline theme so apps get a polished default look with no license. - theme.css: styles every component from the --cratis-* token layer (buttons, inputs, checkbox/radio/toggle/slider, select, dialog, datatable, tag/badge/ chip/avatar/progressbar/skeleton, stepper), scoped under `.cratis-theme` with light + dark palettes. It supplies concrete colors that defer to a preset's --p-* tokens when one is present, so the license-free path finally resolves. - Exposed as the `@cratis/components/theme` subpath (shipped by copy-css). - Surface `data-severity` on Tag/Badge so severity coloring works unstyled. - Repurpose the Storybook `cratis-theme` mode to demo it (unstyled, no license), and document it in the README. Verified in Storybook: Display, form fields, DataTable, and Stepper all render cleanly styled with no PrimeUI license. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Teach consumers and AI about the surface added in this migration: - components.md: Notifications (Toaster/toast/toastCommandResult) and Display (Tag/Badge/Chip/Skeleton/Avatar/ProgressBar) subpaths, the new CommandForm fields, and column filtering / global search. - react.md: point the out-of-dialog command branch at toastCommandResult. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ran axe against the new components/theme and fixed what's in our control: - Use WCAG-AA-safe (darker) filled backgrounds for buttons, badges, severity tags, and the progress bar in the baseline theme, and lift the dark-mode secondary text — clearing every color-contrast violation on the toaster, Display, and DataPage stories. - Give the Chip remove control a role so its aria-label is valid. - Strip the invalid aria-sort PrimeReact 11 emits on the data-table sort button (aria-sort belongs on the column header, not a role=button), clearing that critical violation. - Add a navigation landmark to the table paginator. DX: `CratisComponentsProvider` gains an optional `toaster` prop that mounts a `<Toaster />` so `toast(...)` works app-wide with no extra setup. Known upstream: PrimeReact 11's Stepper marks its headers role="tab" and points aria-controls at conditionally-rendered panels; that ARIA model is the framework's and not fully axe-clean, though keyboard navigation works. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@einari — follow-up: I pushed a round of additions on top of the migration, so this is now more of a "v0.2 done right" than just a port. Highlights:
Still not merging — the two things I'd most value your steer on are (1) whether the baseline theme should become the recommended default for Cratis apps, and (2) the licensing posture (unstyled-first + baseline theme = free; presets = keyed). Full detail in the updated PR description. |
The `.cratis-theme` root set a text color but never painted a base surface, so on any non-white host (a subtree, or a dark canvas) the light variant rendered dark-on-dark and unreadable. Paint the surface token on the themed root so the theme is self-contained; it flips light/dark with the palette. Add a `cratis-theme-light` Storybook mode so the light variant is previewable and verifiable at all — previously only the dark variant was ever rendered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The switch input had no accessible name (the visible label was not associated with it) and the rating star radios had none either — both flagged as axe critical `label` violations. Wrap the switch in a real <label> for implicit association plus an aria-label fallback, and give each rating option a per-star aria-label. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Raw green/red text could not meet WCAG AA contrast on both the light and dark baseline surfaces (a fixed hex fails one or the other). Use the Display `Tag` with a severity instead — theme-aware, contrast-tuned, and the documented pattern for status indicators in tables. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Follow-up polish while the PR waits for review — I set up a light and dark axe/screenshot pass over the baseline theme and it surfaced a real bug plus two a11y gaps, now fixed:
Both light and dark now scan clean except for the one known upstream PrimeReact Stepper ARIA limitation already noted above. Gates green (tsc, lint, 209 specs, rollup, build-storybook). |
The `files` allowlist only excluded stories and given files, so the published tarball also shipped the entire `storybook-static` build, `vite.config`, `vitest.setup`, and `tsconfig.tsbuildinfo` — build/test scaffolding a consumer never needs. Exclude them; the tarball drops from ~544 kB to ~302 kB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PrimeReact 11's Stepper marks each step header role="tab" and each panel role="tabpanel" with aria-controls pointing at element ids it never renders (a dangling reference), and the list is not a role="tablist" — axe flags both as critical. The headless stepper implements no keyboard navigation bound to these roles (steps navigate by click on the native button), so strip the broken tab semantics via pt, leaving natively keyboard-accessible buttons and a plain content region. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cratis/arc.react's field wrappers, form errors, and dialogs read a `--color-*` token family (--color-error, --color-border, --color-text, --color-success, --color-warning, …) that the baseline theme did not define, so Arc chrome fell back to hardcoded defaults — notably field error text (#c00) that failed WCAG AA contrast on the dark surface. Map the family onto the palette with AA-safe light and dark semantic colors so the baseline theme also themes the Arc surface, not only PrimeReact. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The demo pt preset styled buttons bg-sky-500 with white text (2.7:1), failing WCAG AA. Use sky-700 (~6:1). The preset is a reference consumers copy for the unstyled + Tailwind pt path, so it should model AA contrast. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The imperative toast quick-reference showed `toast.info(...)` without noting the argument is an options object, not a bare string — easy for a consumer to get wrong. Show the object form. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Ran a real consumer smoke test (the gap I flagged: everything so far had been verified in the library's own environment, never as a consumer consumes it) and it drove out several genuine fixes: Consumer smoke test — passes end-to-end. Packed the tarball, installed it into a throwaway app with only the declared peers, then Fixes it surfaced:
One honest note: there's a pre-existing One thing worth your eye: |
The consumer-facing README still described the pre-migration package: - Claimed a dual CommonJS + ESM build — the package is now ESM-only. - Named the styled Storybook preset "Lara" — it is Aura; and listed five styling modes when there are now six (baseline theme gained a light one). - Listed React 18+ — the peer is React 19. - Described primereact/primeicons as peer dependencies — they ship as regular dependencies; documented that and the dedupe caveat. - Omitted the new `/Display`, `/Notifications`, and `/theme` exports. - Left the license-free baseline theme out of the styling decision table. - Framed the "why you need a theme" note around PrimeReact 10 semantics. - Modeled `bg-sky-500` (fails AA) in the Tailwind pt example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
CheckboxField, RadioButtonField, and RadioGroupField rendered their label text in an unassociated <label> (no htmlFor, not wrapping the control), so screen readers saw a nameless control — the same axe critical the ToggleSwitch fix already addressed, which had stopped one field short of its siblings. Wrap each control in a real <label> for implicit association. Also drop the dead aria-label on ToggleSwitch (it landed on the wrapper div, not the input; the wrapping label is the name). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Several aria-labels were baked-in English strings a consumer could not translate. Expose each as an optional prop with an English default: Chip `removeAriaLabel`, Dialog `closeAriaLabel`, DataTableCore `selectionAriaLabel`, TablePaginator `ariaLabels`, RatingField `starAriaLabel`, Toaster `dismissAriaLabel`. The BusyIndicator spinner (role="progressbar") had no accessible name at all — name it from the consumer-supplied message/title (already localized). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Map Arc's `--radius-*`, `--space-*`, and `--font-mono` (which @cratis/arc.react reads with no fallbacks) so Arc chrome keeps its corners, padding, and gaps instead of collapsing under the theme. - Add concrete `--cratis-surface-ground` / `--cratis-focus-ring` values so the Filter panel's sub-surfaces and focus rings render with no preset. - Deepen the dark `--color-error-bg` (red-950) so error text clears WCAG AA on the exception banner, not just the section surface. - Style the previously-uncovered `rating` and `progressspinner` scopes so the star rating and the busy spinner are visible under the theme. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- The Dialog stories used the removed v10 `<Button label=… icon=…/>` props, which render an empty button in PrimeReact 11 (broken visually and an axe button-name violation) — switch to children. - The observable data-table story colored status/priority with fixed text shades that fail contrast on the dark surface — use Display `Tag` with a severity (theme-aware) instead. - Lift the Filter story's muted helper text above the WCAG AA threshold. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The docs (and the provider's own JSDoc) showed styling options as direct
props — `<CratisComponentsProvider theme={{ preset }}>` / `unstyled` /
`license` — but the provider only accepts a single `value` prop, so those
are silently dropped: they must be `value={{ theme: { preset } }}` etc.
Also correct dialogs.md (`style`/`contentStyle`/`dismissable` are
supported; add the new fields to the catalog).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The package is ESM-only, but a leftover dist/cjs from an earlier build would ship as unreferenced dead weight since `files` includes `dist`. Exclude `dist/cjs/**`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Did a thorough final sweep — a full axe scan across every story (100 stories × light/dark/unstyled) plus three parallel audits (docs drift, baseline-theme completeness, correctness of the session's changes). It surfaced a lot my earlier subset scan had hidden. All fixed: Component accessibility (real bugs)
Localization (thanks for the nudge) — every aria-label I'd added was hard-coded English; all are now optional props with English defaults ( Baseline theme completeness — mapped Arc's Docs correctness (break-on-paste) — the docs (and the provider's own JSDoc) showed Result: the shipped baseline theme went from 93/72 (light/dark) axe nodes → 21/26, and everything remaining is genuinely upstream — see below. Honest boundary — what I deliberately did NOT fix here (yours to weigh):
Gates green (tsc, lint, 209 specs, build, build-storybook). Not merging. |
Externalize every remaining baked-in English string across the consumer-facing components so nothing is assumed on the consumer side — individual override props for single-string components (ChipsField `removeAriaLabel`, ObjectNavigationalBar `backLabel`, DataPage `actionsAriaLabel`, FilterPanel `clearFilterAriaLabel`/`clearRangeAriaLabel`) and a `labels` object with an exported type + English defaults for the multi-string components (`SchemaEditorLabels`, `TimeMachineLabels`, the latter extracted to its own module so the sub-views can default without a circular import). All defaults preserve current behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Correct the docs that still described the pre-migration (v10) reality:
removed `primereact/column`/`stepperpanel`/`api` imports, the removed
`<Button label= icon=>` API, the provider `value={{ … }}` config (theme/
unstyled/license are not direct props), `PrimeReactProps`/`inputVariant`
(not v10 `APIOptions`/`inputStyle`), the styling section (presets via the
provider + the license-free baseline theme instead of `resources/themes`),
and a full rewrite of the migration page, which had described a different,
older migration and claimed the library was still on PrimeReact 10.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add reference pages for the components introduced in this release — Display (Tag/Badge/Chip/Avatar/ProgressBar/Skeleton), Notifications (Toaster/toast/toastCommandResult), the PasswordField/ToggleSwitchField/ RatingField command-form fields, and a Cratis-baseline-theme styling how-to — and wire them into the navigation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the pass-through cheat sheet's underlying-widget column to the v11 primitive names (select/textarea/datepicker/inputtags/inputcolor) and the coming-from-primereact bridge to the Cratis Dialog API and Button children. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up corrections to the styling section: the custom-palette and mixing-paths guidance now uses the `@primeuix/themes` preset + `--cratis-*` model instead of removed `resources/themes/*` imports; `themed.md` is the licensed-preset path (distinguished from the license-free baseline theme in the nav); and the baseline-theme override example targets `[data-scope]` (the baseline theme's selector) rather than `.p-button` (preset-only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Two more things landed: full label configurability and a full documentation pass. Nothing is assumed on the consumer side anymore. Every remaining hard-coded English string across the components is now overridable with an English default — individual props where there are one or two ( Documentation is now current and complete. The
Markdown + link checks pass; all code gates green (tsc, lint, 209 specs, build, build-storybook). That closes the two follow-ups from the last review round (broader localization debt + the Documentation site). Still not merging. Remaining open items are unchanged and all upstream/maintainer calls: PrimeReact-11 primitive-internal a11y, |
An API-regression audit against main found several consumer-facing props
that were dropped or weakened without PrimeReact 11 forcing it. Restore them:
- Dropdown: re-add style, id, name, tabIndex, aria-label, aria-labelledby
(all expressible on v11's Select) — the wrapper had dropped them.
- DataPage: re-expose menubarPt / menubarPtOptions / menubarUnstyled by
adding pass-through to ActionMenubar's buttons (the props had been removed
while the JSDoc still advertised them).
- DataTableForQuery/ForObservableQuery: surface paginatorAriaLabels so the
paginator's controls can be localized.
- DataTableFilterMeta: type it as a per-field { value, matchMode } constraint
instead of Record<string, unknown>, so defaultFilters type-checks.
- StepperPanel: widen header from string to ReactNode (v10 accepted a
template; it renders through Stepper.Title which takes a node).
- Deprecate the dead clientFiltering flag (declared and forwarded but never
read) with an honest @deprecated note instead of "Enable client-side filtering".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fix documentation that no longer matched the code: the Dropdown page claimed "all PrimeReact Dropdown props supported" (it is a curated wrapper, and it documented a filterPlaceholder prop that does not exist); the DataTables pages described a Server-vs-Client filtering toggle that no longer exists (clientFiltering is a no-op); and the pass-through cheat sheet listed a paginatorPt the custom paginator does not accept. Add a "Reduced capabilities" section to both migration guides listing the props PrimeReact 11 forced into no-ops (resizable, separator, display / maxSelectedLabels, clientFiltering) and the curated surfaces (Column, Dropdown, the action toolbar), so upgraders are not silently surprised. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Ran a focused API-regression audit of the whole Confirmed safe at the boundaries: no export/subpath/component removed (purely additive), no default silently changed, no new But the audit found real, non-forced worsenings — now fixed:
Honestly documented, not hidden: the capabilities PrimeReact 11 genuinely removed ( Net verdict: after these fixes, the upgrade does not make the public API worse than PrimeReact 11 forced — every remaining reduction is inherent to v11 and documented. Gates green (tsc, lint, 209 specs, build, build-storybook, docs link/lint). Still not merging. |
Summary
Migrates
@cratis/componentsfrom PrimeReact 10 → 11, restores full v10 capability parity where v11 removed things, adds new Arc-native components, and — the headline for consumers — ships a license-free Cratis baseline theme so apps look great without a PrimeUI key. Wrapper public APIs are preserved wherever PrimeReact 11 allows; the breaking changes below are the unavoidable consequences of v11 being ESM-only and dropping several v10 modules.Bumped to
0.2.0, labeled major. SeeSource/MIGRATION.mdfor the consumer upgrade guide.PrimeReact 11 changed its licensing:
--cratis-*token layer +ptare free — no key.@primeuix/themespresets (Aura/Lara/…) are license-gated — applying one viatheme={{ preset }}needs a PrimeUI key (free community tier or paid); without it PrimeReact shows an "Invalid PrimeUI License" banner in dev and prod (that's why it appears in the story screenshots — Storybook runs license-free).import '@cratis/components/theme', unstyled), a token-based stylesheet that gives every component a polished default look with no PrimeUI license. Use unstyled-first, the baseline theme, or a licensed preset — your call.Changed
CratisComponentsProvidernow wraps@primereact/core's provider and acceptstheme={{ preset }}and alicense.Columnfrom@cratis/components/DataPage/DataTablesandStepperPanelfrom@cratis/components/CommandDialog(removedprimereact/column/primereact/stepperpanel); the authoring model is unchanged.DataTableSelectionChangeEvent(event.valueunchanged), replacing the removedDataTableSelectionSingleChangeEvent.@primeuix/themespreset instead of the removedprimereact/resources/themes/*.css.Added
Capability parity + improvements (data table & stepper)
<Column filter dataType … />), a global search box, a selection radio forselectionModecolumns, and a paginator range report.orientation(incl. vertical),headerPosition,start/end— reimplemented over the compositional stepper.dismissableonDialog.New Arc-native components
@cratis/components/Notifications—Toaster, imperativetoast, andtoastCommandResult(result)mapping an ArcICommandResultto the right toast (validation → per-field messages, exceptions → generic, never stack traces).CratisComponentsProvidergains an optionaltoasterprop to mount it automatically.@cratis/components/Display—Tag,Badge,Chip,Skeleton,Avatar,ProgressBar.PasswordField,ToggleSwitchField,RatingField.Baseline theme, docs, tests, a11y
@cratis/components/theme— the license-free token-based theme (light + dark, defers to a preset's--p-*when present). It also maps@cratis/arc.react's--color-*chrome tokens (field errors, borders, labels) onto the palette, so it themes the Arc form surface too — not only the PrimeReact components.MIGRATION.mdupgrade guide;.airules updated to teach the new surface.toastCommandResult, selection key↔row translation, paginator range) — 209 specs pass.aria-controls/ orphanedrole="tab"), field-error contrast in dark mode, the Chip remove control, and the data-table sort button's invalidaria-sort. Accessible names added to the toggle-switch and rating fields.Removed
primereact/resources/themes/*.csstheming model.Verified from the consumer's seat. Beyond the internal gates, the packed tarball was installed into a throwaway app with only the declared peers, then type-checked,
vite build-bundled, and rendered headless — every subpath export and thethemeimport resolve, and the components mount and style with zero runtime errors (the baseline theme delivering its look with no PrimeUI license). The published tarball was also trimmed (Storybook build + test scaffolding removed, ~544 kB → ~302 kB).Every gate is green:
tsc -b(0),yarn lint(clean),yarn test(209),yarn build(ESM),build-storybook. Every widget was screenshot- and interaction-verified end-to-end (table sort/filter/select/page, stepper flows, toasts, tooltips, form fields), and the full component surface was axe-scanned in light, dark, and unstyled modes.🤖 Generated with Claude Code