Skip to content

Cratis-controlled styling: theme, palette, unstyled options, full pt forwarding, peer deps#90

Merged
woksin merged 25 commits into
mainfrom
fix/unstyled-improvements
May 30, 2026
Merged

Cratis-controlled styling: theme, palette, unstyled options, full pt forwarding, peer deps#90
woksin merged 25 commits into
mainfrom
fix/unstyled-improvements

Conversation

@woksin
Copy link
Copy Markdown
Contributor

@woksin woksin commented May 29, 2026

Summary

Makes styling in @cratis/components explicit and consumer-controlled. Consumers can use a PrimeReact theme, apply a custom palette on top of a PrimeReact theme, or run fully unstyled with their own pt preset.

Also moves PrimeReact packages to peer dependencies, adds a Cratis provider and token layer, forwards PrimeReact customization props through the wrappers, and updates the documentation around the new setup model.

The token layer is also version-spanning: every --cratis-* token resolves PrimeReact v11 design tokens (@primeuix/themes) first and falls back to v10, so the same build works on PrimeReact 10 and 11 and a 10 → 11 upgrade needs no styling changes. This covers the theming surface only — full PrimeReact 11 component compatibility (prop and pt-slot changes) is a separate follow-up, and the primereact peer stays at ^10.9.0 for now.

Added

  • Added CratisComponentsProvider as the single setup point for PrimeReact global options such as unstyled, pt, ptOptions, locale, ripple, and overlay config.
  • Added a --cratis-* CSS variable token layer for Cratis-owned surfaces, themed out of the box from whichever PrimeReact theme is loaded.
  • Added PrimeReact 10 and 11 compatibility for the token layer — each --cratis-* token resolves the PrimeReact v11 design token (@primeuix/themes) first and falls back to the v10 theme variable, so the same build works across both majors.
  • Added pt, ptOptions, unstyled, and className forwarding on single-widget wrappers.
  • Added per-slot pass-through props on composite wrappers, including dialogPt, tablePt, menubarPt, and paginatorPt.
  • Added root className support on large composites where per-slot forwarding is not practical.
  • Added subpath exports for ObjectContentEditor, ObjectNavigationalBar, SchemaEditor, and tokens.
  • Added Styling documentation for using a PrimeReact theme, applying a custom palette, using fully unstyled mode, combining styling setups, Cratis tokens, and PrimeReact pass-through props.
  • Added a migration guide covering peer dependency changes, visual changes, provider setup, and optional styling capabilities.
  • Added a Storybook Styling toolbar with previews for Lara Dark Blue, Lara Light Blue, Custom palette, Unstyled bare, and Unstyled + Tailwind pt.
  • Added sideEffects: ["**/*.css"] so bundlers can tree-shake unused JS while preserving CSS imports.

Changed

  • Changed primereact and primeicons from runtime dependencies to peer dependencies; consumers must declare them directly after upgrading.
  • Changed pixi.js, framer-motion, and allotment to optional peer dependencies so consumers only install them when using the matching components.
  • Changed FormElement addon styling to use stable Cratis CSS classes and --cratis-* tokens instead of PrimeReact p-inputgroup-addon classes.
  • Changed ObjectNavigationalBar and SchemaEditor bottom borders to render through Cratis CSS instead of PrimeFlex utility classes.
  • Changed internal PrimeReact class hooks such as p-button-text, p-button-sm, p-button-danger, and p-error to typed PrimeReact props or Cratis token-driven styling.
  • Changed the README styling section to describe consumer setup choices instead of internal styling terminology.
  • Changed public component JSDoc to document Arc integration, wrapper behavior, and the exposed PrimeReact customization surface.
  • Changed workspace dependency declarations by removing unused dev dependencies, deduplicating Storybook, and moving @cratis/arc.vite to dev dependencies.

Fixed

  • Fixed the @cratis/components/CommandStepper subpath export so it resolves to the emitted build output.
  • Fixed the documented subpath list by removing @cratis/components/EventModeling, which never existed.
  • Fixed the README pass-through description so it accurately distinguishes single-widget wrappers, multi-slot composites, and large composites.
  • Fixed FormElement documentation that described props the component never had.

Removed

  • Removed unused runtime dependencies on react-router-dom and usehooks-ts.
  • Removed the obsolete Storybook 8 @storybook/addon-storysource registration from the Storybook 10 setup.

woksin added 16 commits May 28, 2026 22:20
Introduce a Cratis-scoped token layer that every internal component reads
from instead of PrimeReact theme variables directly. Each --cratis-* token
defaults to the matching PrimeReact variable so a consumer's PrimeReact theme
just works, while still allowing consumers to take full control by overriding
the tokens on :root or any scope — with or without a PrimeReact theme.

Tokens cover surfaces, text, primary brand, highlight, semantic accents
(green/orange/red), border radius, focus ring, and overlay mask. The token
file is auto-bundled into the compiled @cratis/components/styles stylesheet
via the existing Tailwind build pipeline.
Rename every `var(--surface-*)`, `var(--text-color*)`, `var(--primary-color*)`,
`var(--highlight-*)`, `var(--border-radius)`, `var(--green-500)`,
`var(--orange-500)`, and `var(--red-500)` reference in production CSS, story
files, and trivial inline styles to its `--cratis-*` equivalent.

The tokens cascade to the underlying PrimeReact variables by default, so
behavior is unchanged when a PrimeReact theme is loaded. Consumers wanting to
take control now have a stable, scoped token surface to override on `:root`
or any ancestor.

This commit covers the files whose only change is the rename. Files that
combine var renames with code refactors are migrated in subsequent commits.
Introduce a thin wrapper over PrimeReact's PrimeReactProvider so Cratis has a
single discoverable setup point and a place to layer in defaults later. The
provider deep-merges Cratis-wide defaults with the consumer's value and hands
the result to PrimeReact's context, exposing the full PrimeReact API options
(unstyled, pt, ptOptions, inputStyle, locale, ripple, autoZIndex, …).

`cratisDefaults` is intentionally empty today — it reserves room for future
Cratis-wide opinions without forcing them on consumers now. The pure
`mergeCratisComponentsConfig` helper is exported so the deep-merge contract
can be verified without rendering React, side-stepping the project's
`isolate: false` vitest configuration.
…sName on composites

Make ObjectContentEditor, ObjectNavigationalBar, SchemaEditor, FormElement,
TypeCell and friends consumer-styleable in unstyled mode by removing every
hard-coded `p-button-text`, `p-button-sm`, `p-button-danger`, `p-error`,
`p-inputgroup`, `border-bottom-1`, and `surface-border` className hook and
replacing each with one of:

- A typed PrimeReact prop on the wrapper (Button `text` / `size` / `severity`).
- An inline style using a `--cratis-*` token (e.g. `var(--cratis-red-500)`
  for inline validation error text replacing `<small className="p-error">`).
- A structural CSS class colocated with the component that uses `--cratis-*`
  tokens (`cratis-form-element__addon`, `cratis-object-navigational-bar`,
  `SchemaEditor.module.css#bottomBorder`).

Add a `className` prop on the composite wrappers (`ObjectContentEditor`,
`ObjectNavigationalBar`, `SchemaEditor`) so consumers can append layout
classes to the root without forking. Fine-grained restyling of the inner
PrimeReact widgets keeps going through the global `pt` preset on
`CratisComponentsProvider`.

A small number of `p-menuitem-link` / `p-menuitem-text` class hooks remain in
SchemaEditor's Menubar custom-template — those are required by PrimeReact's
slot-rendering contract to match the surrounding default-rendered items, so
they have no effect in unstyled mode and stay aligned in themed mode.
Add pass-through pt/ptOptions/unstyled and className on Dialog and
CommandDialog so consumers can fully restyle (or unstyle) the underlying
PrimeReact Dialog without forking. The props plumb straight through to
PrimeDialog with no transformation.

For StepperCommandDialog — which renders both a Dialog and a Stepper — keep
the inherited `pt`/`ptOptions`/`unstyled` targeting the Stepper (matching
StepperCustomizationProps) and add explicit `dialogPt`/`dialogPtOptions`/
`dialogUnstyled`/`dialogClassName` siblings for the outer Dialog. This makes
each slot independently styleable and matches the convention introduced
elsewhere for multi-slot composites.

BusyIndicatorDialog only documents its behavior — per-instance pt is not
exposed because its request type is owned by `@cratis/arc.react`. Consumers
restyle it via the global pt preset on CratisComponentsProvider.
Open up DataPage, DataTableForQuery, and DataTableForObservableQuery for
consumer restyling.

The DataTable wrappers forward `pt`/`ptOptions`/`unstyled`/`className` to
the underlying PrimeReact DataTable plus a sibling set of
`paginatorPt`/`paginatorPtOptions`/`paginatorUnstyled` for the inner
Paginator.

DataPage composes both a DataTable and a Menubar, so it exposes per-slot
props mirroring the slot pattern: `tablePt` / `tablePtOptions` / `tableUnstyled`
/ `tableClassName` for the data table, and `menubarPt` / `menubarPtOptions` /
`menubarUnstyled` / `menubarClassName` for the action Menubar. The inner
`Columns` and `MenuItems` components read these from the surrounding
DataPage context and forward them to the appropriate primitive.

Border colors that were previously inline-styled with `var(--surface-border)`
are migrated to `var(--cratis-surface-border)` so consumer overrides take
effect alongside the new pt forwarding.
Each of the 13 CommandForm field wrappers (InputTextField, TextAreaField,
NumberField, DropdownField, RadioGroupField, RadioButtonField, CalendarField,
CheckboxField, SliderField, ChipsField, MultiSelectField, ColorPickerField)
now accepts `pt`, `ptOptions`, `unstyled`, and `className` and forwards each
straight to its underlying PrimeReact widget. The default `w-full` Tailwind
class is preserved by combining it with any consumer-supplied `className`.

This gives consumers full per-field styling control on top of (or instead of)
the global `pt` preset set on `CratisComponentsProvider`. Each prop is typed
from the underlying PrimeReact component's own type so autocomplete reflects
the real pt slot surface.
Document every consumer-facing component and prop interface that was
previously undocumented or thinly documented, using the same JSDoc style as
PrimeReact itself — one block on the component covering purpose, behavior,
and a short usage example, plus a block on every prop in the props interface.

Covers CommandStepper, Common/ErrorBoundary, Common/Page, Dropdown,
PivotViewer, and TimeMachine/{EventsView,ReadModelView}. Together with the
JSDoc landed alongside each pt-forwarding commit, the entire public surface
of the package now has consistent prop-level documentation that surfaces in
IDE intellisense.
Bring the published package metadata in line with the actual shipping
surface and current React-library packaging best practices.

- Add `"sideEffects": ["**/*.css"]` so bundlers can tree-shake unused JS
  modules while still preserving the colocated CSS imports.
- Fix the broken `./CommandStepper` export — it pointed at
  `./dist/{esm,cjs}/CommandStepper/index.js` which does not exist. The
  compiled file lives at `./dist/{esm,cjs}/CommandDialog/CommandStepper.js`
  because the source resides in `CommandDialog/`.
- Add the three exports that were missing from the map even though their
  built indexes ship in dist: `./ObjectContentEditor`,
  `./ObjectNavigationalBar`, `./SchemaEditor`.
- Add the new `./tokens` stylesheet entry so consumers who only want the
  `--cratis-*` token layer (without the bundled Tailwind utilities) can
  `import '@cratis/components/tokens'`.
- Move `primereact`, `primeicons`, and `react-router-dom` from
  `dependencies` to `peerDependencies` to avoid duplicate copies in
  consumer apps and the resulting PrimeReact context fragmentation.
- Move `pixi.js`, `framer-motion`, and `allotment` to peerDependencies
  with `peerDependenciesMeta.optional = true` — they're only needed when
  the corresponding component (PivotViewer, animated panels, DataPage
  split panes) is actually used. Mirror them in devDependencies so the
  package can still typecheck and build locally.
- Re-export `CratisComponentsProvider`, `cratisDefaults`,
  `mergeCratisComponentsConfig`, and their types from the package root so
  `import { CratisComponentsProvider } from '@cratis/components'` works
  without consumers having to know about the `Common` subpath.
Replace the prior reference-only Styling section with a guide structured
around the three documented paths a consumer can choose between:

  A. PrimeReact-themed — fastest start; load a PrimeReact theme stylesheet
     and let the --cratis-* tokens cascade through.
  B. Cratis-themed — override --cratis-* tokens directly without loading a
     PrimeReact theme, optionally via Tailwind's @layer base + theme().
  C. Fully unstyled — disable PrimeReact's base styles entirely and ship
     visuals via a pt preset, your own CSS, or both.

Each path has a worked example pair (plain CSS and TailwindCSS), the full
--cratis-* token reference table, and concrete "Choose this when…" guidance.
Adds a "Mixing paths" section showing how to compose them (themed app with
one unstyled component, unstyled app with one themed island, scoped
dark-mode token overrides).

Also fix the available-subpaths list:
- Remove the stale `@cratis/components/EventModeling` claim — that path
  does not exist in the exports map and never has.
- Add the missing entries that do ship: CommandStepper, CommandForm/fields,
  ObjectContentEditor, ObjectNavigationalBar, SchemaEditor, Toolbar, types.
- Add a callout at the top of the Styling section pointing at the new
  Storybook styling toolbar so consumers can preview each path live.
- Update the install command and add the optional peer-dependency table to
  match the package.json restructure.
Extend the Storybook theme toolbar from one option (PrimeReact theme) to
five entries that line up with the three documented styling paths in the
README, so consumers can see the same component rendered under each setup
by toggling a single dropdown.

Toolbar entries:

  - Path A — Lara Dark Blue        (PrimeReact dark theme + provider defaults)
  - Path A — Lara Light Blue       (PrimeReact light theme)
  - Path B — Cratis-themed         (no PrimeReact theme; slate surfaces + sky brand via scoped --cratis-* overrides)
  - Path C — Unstyled (bare)       (provider unstyled=true, no pt — shows raw structural rendering)
  - Path C — Unstyled + Tailwind pt (provider unstyled=true with sample tailwindPtPreset)

The decorator toggles three things per mode: the injected PrimeReact theme
link, a body class that activates the right --cratis-* token override, and
the `value` passed to `CratisComponentsProvider` (unstyled + pt).

Also fixes a latent bug in the previous storybook setup: the neutral
fallback tokens were declared at `:root` unconditionally and so blocked the
loaded PrimeReact theme from driving --cratis-* via the cascade in the dark/
light modes. Scoping the fallbacks under body classes lets the theme cascade
naturally in Path A modes.

`pt-preset.ts` ships a sample Tailwind-utility-class pt preset covering
Button, Dialog, InputText, InputTextarea, InputNumber, Dropdown, Checkbox,
DataTable, Paginator, and Menubar — Storybook-only, intended as a starting
point consumers can fork into their own apps.
Drop entries that are unused, duplicated, or misclassified across the
workspace root and the published Source package.

Unused at runtime:
- Remove `react-router-dom` from the published package's dependencies and
  peer dependencies entirely (and from the install instructions in the
  README). No file in the published surface imports it.
- Remove `usehooks-ts` from the published package's runtime dependencies.
  No file in the published surface imports it.
- Remove `@types/leaflet` from the workspace root devDependencies. No file
  imports anything from Leaflet.
- Remove `rollup-plugin-copy` from the workspace root devDependencies. No
  rollup config references it.

Duplicated across workspaces:
- Remove `storybook` from the published package's devDependencies. The
  workspace root already lists it at the current pin (`^10.4.1`); the local
  override (`^10.3.4`) just lagged behind.

Misclassified:
- Move `@cratis/arc.vite` from peerDependencies to devDependencies in the
  published Source package. It is only imported by `Source/vite.config.ts`
  (the local dev / storybook config). Nothing in the published runtime
  references it, so we should not promise consumers they need to provide
  it.

Storybook 8 plugin in a Storybook 10 setup:
- Remove `@storybook/addon-storysource@8.6.14` from the root devDependencies
  and drop its entry from `.storybook/main.ts`. The addon shipped against
  Storybook 8 internals and was incompatible with the Storybook 10 host
  registered alongside it. (Dropping the addon does not fix the pre-existing
  lightningcss `Invalid empty selector` build-storybook failure — that lives
  elsewhere in the CSS processing pipeline — but it removes one source of
  version drift.)
…ns-only

The previous Path B description ("Cratis-themed without a PrimeReact theme")
was misleading and the Storybook mode that reflected it produced the
visually-broken bare-bones rendering captured in review.

The root cause: in PrimeReact 10 every widget's structural CSS (padding,
borders, dialog frame, focus rings, button shapes) ships inside the theme
file. There is no separate primitives stylesheet. So a setup without any
PrimeReact theme has no widget chrome at all — components render as the raw
HTML primitives the browser supplies by default.

The --cratis-* tokens are a Cratis-scoped tint layer for surfaces *our*
wrappers own (validation error text, the FormElement addon, breadcrumb
borders, etc.) — they are not, by themselves, sufficient to skin PrimeReact
widgets. PrimeReact widgets read --surface-card / --text-color /
--primary-color / etc. directly, never the --cratis-* siblings.

Reframe Path B as "Themed with custom palette": a PrimeReact theme provides
the structural baseline, and the consumer overrides PrimeReact's own
variables (--surface-card, --text-color, --primary-color, …) on :root to
retint every widget. The --cratis-* tokens follow along through tokens.css's
cascade, and can be overridden independently when Cratis-scoped surfaces
should differ from PrimeReact widgets.

- Storybook decorator: Path B mode now loads Lara Dark Blue as the
  structural baseline and the body.cratis-themed class overrides PrimeReact
  variables (plus a few --cratis-* siblings) to produce the slate/sky palette.
- README: rewrite the Path B section with accurate CSS (overrides
  PrimeReact variables, not just --cratis-*), an explanatory call-out about
  why a PrimeReact theme is still in Paths A and B, and a clarifying
  "What --cratis-* tokens are for" subsection.
- Mixing paths > Dark mode example updated to use the same approach.
Build out the styling story in Documentation/ so consumers can self-serve
through the three documented paths without reading the README. Markdown
verification passes (markdownlint + link check, 77 files scanned).

New Styling section (Documentation/Styling/):
- index.md ............ Overview, decision tree, mental model.
- getting-started.md .. The one-line setup every path shares.
- themed.md ........... Path A: PrimeReact theme + CSS / className / pt
                        tweaks.
- custom-palette.md ... Path B: PrimeReact theme + override of the
                        PrimeReact CSS variables on :root for a custom
                        palette, with worked CSS and TailwindCSS examples.
- unstyled.md ......... Path C: provider unstyled=true plus pt presets in
                        both plain CSS and TailwindCSS, per-instance
                        overrides, and composite-component slot props.
- cratis-tokens.md .... Full reference for every --cratis-* token, the
                        Cratis-scoped surface it tints, and how cratis
                        tokens relate to PrimeReact variables.
- pass-through.md ..... Per-component pt cheat sheet: single-widget
                        wrappers, multi-slot composites (DataPage,
                        StepperCommandDialog, DataTables), large
                        composites (ObjectContentEditor, NavigationalBar,
                        SchemaEditor), and BusyIndicatorDialog.
- mixing-paths.md ..... Themed app with unstyled island, unstyled app
                        with themed island, app-wide dark mode, per-region
                        brand zones, per-component overrides.
- toc.yml ............. Wires the section into DocFX navigation.

New Common page:
- cratis-components-provider.md ..... Full reference for the provider:
  purpose, basic setup, value prop (APIOptions members), direct
  PrimeReactProvider alternative, and the pure mergeCratisComponentsConfig
  / cratisDefaults helpers exported for tests and library extensions.

Updates:
- Documentation/toc.yml: insert the new Styling section before Components.
- Documentation/index.md: introduce the styling system, point at the
  three paths and the token reference, mention the optional peer deps,
  list CratisComponentsProvider under Common.
- Documentation/Common/toc.yml + index.md: add the new provider page.
- Documentation/Common/form-element.md: rewrite from scratch — the
  previous content described a label/required/error API that the
  component has never had. Document the real `icon` + `children` props
  with worked examples, list the --cratis-* tokens that tint the addon,
  show the stable `cratis-form-element` class hooks for unstyled mode,
  and point at the styling section.
…eases

Cover everything a consumer needs to know to land the upgrade safely:

Required actions
- Quick checklist with the must-do install (primereact + primeicons as
  peer deps, plus the optional peers for PivotViewer / CommandStepper /
  resizable DataPage).

Breaking changes
- primereact and primeicons moved from dependencies to peerDependencies
  (with rationale: avoids the duplicate-installation + fragmented
  PrimeReact context pitfall).
- pixi.js / framer-motion / allotment moved to optional peers (no longer
  shipped to consumers who never use those components).
- react-router-dom removed entirely (never imported by the package).

Visual changes
- FormElement addon now uses bespoke --cratis-* token styling instead of
  PrimeReact's p-inputgroup-addon chrome. Shape identical; pixels may
  drift in unusual themes.
- ObjectNavigationalBar and SchemaEditor bottom border now actually
  renders (was silent no-op without PrimeFlex). With instructions for
  overriding to transparent if the borderless look was preferred.
- Catalogue of removed hard-coded PrimeReact / PrimeFlex class hooks with
  their replacements (Button text/size/severity props, inline
  --cratis-red-500 in place of p-error, etc.).

Subpath import changes
- @cratis/components/CommandStepper now resolves (the previous exports
  map pointed at a non-existent path).
- @cratis/components/EventModeling was never real — documented and the
  README claim removed.
- New subpaths: ObjectContentEditor, ObjectNavigationalBar, SchemaEditor,
  tokens.

Recommended migrations
- Switch PrimeReactProvider call sites to CratisComponentsProvider from
  the package root.
- Consolidate per-component CSS overrides into --cratis-* token blocks
  where the surface is Cratis-scoped.
- Replace global .p-button CSS rules with per-instance pt slot config to
  avoid collisions with future PrimeReact theme updates.
- Adopt subpath imports for tree-shaking.

New optional capabilities tour
- Per-component pt / ptOptions / unstyled / className.
- Per-slot props on composites (StepperCommandDialog, DataPage,
  DataTables).
- className on the large composite editors.
- The --cratis-* token layer.
- Storybook styling toolbar.

Before / after recipes
- Root setup, restyling one Dialog, restyling the inner DataTable in
  DataPage, switching to a fully-unstyled design system.

Troubleshooting
- Module resolution failures, peer-dep warnings, sparse visuals after
  upgrade, the stale @cratis/components/EventModeling claim, and the
  pre-existing yarn build-storybook failure.

Also: wire the new guide into Documentation/toc.yml between Styling and
Components, and link it from Documentation/index.md in a new "Upgrading
from an earlier release" section. Markdown verification still passes
(markdownlint + link check, 78 files scanned).
…notes

Previous JSDoc on the exported components covered the props well but was
thin on what the components actually do, how they integrate with the Arc
framework, and what makes each one distinct from the underlying PrimeReact
widget. Rewrite the component-level docblocks to fill that gap so the
IDE-surfaced documentation answers the questions a consumer would ask
encountering the component for the first time.

Dialog
- Document the @cratis/arc.react/dialogs host integration: how a Dialog
  inside a DialogHost discovers the context via useDialogContext() and
  closes through it automatically, with a worked useDialog + closeDialog
  call-site example.
- Cover the confirm/cancel callback contract (return false keeps open),
  the busy state used by command-executing wrappers, the validity gate,
  and the typed DialogButtons enum.

CommandDialog
- Spell out where TCommand comes from (auto-generated proxy from a C#
  [Command] record produced by dotnet build) and what the typed result
  contract is.
- Walk through what happens on confirm: onBeforeExecute transform →
  Arc command pipeline → onSuccess / onValidationFailure / onFailed
  branches, with the dialog's isBusy state tracked throughout.
- Document the value={c => c.prop} accessor as the field-binding pattern,
  including the type-inference behavior.
- Add a worked example with useDialog<CommandResult<TResponse>>() showing
  the typed-result idiom.
- Call out what's special vs. raw Dialog + CommandForm.

StepperCommandDialog
- Explain that TCommand is a single command split into stages, not
  multiple commands.
- Document the per-step error indicator behavior (red step number when
  any field in a visited step has an error), the linear-progression
  default, the visited-step tracking, and that submit only fires on the
  last step.
- Add a worked example using useDialog<CommandResult<...>> with
  StepperPanel children.
- Spell out the pt vs. dialogPt slot distinction.

CommandStepper
- Position as the embedded, non-modal counterpart of
  StepperCommandDialog for use directly inside a page region.
- Note the absence of dialogPt because there is no outer dialog.

BusyIndicatorDialog
- Make explicit that consumers do not instantiate this directly — it is
  rendered by the dialog host in response to showBusyIndicator from
  @cratis/arc.react/dialogs. Worked usage example with the typical
  try/finally pattern around a long-running operation.
- Explain why per-instance pt is not exposed (request type owned by
  arc.react) and how to restyle via the global pt preset.

DataPage
- Explain that both IQueryFor and IObservableQueryFor are accepted and
  the correct inner table (DataTableForQuery vs ForObservableQuery) is
  selected automatically via runtime prototype inspection.
- Document the three declarative children (MenuItems, Columns, optional
  detailsComponent), the selection lifecycle, and the
  disableOnUnselected pattern.
- Worked example with three menu items, two columns, and a details pane.

DataTableForQuery
- Identify the query class as Arc proxy from a C# read model static
  query method.
- Document lazy paging (server returns one page at a time), the
  clientFiltering toggle, and defaultFilters seeding.
- Worked example.

DataTableForObservableQuery
- Position as the real-time variant: WebSocket subscription via
  useObservableQueryWithPaging from @cratis/arc.react/queries; rows
  appear and disappear as the underlying read model changes server-side.
- Document the ResizeObserver-driven scrollable-height behavior.
- Worked example using a sessions read model.

CommandForm fields (13 files)
- InputTextField becomes the canonical reference: explains the
  value={c => c.prop} accessor, how asCommandFormField from
  @cratis/arc.react/commands wires up the binding, the end-to-end
  type inference, and the automatic validation-state propagation.
- The other twelve fields keep their existing examples but now include
  the specific TypeScript type they bind to (string, number, boolean,
  Date | null, string[], Array<string | number>, etc.) and link back
  to InputTextField for the full binding model.

tsc, eslint and the 146 vitest specs remain clean.
@woksin woksin added the major label May 29, 2026
@woksin woksin requested a review from einari May 29, 2026 05:59
…y and consistency

- Updated token references in cratis-tokens.md for accurate descriptions.
- Consolidated optional peer dependencies in getting-started.md and migration.md.
- Added EventsView component to pass-through documentation in pass-through.md.
- Improved CheckboxField, ColorPickerField, RadioButtonField, and RadioGroupField components for consistent styling.
- Adjusted Dialog story for proper flex layout.
- Updated README with clearer optional peer dependency information.
- Fixed NameCell component to handle validation errors correctly.
- Enhanced EventsView component to support additional props for styling and configuration.
- Excluded story files from package distribution in package.json.
@woksin
Copy link
Copy Markdown
Contributor Author

woksin commented May 29, 2026

@copilot resolve the merge conflicts in this pull request

Copy link
Copy Markdown
Contributor

Copilot AI commented May 29, 2026

@copilot resolve the merge conflicts in this pull request

Resolved and merged main into this PR branch; conflicts are fixed in commit 0891e18.

Copilot finished work on behalf of woksin May 29, 2026 20:23
@woksin woksin changed the title Cratis-controlled styling: three documented paths, full pt forwarding, peer-dep restructure Cratis-controlled styling: theme, palette, and unstyled setup docs May 29, 2026
@woksin woksin changed the title Cratis-controlled styling: theme, palette, and unstyled setup docs Cratis-controlled styling: theme, palette, unstyled options, full pt forwarding, peer deps May 29, 2026
woksin and others added 4 commits May 29, 2026 23:09
The new tablePt/tablePtOptions props used PrimeDataTableProps<any>. Use
the in-scope TDataType, constraining it to object to match the inner
DataTableForQuery/DataTableForObservableQuery, removing the any hole.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A blank line between the doc comment and the export detached it from
the symbol, dropping it from TypeDoc output and IDE hover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
woksin and others added 3 commits May 30, 2026 01:17
The validation-error <small> style was duplicated inline six times.
Hoist it into a fieldErrorStyle const alongside the other style
constants, matching the file's existing pattern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PrimeReact v11 (@primeuix/themes) replaces the legacy --surface-*/
--primary-* theme variables with a different token vocabulary
(--p-* primitives + semantic content/surface/text/primary tokens),
verified against the primeuix base preset.

Repoint every --cratis-* token to var(--p-<v11>, var(--<v10>)) so the
same build works on PrimeReact 10 and 11 and a 10->11 upgrade becomes a
one-file change instead of touching every component. Token names are
unchanged, so the component layer and the consumer override contract
are untouched. Where v11 has no 1:1 equivalent (surface-ground/section/
overlay, composite focus-ring) the closest durable semantic token is
used and noted inline.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Explain that the --cratis-* layer resolves PrimeReact v11 design tokens
(@primeuix/themes) first and falls back to v10, so the same build works
across both majors. Updates the styling overview's mental model, adds a
PrimeReact-version note to the custom-palette guide, and adds a
'PrimeReact 10 and 11' section to the migration guide — with the scope
caveat that full v11 component/pt-slot support is a separate follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@woksin woksin merged commit d310b0c into main May 30, 2026
7 checks passed
@woksin woksin deleted the fix/unstyled-improvements branch May 30, 2026 00:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants