From c8ae86384a237d317818b4f99cacb313311ad944 Mon Sep 17 00:00:00 2001 From: woksin Date: Wed, 9 Sep 2026 22:10:17 +0200 Subject: [PATCH 01/13] Add Starlight authoring validation Run Markdown, MDX, authoring, and local-link checks through one shared entry point so local and CI verification stay aligned. --- .github/workflows/documentation.yml | 1 + .github/workflows/markdown-verification.yml | 40 ++------ .markdownlint.json | 24 +++-- Documentation/verify-authoring.mjs | 100 ++++++++++++++++++++ Documentation/verify-markdown.sh | 27 +++++- 5 files changed, 151 insertions(+), 41 deletions(-) create mode 100644 Documentation/verify-authoring.mjs diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index c04cf1d9..2c7a1da0 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -12,6 +12,7 @@ on: push: branches: ["main"] paths: + - ".github/workflows/documentation.yml" - "Documentation/**" permissions: diff --git a/.github/workflows/markdown-verification.yml b/.github/workflows/markdown-verification.yml index 91d755e2..c0d947d7 100644 --- a/.github/workflows/markdown-verification.yml +++ b/.github/workflows/markdown-verification.yml @@ -6,6 +6,8 @@ on: branches: - main paths: + - '.github/workflows/markdown-verification.yml' + - '.markdownlint.json' - 'Documentation/**' - 'README.md' - 'release.md' @@ -20,6 +22,8 @@ on: branches: - '**' paths: + - '.github/workflows/markdown-verification.yml' + - '.markdownlint.json' - 'Documentation/**' - 'README.md' - 'release.md' @@ -39,32 +43,7 @@ permissions: contents: read jobs: - markdown-lint: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout code - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - with: - persist-credentials: false - - - name: Lint Markdown files - uses: DavidAnson/markdownlint-cli2-action@eb5ca3ab411449c66620fe7f1b3c9e10547144b0 # v18 - with: - globs: | - README.md - release.md - Documentation/**/*.md - Documentation/**/*.mdx - Source/*.md - Migrator/*.md - ESLint/*.md - Conformance/*.md - Adapters/**/*.md - Storybook/*.md - scripts/*.md - - link-verification: + markdown-verification: runs-on: ubuntu-latest timeout-minutes: 15 steps: @@ -78,11 +57,10 @@ jobs: with: node-version: 23.x - - name: Check repository-local Markdown and MDX links - run: | - node Documentation/verify-local-links.mjs Documentation - node Documentation/verify-local-links.mjs Adapters - node Documentation/verify-local-links.mjs scripts + # Run the same entry point contributors use locally so linting, + # authoring validation, and local-link checks cannot drift apart. + - name: Check Markdown and MDX authoring + run: ./Documentation/verify-markdown.sh - name: Check external links in consumer documentation uses: JustinBeckwith/linkinator-action@7b6b0bc671f6264e1a8daa4488a5bd91ce61dcd4 # v2.4.2 diff --git a/.markdownlint.json b/.markdownlint.json index 1114b19f..249f4bed 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -4,16 +4,28 @@ "MD013": false, "MD033": { "allowed_elements": [ - "antml:function_calls", - "antml:invoke", - "antml:parameter", "a", - "Steps", "Aside", + "Badge", + "Card", "CardGrid", + "Code", + "FileTree", + "Fragment", + "FullStackTabs", + "Icon", + "LinkButton", + "LinkCard", + "OsAwareTabs", + "Recap", "SimpleCard", - "Card", - "StorybookEmbed" + "StackDiagram", + "Steps", + "StorybookEmbed", + "TabItem", + "Tabs", + "TopicHero", + "YouWillLearn" ] }, "MD041": false, diff --git a/Documentation/verify-authoring.mjs b/Documentation/verify-authoring.mjs new file mode 100644 index 00000000..4a4d0619 --- /dev/null +++ b/Documentation/verify-authoring.mjs @@ -0,0 +1,100 @@ +// Copyright (c) Cratis. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +import { readdir, readFile, stat } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const documentationRoot = path.dirname(fileURLToPath(import.meta.url)); +const validAsideVariants = new Set(['note', 'tip', 'caution', 'danger']); +const errors = []; + +async function filesBelow(directory) { + const files = []; + for (const entry of await readdir(directory, { withFileTypes: true })) { + const entryPath = path.join(directory, entry.name); + if (entry.isDirectory()) { + files.push(...await filesBelow(entryPath)); + } else if (/\.mdx?$/i.test(entry.name)) { + files.push(entryPath); + } + } + + return files; +} + +function validateContent(file, content) { + const isMarkdown = path.extname(file).toLowerCase() === '.md'; + let fence; + + for (const [index, line] of content.split('\n').entries()) { + const fenceMatch = line.match(/^\s*(`{3,}|~{3,})/); + if (fenceMatch) { + const marker = fenceMatch[1]; + if (!fence) { + fence = { character: marker[0], length: marker.length }; + } else if (marker[0] === fence.character && marker.length >= fence.length) { + fence = undefined; + } + continue; + } + + if (fence) continue; + + const asideMatch = line.match(/^\s*:::(\w[\w-]*)/); + if (asideMatch && !validAsideVariants.has(asideMatch[1])) { + errors.push(`${relative(file)}:${index + 1}: Unknown Starlight aside variant '${asideMatch[1]}'. Use note, tip, caution, or danger.`); + } + + if (isMarkdown && /^\s*import\s+(?:.+\s+from\s+)?['"]/.test(line)) { + errors.push(`${relative(file)}:${index + 1}: Imports require .mdx; in .md they render as visible prose.`); + } + + if (isMarkdown) { + const componentMatch = line.match(/^\s*<\/?([A-Z][A-Za-z0-9.]*)\b/); + if (componentMatch) { + errors.push(`${relative(file)}:${index + 1}: <${componentMatch[1]}> requires .mdx; in .md it renders as an inert element.`); + } + } + } +} + +async function validateLandingCollisions(files) { + for (const file of files) { + const extension = path.extname(file); + const possibleDirectory = file.slice(0, -extension.length); + let directoryStats; + try { + directoryStats = await stat(possibleDirectory); + } catch { + continue; + } + + if (!directoryStats.isDirectory()) continue; + + const entries = await readdir(possibleDirectory); + if (entries.some(entry => /^index\.mdx?$/i.test(entry))) { + errors.push(`${relative(file)}: Conflicts with ${relative(possibleDirectory)}/index.md[x]. The site demotes the directory index to /overview/ and can orphan it; keep one landing page for the route.`); + } + } +} + +function relative(file) { + return path.relative(path.dirname(documentationRoot), file).split(path.sep).join('/'); +} + +const files = await filesBelow(documentationRoot); +for (const file of files) { + validateContent(file, await readFile(file, 'utf8')); +} +await validateLandingCollisions(files); + +if (errors.length > 0) { + console.error('Documentation authoring validation failed:'); + for (const error of errors) console.error(` - ${error}`); + process.exit(1); +} + +const markdownCount = files.filter(file => path.extname(file).toLowerCase() === '.md').length; +const mdxCount = files.length - markdownCount; +console.log(`Documentation authoring validation passed for ${files.length} files (${markdownCount} .md, ${mdxCount} .mdx).`); diff --git a/Documentation/verify-markdown.sh b/Documentation/verify-markdown.sh index 64a1cdfa..b9fde748 100755 --- a/Documentation/verify-markdown.sh +++ b/Documentation/verify-markdown.sh @@ -15,7 +15,7 @@ echo "==========================================" echo "" # Always resolve from this script rather than trusting an inherited/symlinked PWD. -cd "$ROOT_DIR" +cd "$ROOT_DIR" || exit 1 echo "Working directory: $(pwd -P)" echo "" @@ -53,9 +53,9 @@ else fi echo "" -# Step 2: Link Verification +# Step 2: Starlight Authoring Validation echo "==========================================" -echo "Step 2: Running local link verification..." +echo "Step 2: Validating Starlight authoring..." echo "==========================================" echo "" @@ -64,7 +64,25 @@ if ! command -v node >/dev/null 2>&1; then exit 1 fi +node "$SCRIPT_DIR/verify-authoring.mjs" +AUTHORING_EXIT_CODE=$? + +echo "" +if [ $AUTHORING_EXIT_CODE -eq 0 ]; then + echo "✓ Starlight authoring validation passed!" +else + echo "✗ Starlight authoring validation failed with exit code $AUTHORING_EXIT_CODE" +fi +echo "" + +# Step 3: Link Verification +echo "==========================================" +echo "Step 3: Running local link verification..." +echo "==========================================" +echo "" + LINK_EXIT_CODE=0 +node "$SCRIPT_DIR/verify-local-links.mjs" --self-test || LINK_EXIT_CODE=$? for SCAN_ROOT in "$SCRIPT_DIR" "$ROOT_DIR/Adapters" "$ROOT_DIR/scripts"; do node "$SCRIPT_DIR/verify-local-links.mjs" "$SCAN_ROOT" || LINK_EXIT_CODE=$? done @@ -81,12 +99,13 @@ echo "" echo "==========================================" echo "Summary" echo "==========================================" -if [ $LINT_EXIT_CODE -eq 0 ] && [ $LINK_EXIT_CODE -eq 0 ]; then +if [ $LINT_EXIT_CODE -eq 0 ] && [ $AUTHORING_EXIT_CODE -eq 0 ] && [ $LINK_EXIT_CODE -eq 0 ]; then echo "✓ All checks passed!" exit 0 else echo "✗ Some checks failed:" [ $LINT_EXIT_CODE -ne 0 ] && echo " - Markdown linting" + [ $AUTHORING_EXIT_CODE -ne 0 ] && echo " - Starlight authoring validation" [ $LINK_EXIT_CODE -ne 0 ] && echo " - Link verification" exit 1 fi From 8fa1c39be99e81f5af29fbe819ef997286d161cf Mon Sep 17 00:00:00 2001 From: woksin Date: Wed, 9 Sep 2026 22:10:41 +0200 Subject: [PATCH 02/13] Add metadata to component landing pages Give Starlight explicit titles and descriptions while leaving navigation order to the table of contents. Preserve decision badges and normalize Markdown endings. --- Documentation/Chat/index.md | 5 ++++- Documentation/CommandDialog/index.md | 5 ++++- Documentation/CommandForm/checkbox-field.md | 1 - Documentation/CommandForm/index.md | 5 ++++- Documentation/CommandForm/input-text-field.md | 1 - Documentation/CommandForm/number-field.md | 1 - Documentation/CommandForm/slider-field.md | 1 - Documentation/CommandStepper/index.md | 5 ++++- Documentation/Common/index.md | 5 ++++- Documentation/DataPage/index.md | 5 ++++- Documentation/DataPage/menu-items.md | 2 +- Documentation/DataTables/index.md | 5 ++++- Documentation/Dialogs/index.md | 5 ++++- Documentation/Display/index.md | 5 ++++- Documentation/Filter/index.md | 5 ++++- Documentation/Migration/index.md | 5 ++++- Documentation/ObjectContentEditor/index.md | 5 ++++- Documentation/ObjectNavigationalBar/index.md | 5 ++++- Documentation/PivotViewer/index.md | 5 ++++- Documentation/SchemaEditor/index.md | 5 ++++- Documentation/StepperCommandDialog/index.md | 5 ++++- Documentation/TimeMachine/index.md | 5 ++++- Documentation/Toolbar/index.md | 5 ++++- Documentation/Types/index.md | 6 ++++-- Documentation/building-a-form.md | 2 -- Documentation/decisions/0001-dom-coupled-contract.md | 1 - Documentation/decisions/0002-component-classification.md | 1 - Documentation/decisions/0003-kernel-boundary.md | 1 - .../decisions/0004-stable-presentation-renderer-profile.md | 1 - Documentation/displaying-data.md | 2 -- Documentation/getting-started.mdx | 2 -- Documentation/list-screen-with-actions.md | 2 -- Documentation/multi-step-form.md | 2 -- Documentation/ui-foundation.md | 2 -- Documentation/why-components.md | 2 -- 35 files changed, 77 insertions(+), 43 deletions(-) diff --git a/Documentation/Chat/index.md b/Documentation/Chat/index.md index fafcf425..f33f682e 100644 --- a/Documentation/Chat/index.md +++ b/Documentation/Chat/index.md @@ -1,4 +1,7 @@ -# Chat +--- +title: Chat +description: Build topic-based chat with host-owned data, mentions, emoji, and message actions. +--- The `Chat` components give an application a topic-based chat that opens in a sidebar next to the view — a topics list, the conversation for the picked topic, `@`-mentions of people and agents, emoji, and per-message actions — without the library holding any opinion about where the data lives or what a backend looks like. diff --git a/Documentation/CommandDialog/index.md b/Documentation/CommandDialog/index.md index 0c98ff43..ddf4b0a6 100644 --- a/Documentation/CommandDialog/index.md +++ b/Documentation/CommandDialog/index.md @@ -1,4 +1,7 @@ -# CommandDialog +--- +title: CommandDialog +description: Execute Arc commands in a dialog with automatic form state, validation, and result handling. +--- The `CommandDialog` component provides a dialog interface for executing commands with built-in form handling and validation. diff --git a/Documentation/CommandForm/checkbox-field.md b/Documentation/CommandForm/checkbox-field.md index 610de7b9..1f6cea63 100644 --- a/Documentation/CommandForm/checkbox-field.md +++ b/Documentation/CommandForm/checkbox-field.md @@ -25,4 +25,3 @@ import { CheckboxField } from '@cratis/components/CommandForm'; - Default value is `false`. - Validation state is reflected through `aria-invalid` and `data-invalid`. - diff --git a/Documentation/CommandForm/index.md b/Documentation/CommandForm/index.md index 48f1fc6e..1748ee6f 100644 --- a/Documentation/CommandForm/index.md +++ b/Documentation/CommandForm/index.md @@ -1,4 +1,7 @@ -# CommandForm +--- +title: CommandForm +description: Build type-safe Arc command forms with reusable fields, validation, and automatic value binding. +--- The `CommandForm` component provides form field components for building command input forms with automatic type handling and validation. diff --git a/Documentation/CommandForm/input-text-field.md b/Documentation/CommandForm/input-text-field.md index e9c0a4ae..f003f544 100644 --- a/Documentation/CommandForm/input-text-field.md +++ b/Documentation/CommandForm/input-text-field.md @@ -28,4 +28,3 @@ import { InputTextField } from '@cratis/components/CommandForm'; - Default value is an empty string. - The field spans full width within its container. - Validation state is reflected through `aria-invalid` and `data-invalid`. - diff --git a/Documentation/CommandForm/number-field.md b/Documentation/CommandForm/number-field.md index c7e9c577..ba9db363 100644 --- a/Documentation/CommandForm/number-field.md +++ b/Documentation/CommandForm/number-field.md @@ -30,4 +30,3 @@ import { NumberField } from '@cratis/components/CommandForm'; - The field spans full width within its container. - Validation state is reflected through `aria-invalid` and `data-invalid`. - When the value is cleared, it falls back to `0`. - diff --git a/Documentation/CommandForm/slider-field.md b/Documentation/CommandForm/slider-field.md index 1bb6585e..6ed615c7 100644 --- a/Documentation/CommandForm/slider-field.md +++ b/Documentation/CommandForm/slider-field.md @@ -28,4 +28,3 @@ import { SliderField } from '@cratis/components/CommandForm'; - Default value is `0`. - The slider spans full width within its container. - The selected numeric value is rendered centered beneath the slider track. - diff --git a/Documentation/CommandStepper/index.md b/Documentation/CommandStepper/index.md index 45717a74..5f50a91c 100644 --- a/Documentation/CommandStepper/index.md +++ b/Documentation/CommandStepper/index.md @@ -1,4 +1,7 @@ -# CommandStepper +--- +title: CommandStepper +description: Split an Arc command form into validation-aware steps for wizard-style workflows. +--- The `CommandStepper` component is a command-scoped stepper foundation for wizard-style flows. diff --git a/Documentation/Common/index.md b/Documentation/Common/index.md index 0926ffef..30b9b97c 100644 --- a/Documentation/Common/index.md +++ b/Documentation/Common/index.md @@ -1,4 +1,7 @@ -# Common Components +--- +title: Common Components +description: Reference the shared controls, provider, layout, icons, and form utilities used across Components. +--- The Common module provides reusable UI components and the styling setup primitive that serve as building blocks for applications. diff --git a/Documentation/DataPage/index.md b/Documentation/DataPage/index.md index 8bca029e..d218bc4d 100644 --- a/Documentation/DataPage/index.md +++ b/Documentation/DataPage/index.md @@ -1,4 +1,7 @@ -# DataPage +--- +title: DataPage +description: Combine query-backed tables, actions, selection, and optional details in a complete data page. +--- The `DataPage` component provides a complete page layout for displaying and managing data from queries, including table view, menu actions, and optional detail panels. diff --git a/Documentation/DataPage/menu-items.md b/Documentation/DataPage/menu-items.md index 056b8cc3..b5e766b4 100644 --- a/Documentation/DataPage/menu-items.md +++ b/Documentation/DataPage/menu-items.md @@ -96,7 +96,7 @@ import { FaFloppyDisk, FaDownload, FaUpload } from 'react-icons/fa6'; ``` -:::caution +:::caution[Pass an icon component] Don't pass `icon="pi pi-save"` (a PrimeIcons CSS class) or `icon={}` (a JSX element). DataPage instantiates the icon itself, so the prop must be the component type: `icon={FaFloppyDisk}`. ::: diff --git a/Documentation/DataTables/index.md b/Documentation/DataTables/index.md index c5cd573f..defa4250 100644 --- a/Documentation/DataTables/index.md +++ b/Documentation/DataTables/index.md @@ -1,4 +1,7 @@ -# DataTables +--- +title: DataTables +description: Render local, paged, and observable query data with sorting, filtering, and selection. +--- The DataTables module provides a semantic local-array table plus specialized Arc query and observable-query wrappers. diff --git a/Documentation/Dialogs/index.md b/Documentation/Dialogs/index.md index 15debcca..c2c37c6d 100644 --- a/Documentation/Dialogs/index.md +++ b/Documentation/Dialogs/index.md @@ -1,4 +1,7 @@ -# Dialogs +--- +title: Dialogs +description: Present custom content, busy states, and confirmations with the shared dialog components. +--- The Dialogs module provides common dialog components for user interactions. diff --git a/Documentation/Display/index.md b/Documentation/Display/index.md index 403d4c7a..d12d2f1c 100644 --- a/Documentation/Display/index.md +++ b/Documentation/Display/index.md @@ -1,4 +1,7 @@ -# Display +--- +title: Display +description: Show statuses, counts, avatars, progress, and loading states with presentational primitives. +--- The `Display` components are small, presentational primitives for status and feedback — tags, badges, chips, avatars, progress, and loading skeletons. Import them from `@cratis/components/Display`. diff --git a/Documentation/Filter/index.md b/Documentation/Filter/index.md index 55a351d4..6186b3bd 100644 --- a/Documentation/Filter/index.md +++ b/Documentation/Filter/index.md @@ -1,4 +1,7 @@ -# FilterPanel +--- +title: FilterPanel +description: Build reusable filter panels with option, range, and custom editors. +--- The `FilterPanel` component provides a standalone, reusable filter UI that can be placed next to any data view. It renders as a positioned dropdown anchored below a trigger button and supports single-select, multi-select, numeric range (with histogram), and fully custom filter editors declared as children. diff --git a/Documentation/Migration/index.md b/Documentation/Migration/index.md index e97340ca..b6426029 100644 --- a/Documentation/Migration/index.md +++ b/Documentation/Migration/index.md @@ -1,4 +1,7 @@ -# Migration +--- +title: Migration +description: Move @cratis/components applications between major versions with focused upgrade guides. +--- Guides for moving `@cratis/components` forward across major versions. Each guide is scoped to one version jump and lists the changes a consuming application can observe: dependencies, imports, styling, licensing, behavior, and verification. diff --git a/Documentation/ObjectContentEditor/index.md b/Documentation/ObjectContentEditor/index.md index 5bd2a5b4..4d8e8766 100644 --- a/Documentation/ObjectContentEditor/index.md +++ b/Documentation/ObjectContentEditor/index.md @@ -1,4 +1,7 @@ -# ObjectContentEditor +--- +title: ObjectContentEditor +description: Explore complex JSON objects with schema-aware rendering and breadcrumb navigation. +--- The `ObjectContentEditor` component displays and allows exploration of complex JSON objects with schema-aware rendering and navigation. diff --git a/Documentation/ObjectNavigationalBar/index.md b/Documentation/ObjectNavigationalBar/index.md index fad938be..d88caf3b 100644 --- a/Documentation/ObjectNavigationalBar/index.md +++ b/Documentation/ObjectNavigationalBar/index.md @@ -1,4 +1,7 @@ -# ObjectNavigationalBar +--- +title: ObjectNavigationalBar +description: Navigate hierarchical objects with a controlled breadcrumb bar and back action. +--- The `ObjectNavigationalBar` component provides breadcrumb navigation for hierarchical data structures. diff --git a/Documentation/PivotViewer/index.md b/Documentation/PivotViewer/index.md index 168cae3d..c6dc2c7d 100644 --- a/Documentation/PivotViewer/index.md +++ b/Documentation/PivotViewer/index.md @@ -1,4 +1,7 @@ -# PivotViewer +--- +title: PivotViewer +description: Explore large datasets through interactive grouping, filtering, zooming, and spatial rendering. +--- The `PivotViewer` component provides an interactive, high-performance visualization for exploring large datasets with dynamic grouping, filtering, and zooming capabilities. diff --git a/Documentation/SchemaEditor/index.md b/Documentation/SchemaEditor/index.md index 9db59001..5a4e1f21 100644 --- a/Documentation/SchemaEditor/index.md +++ b/Documentation/SchemaEditor/index.md @@ -1,4 +1,7 @@ -# SchemaEditor +--- +title: SchemaEditor +description: Create and edit supported JSON Schema structures in an interactive table. +--- The `SchemaEditor` component provides an interactive table-based interface for creating and editing JSON schemas. diff --git a/Documentation/StepperCommandDialog/index.md b/Documentation/StepperCommandDialog/index.md index ca3a5600..fd1e7410 100644 --- a/Documentation/StepperCommandDialog/index.md +++ b/Documentation/StepperCommandDialog/index.md @@ -1,4 +1,7 @@ -# StepperCommandDialog +--- +title: StepperCommandDialog +description: Execute Arc commands through a multi-step dialog with validation-aware navigation. +--- The `StepperCommandDialog` component provides a multi-step wizard dialog interface for executing commands, built on top of the Cratis-owned `CommandStepper`. diff --git a/Documentation/TimeMachine/index.md b/Documentation/TimeMachine/index.md index 5f73d648..8fd52425 100644 --- a/Documentation/TimeMachine/index.md +++ b/Documentation/TimeMachine/index.md @@ -1,4 +1,7 @@ -# TimeMachine +--- +title: TimeMachine +description: Explore versions, events, and read-model changes along an interactive timeline. +--- The `TimeMachine` component provides an interactive timeline visualization for exploring the evolution of data over time through events and state changes. diff --git a/Documentation/Toolbar/index.md b/Documentation/Toolbar/index.md index d8e23ee6..267dd474 100644 --- a/Documentation/Toolbar/index.md +++ b/Documentation/Toolbar/index.md @@ -1,4 +1,7 @@ -# Toolbar +--- +title: Toolbar +description: Build canvas-style tool palettes with groups, contexts, slots, folders, and fan-out panels. +--- The `Toolbar` component provides a canvas-style icon toolbar with support for orientations, active states, animated context switching, separators, fan-out sub-panels, and drag & drop onto surfaces. diff --git a/Documentation/Types/index.md b/Documentation/Types/index.md index f2a03313..87a4ed73 100644 --- a/Documentation/Types/index.md +++ b/Documentation/Types/index.md @@ -1,4 +1,7 @@ -# Types +--- +title: Types +description: Reference the shared TypeScript types and constants exported by Components. +--- The `Types` module exports shared TypeScript types and constants used across the component library. Import from `@cratis/components/types`. @@ -102,4 +105,3 @@ interface NavigationItem { ``` Used internally by `ObjectNavigationalBar`. - diff --git a/Documentation/building-a-form.md b/Documentation/building-a-form.md index 10af7150..b94ae2f1 100644 --- a/Documentation/building-a-form.md +++ b/Documentation/building-a-form.md @@ -1,8 +1,6 @@ --- title: 'Recipe: Building a form' description: Execute a command from a typed form using CommandDialog and CommandForm fields, with validation handled for you. -sidebar: - order: 3 --- **Goal:** collect input and run an Arc command — with the confirm button disabled while it executes, validation wired up, and no manual fetch. diff --git a/Documentation/decisions/0001-dom-coupled-contract.md b/Documentation/decisions/0001-dom-coupled-contract.md index be52b87b..582b4e4b 100644 --- a/Documentation/decisions/0001-dom-coupled-contract.md +++ b/Documentation/decisions/0001-dom-coupled-contract.md @@ -2,7 +2,6 @@ title: DOM-coupled public component contract description: Why Components intentionally exposes React, HTML, native form, ref, and DOM event semantics while keeping renderer vendors private. sidebar: - order: 1 badge: { text: Accepted, variant: tip } --- diff --git a/Documentation/decisions/0002-component-classification.md b/Documentation/decisions/0002-component-classification.md index 87978ce2..43ab8e1e 100644 --- a/Documentation/decisions/0002-component-classification.md +++ b/Documentation/decisions/0002-component-classification.md @@ -2,7 +2,6 @@ title: Public component classification description: The architecture categories assigned to every component exported by the public package barrels. sidebar: - order: 2 badge: { text: Accepted, variant: tip } --- diff --git a/Documentation/decisions/0003-kernel-boundary.md b/Documentation/decisions/0003-kernel-boundary.md index 5ee6e063..b9f63d52 100644 --- a/Documentation/decisions/0003-kernel-boundary.md +++ b/Documentation/decisions/0003-kernel-boundary.md @@ -2,7 +2,6 @@ title: Repository-owned kernel boundary description: The explicit React-free and browser-DOM-free computation kernel enforced in Components source and emitted package graphs. sidebar: - order: 3 badge: { text: Accepted, variant: tip } --- diff --git a/Documentation/decisions/0004-stable-presentation-renderer-profile.md b/Documentation/decisions/0004-stable-presentation-renderer-profile.md index 172eb763..b11078e8 100644 --- a/Documentation/decisions/0004-stable-presentation-renderer-profile.md +++ b/Documentation/decisions/0004-stable-presentation-renderer-profile.md @@ -2,7 +2,6 @@ title: Stable presentation renderer profile description: The bounded nine-slot renderer contract promoted after independent conformance proof. sidebar: - order: 4 badge: { text: Accepted, variant: tip } --- diff --git a/Documentation/displaying-data.md b/Documentation/displaying-data.md index 1d63b1ae..4a823bdc 100644 --- a/Documentation/displaying-data.md +++ b/Documentation/displaying-data.md @@ -1,8 +1,6 @@ --- title: "Recipe: Displaying data" description: Render query results in a data table that updates live, and build list-and-detail screens with DataPage. -sidebar: - order: 4 --- **Goal:** show the results of an Arc query in a table — and have it update on its own when the underlying read model changes. diff --git a/Documentation/getting-started.mdx b/Documentation/getting-started.mdx index 9e142bf3..ff99afd5 100644 --- a/Documentation/getting-started.mdx +++ b/Documentation/getting-started.mdx @@ -1,8 +1,6 @@ --- title: Getting started description: Install Components, mount the provider, and render your first type-safe command form. -sidebar: - order: 2 --- import { Steps, Aside } from '@astrojs/starlight/components'; diff --git a/Documentation/list-screen-with-actions.md b/Documentation/list-screen-with-actions.md index d807be5b..3de1f2d1 100644 --- a/Documentation/list-screen-with-actions.md +++ b/Documentation/list-screen-with-actions.md @@ -1,8 +1,6 @@ --- title: "Recipe: A list screen with actions" description: Combine a live table with command dialogs to build the everyday "list things, add/edit/remove them" screen. -sidebar: - order: 6 --- **Goal:** the most common screen in any app — a table of things with a toolbar to add, and per-row actions to edit or remove. This recipe wires [displaying data](/components/displaying-data/) and [running commands](/components/building-a-form/) together. diff --git a/Documentation/multi-step-form.md b/Documentation/multi-step-form.md index 9ec3e677..ac628899 100644 --- a/Documentation/multi-step-form.md +++ b/Documentation/multi-step-form.md @@ -1,8 +1,6 @@ --- title: "Recipe: Multi-step form" description: Gather a command's input across several named steps with StepperCommandDialog. -sidebar: - order: 5 --- **Goal:** one command needs more input than fits comfortably on a single screen. Split it into a wizard — named steps the user moves through — that still executes a single command at the end. diff --git a/Documentation/ui-foundation.md b/Documentation/ui-foundation.md index 611a8ea1..285d573f 100644 --- a/Documentation/ui-foundation.md +++ b/Documentation/ui-foundation.md @@ -1,8 +1,6 @@ --- title: UI foundation description: How Components owns its public React contracts and delegates selected interaction primitives. -sidebar: - order: 2 --- Components 4 owns its public React markup, TypeScript types, tokens, documented parts, and component behavior without exposing its internal interaction library as a consumer contract. The public component contract is deliberately coupled to React and the browser DOM: standard HTML attributes, React refs, native element types, form behavior, and DOM event semantics are intentional guarantees. React Aria supplies selected focus, keyboard, overlay, collection, and date interaction primitives internally. These implementation facts do not establish accessibility conformance for every component or application. diff --git a/Documentation/why-components.md b/Documentation/why-components.md index c4f0c3c7..dcead31f 100644 --- a/Documentation/why-components.md +++ b/Documentation/why-components.md @@ -1,8 +1,6 @@ --- title: Why Components description: Why Components owns React composition around Arc proxies and selected interaction primitives. -sidebar: - order: 1 --- You can connect an Arc-generated command or query to any React UI. Without Components, every application repeatedly builds command execution state, validation display, dialogs, observable subscriptions, paging, selection, empty/pending states, localization, and accessibility behavior. From acafcbf85e2b08562d212d71a3e2ae45da58dd94 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 09:45:48 +0200 Subject: [PATCH 03/13] Correct command stepper guidance --- Documentation/CommandStepper/index.md | 22 ++++++++++----------- Documentation/StepperCommandDialog/index.md | 6 +++--- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/Documentation/CommandStepper/index.md b/Documentation/CommandStepper/index.md index 5f50a91c..acd42943 100644 --- a/Documentation/CommandStepper/index.md +++ b/Documentation/CommandStepper/index.md @@ -3,19 +3,13 @@ title: CommandStepper description: Split an Arc command form into validation-aware steps for wizard-style workflows. --- -The `CommandStepper` component is a command-scoped stepper foundation for wizard-style flows. +The `CommandStepper` component executes one Arc command through an inline, multi-step form. ## Purpose -`CommandStepper` establishes a `CommandForm` context and focuses on step rendering and validation-driven navigation. +Use `CommandStepper` when the wizard belongs directly in a page region, panel, or route. It establishes a `CommandForm`, renders `StepperPanel` steps with built-in navigation, and executes the command from the final step. -Use it when you want to: - -- Render `StepperPanel` steps with built-in previous and next navigation -- Color step number circles based on validation state -- Keep form validation and step transitions scoped to a single command - -`StepperCommandDialog` is built on top of `CommandStepper` and adds command execution, submission flow, and dialog behavior. +`CommandStepper` and [`StepperCommandDialog`](../StepperCommandDialog/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. Both execute the command. Choose `StepperCommandDialog` when the wizard should be modal; it also owns dialog dismissal, authorization-result routing, and its execution busy state. ## Basic Usage @@ -55,12 +49,16 @@ export const ProjectWizard = () => { - `showSubmit`: Show the built-in submit action on the last step (default: `true`) - `okLabel`: Submit button label. Falls back to the provider's `messages.stepper.submit`, then `'Submit'` - `isBusy`: Disables the navigation controls while something is running -- `onSubmit`: Submit callback invoked on the last step -- Any `CommandForm` props, including `initialValues`, `currentValues`, `validateOnInit`, and validation callbacks +- `onSuccess`: Callback invoked with the typed response after successful command execution +- `onValidationFailure`: Callback invoked with validation results when command execution returns validation errors +- `onFailed`: Callback invoked with the full command result for an unsuccessful, non-validation result +- Other applicable `CommandForm` props, including `initialValues`, `currentValues`, `validateOnInit`, and field-validation callbacks - `onBeforeExecute`: Transform command values before execution — it must **return** the values to run with, and it runs only on submit, so it can never satisfy required-field validation (seed those through `initialValues`) - `linear` (default `true`), `orientation` (`'horizontal'` default / `'vertical'`), `headerPosition` (`'top'` default / `'bottom'`), `start`, `end`, `onChangeStep`, and `pt`: the active `StepperCustomizationProps` surface. It maps onto stable `root`, `list`, `step`, `header`, `number`, `title`, `separator`, `panels`, and `panel` parts. - `ptOptions` and `unstyled`: retained temporarily for source compatibility; ignored because Cratis part attributes always merge and styling is CSS-owned. +There is no outer dialog, so `CommandStepper` has no `dialogPt` or `dialogUnstyled` props. Its `pt` prop targets the stepper directly. + Conditional steps written as `{condition && }` are counted correctly — only the panels that actually render are counted, so navigation and the per-step validation state stay in step with what is on screen. A `<>…` fragment wrapping several panels still counts as **one** step. ## Validation Indicators @@ -75,4 +73,4 @@ The step number circles are then styled based on state: ## See Also -- [StepperCommandDialog](../StepperCommandDialog/index.md) +- [StepperCommandDialog](../StepperCommandDialog/index.md) — place the same kind of command wizard in a modal dialog diff --git a/Documentation/StepperCommandDialog/index.md b/Documentation/StepperCommandDialog/index.md index fd1e7410..406c8ac0 100644 --- a/Documentation/StepperCommandDialog/index.md +++ b/Documentation/StepperCommandDialog/index.md @@ -3,7 +3,7 @@ title: StepperCommandDialog description: Execute Arc commands through a multi-step dialog with validation-aware navigation. --- -The `StepperCommandDialog` component provides a multi-step wizard dialog interface for executing commands, built on top of the Cratis-owned `CommandStepper`. +The `StepperCommandDialog` component executes one Arc command through a modal, multi-step form. It and [`CommandStepper`](../CommandStepper/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. ## Purpose @@ -280,10 +280,10 @@ The count is not fixed for the lifetime of the dialog either. A late-resolving q - `@cratis/arc/commands` for command execution - `@cratis/arc.react/commands` for form handling -- the Cratis-owned Stepper and `StepperPanel` for the wizard UI +- the private `CommandStepperContent` rendering primitive and public `StepperPanel` marker for the wizard UI - The Cratis [`Dialog`](../Dialogs/dialog.md) for the modal wrapper ## See Also - [Advanced Features](advanced-features.md) - Field validation, transformation, and change tracking across steps -- [CommandStepper](../CommandStepper/index.md) - Standalone stepper foundation component +- [CommandStepper](../CommandStepper/index.md) — render an executing command wizard inline without a modal dialog From 01e50318b00ca5aa9b2d08ebbbe1b6e5f03504f9 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 09:47:27 +0200 Subject: [PATCH 04/13] Document ActionMenubar --- Documentation/Common/action-menubar.md | 59 ++++++++++++++++++++++++++ Documentation/Common/index.md | 2 + Documentation/Common/toc.yml | 2 + Documentation/Toolbar/index.md | 2 +- Documentation/choosing-a-component.md | 2 +- 5 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 Documentation/Common/action-menubar.md diff --git a/Documentation/Common/action-menubar.md b/Documentation/Common/action-menubar.md new file mode 100644 index 00000000..aed096f7 --- /dev/null +++ b/Documentation/Common/action-menubar.md @@ -0,0 +1,59 @@ +--- +title: ActionMenubar +description: Render a horizontal toolbar of page-level command actions. +--- + + + + +`ActionMenubar` renders a flat set of command actions from `@cratis/components/Common`. Use it for page-level actions; use [`Toolbar`](../Toolbar/index.md) for a canvas-style tool palette with active tools, groups, folders, or fan-out panels. + +## Basic usage + +```tsx +import { ActionMenubar } from '@cratis/components/Common'; + +; +``` + +The root is a `div` with `role='toolbar'` and `data-cratis-part='root'`. Pass `aria-label` to set the toolbar's accessible name. + +## `ActionMenuItem` + +| Field | Type | Purpose | +| ----------- | ------------------------------------------- | -------------------------------------------- | +| `label` | `string` | Visible button label. | +| `icon` | `ReactNode` | Content rendered before the label. | +| `command` | `() => void` | Invoked when the action is activated. | +| `disabled` | `boolean` | Disables the action button. | +| `className` | `string` | Extra class name for the action button. | +| `severity` | `ButtonSeverity` | Maps the action severity to a button tone. | +| `template` | `(item: ActionMenuItem) => ReactNode` | Fully replaces rendering for this menu item. | + +When `template` is present, `ActionMenubar` renders its result directly instead of rendering a Components `Button`. The item's `severity`, `disabled`, and `className`, the shared `pt`, and the normal button label, icon, and command wiring therefore do not apply unless the template implements them. + +## `ActionMenubarProps` + +| Prop | Type | Required | Purpose | +| ------------ | ------------------ | -------- | ---------------------------------------------------------- | +| `model` | `ActionMenuItem[]` | Yes | Actions rendered from left to right. | +| `className` | `string` | No | Extra class name for the toolbar root. | +| `aria-label` | `string` | No | Accessible name for the toolbar. | +| `pt` | `ButtonParts` | No | Part attributes applied to every non-template action button. | +| `ptOptions` | `object` | No | Deprecated, retained for source compatibility, and ignored. | +| `unstyled` | `boolean` | No | Deprecated, retained for source compatibility, and ignored. | + +`pt` is the [`ButtonParts`](basic-controls.md) surface, not a toolbar-root parts object. It is passed to each `Button` created from the model. Use `className` to identify the `ActionMenubar` root. + +## See also + +- [DataPage](../DataPage/index.md) — the list-page composition that uses `ActionMenubar` for its action row +- [Toolbar](../Toolbar/index.md) — canvas-style tool palettes +- [Stable component parts](../Styling/pass-through.md) — Components-owned parts and state attributes diff --git a/Documentation/Common/index.md b/Documentation/Common/index.md index 30b9b97c..37c4bf92 100644 --- a/Documentation/Common/index.md +++ b/Documentation/Common/index.md @@ -11,6 +11,7 @@ The Common module provides reusable UI components and the styling setup primitiv - **TextInput / TextArea**: Native text controls with semantic string changes and real element refs. - **Checkbox / Radio / Switch**: Native form choices with semantic boolean changes and browser-owned submission and reset behavior. - **Button / IconButton**: Native actions with semantic variants, tones, loading, and disabled behavior. +- **ActionMenubar**: Horizontal toolbar of page-level command actions. - **Surface**: A bounded `div`, `section`, or `article` container with no invented interaction state. - **Icon / IconDisplay**: Unified icon type that accepts a CSS class string or any React node. - **Page**: Layout primitive for consistent page structures. @@ -20,6 +21,7 @@ The Common module provides reusable UI components and the styling setup primitiv ## See Also - [Basic controls](basic-controls.md) — native form, ref, change, part, and state contracts +- [ActionMenubar](action-menubar.md) — page-level command actions - [CratisComponentsProvider](cratis-components-provider.md) — locale, labels, and toaster configuration - [Icon](icon.md) - Icon type and IconDisplay component - [Page](page.md) - Page layout component diff --git a/Documentation/Common/toc.yml b/Documentation/Common/toc.yml index c99986f1..901b0759 100644 --- a/Documentation/Common/toc.yml +++ b/Documentation/Common/toc.yml @@ -4,6 +4,8 @@ href: cratis-components-provider.md - name: Basic controls href: basic-controls.md +- name: ActionMenubar + href: action-menubar.md - name: Icon href: icon.md - name: Page diff --git a/Documentation/Toolbar/index.md b/Documentation/Toolbar/index.md index 267dd474..0adcf836 100644 --- a/Documentation/Toolbar/index.md +++ b/Documentation/Toolbar/index.md @@ -7,7 +7,7 @@ The `Toolbar` component provides a canvas-style icon toolbar with support for or Toolbar belongs to the [Advanced React capability profile](../ui-foundation.md#capability-profiles) — a specialized, React-only surface with no Pixi dependency, despite its canvas-adjacent purpose. -**`Toolbar` is not a default page action row.** It is built for a canvas/tool-palette interaction — active tools, groups, slots, folders, and fan-out panels — not for an ordinary page's list of commands. `DataPage`'s built-in action row renders `ActionMenubar` (from `@cratis/components/Common`), not `Toolbar`. Reach for `ActionMenubar`, or a product-owned action row, for flat page-level actions; reach for `Toolbar` only when the surface is genuinely a spatial tool palette. See [Choosing a component: Actions and tool palettes](../choosing-a-component.md#actions-and-tool-palettes). +**`Toolbar` is not a default page action row.** It is built for a canvas/tool-palette interaction — active tools, groups, slots, folders, and fan-out panels — not for an ordinary page's list of commands. `DataPage`'s built-in action row renders `ActionMenubar` (from `@cratis/components/Common`), not `Toolbar`. Reach for [`ActionMenubar`](../Common/action-menubar.md), or a product-owned action row, for flat page-level actions; reach for `Toolbar` only when the surface is genuinely a spatial tool palette. See [Choosing a component: Actions and tool palettes](../choosing-a-component.md#actions-and-tool-palettes). Pass React icon nodes or product-owned SVGs for a dependency-free toolbar. Consumer-owned icon-font class strings remain accepted, but Components does not install an icon font or infer provider base classes; the product must load the matching stylesheet and pass the complete class string. diff --git a/Documentation/choosing-a-component.md b/Documentation/choosing-a-component.md index b5cb07c3..f7336e69 100644 --- a/Documentation/choosing-a-component.md +++ b/Documentation/choosing-a-component.md @@ -42,7 +42,7 @@ actions. ## Actions and tool palettes -Use `ActionMenubar` or an ordinary product action row for flat page commands. `DataPage`'s built-in toolbar already renders `ActionMenubar`, not `Toolbar` — that is the default action row for a page, not a canvas tool palette. Use [`Toolbar`](./Toolbar/index.md) only for a genuine canvas/tool-palette interaction with active tools, groups, slots, folders, and fan-out panels. It is not a one-for-one replacement for a generic Prime Toolbar, and it is not a page-level action row wearing a different name. +Use [`ActionMenubar`](./Common/action-menubar.md) or an ordinary product action row for flat page commands. `DataPage`'s built-in toolbar already renders `ActionMenubar`, not `Toolbar` — that is the default action row for a page, not a canvas tool palette. Use [`Toolbar`](./Toolbar/index.md) only for a genuine canvas/tool-palette interaction with active tools, groups, slots, folders, and fan-out panels. It is not a one-for-one replacement for a generic Prime Toolbar, and it is not a page-level action row wearing a different name. ## Spatial workspaces From 860f287e0031b4fd0352df50cd01d08860b058d2 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 09:49:06 +0200 Subject: [PATCH 05/13] Add symptom-based troubleshooting --- Documentation/Styling/index.md | 4 ++++ Documentation/getting-started.mdx | 1 + Documentation/renderers/index.md | 1 + Documentation/toc.yml | 2 ++ Documentation/troubleshooting.md | 37 +++++++++++++++++++++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 Documentation/troubleshooting.md diff --git a/Documentation/Styling/index.md b/Documentation/Styling/index.md index 41d7e152..86c1bcfe 100644 --- a/Documentation/Styling/index.md +++ b/Documentation/Styling/index.md @@ -41,3 +41,7 @@ import './product-components.css'; ``` React Aria is internal. Never style React Aria class names or undocumented DOM structure. + +## See also + +- [Troubleshoot product CSS precedence](../troubleshooting.md#product-css-does-not-win-over-components-styles) diff --git a/Documentation/getting-started.mdx b/Documentation/getting-started.mdx index ff99afd5..3add7e8d 100644 --- a/Documentation/getting-started.mdx +++ b/Documentation/getting-started.mdx @@ -173,3 +173,4 @@ You installed one UI package, imported Components-owned styles, and mounted a lo - [Choosing a component](/components/choosing-a-component/) - [Migrate from Components 3](/components/migration/) - [Understand the UI foundation](/components/ui-foundation/) — including the capability profiles and capability matrix behind Foundation, Advanced React, and Spatial components +- [Troubleshoot a Components symptom](/components/troubleshooting/) diff --git a/Documentation/renderers/index.md b/Documentation/renderers/index.md index 04212e5a..0a481494 100644 --- a/Documentation/renderers/index.md +++ b/Documentation/renderers/index.md @@ -116,3 +116,4 @@ Use the schema for editor/build-time manifest validation, then run `@cratis/comp presentation. - Use [custom composition](custom-composition.md) when the workflow itself must be vendor-native. - Check [unsupported renderer claims](unsupported.md) before promising replacement behavior. +- Use [Troubleshooting](../troubleshooting.md#an-adapter-still-renders-a-built-in-control) when an active adapter falls back to a built-in control. diff --git a/Documentation/toc.yml b/Documentation/toc.yml index 47536727..0d82c424 100644 --- a/Documentation/toc.yml +++ b/Documentation/toc.yml @@ -70,5 +70,7 @@ href: Common/toc.yml - name: Types href: Types/toc.yml +- name: Troubleshooting + href: troubleshooting.md - name: Migration href: Migration/toc.yml diff --git a/Documentation/troubleshooting.md b/Documentation/troubleshooting.md new file mode 100644 index 00000000..2484a995 --- /dev/null +++ b/Documentation/troubleshooting.md @@ -0,0 +1,37 @@ +--- +title: Troubleshooting +description: Find the owning guidance for common Components installation, styling, rendering, and form symptoms. +--- + + + + +Start from the symptom you can observe. Each entry points to the page that owns the current contract and remedy. + +## The command submit button stays disabled + +Required command values must be visible to client validation before submission. Put non-input required values in `initialValues`, or keep custom controls synchronized through `currentValues`; a value first created in `onBeforeExecute` arrives too late to satisfy the validity gate. Follow [Building a form](building-a-form.md#tips) for the short rule and [CommandDialog advanced features](CommandDialog/advanced-features.md#custom-inputs) for custom inputs. + +## Yarn PnP cannot resolve `rxjs` from Arc React + +The current `@cratis/arc.react@22.6.2` package imports `rxjs` without declaring it. A strict Yarn PnP consumer needs the temporary `packageExtensions` entry and `rxjs` version shown in [Getting started](getting-started.mdx#yarn-pnp-with-arc-react-2262). + +## Product CSS does not win over Components styles + +Import the product stylesheet after the Components `tokens` and `styles` entries. Unlayered product CSS wins over the low-priority Components layers; a product that uses its own cascade layers must declare their order explicitly. See the [Styling cascade contract](Styling/index.md#cascade-contract) and the [mixed styling example](Styling/mixing-paths.md). + +## A component import from the package root no longer compiles + +The Components 4 package root is setup-only. Import components from explicit subpaths and use the current namespace-to-subpath mapping in [Migrate from Components 3 to 4](Migration/3-to-4.md#import-from-explicit-subpaths). + +## An adapter still renders a built-in control + +The public adapters implement the declared presentation slots rather than replacing every Components export. With the default `rendererFallback='core'`, undeclared slots use the built-in implementation; `rendererFallback='throw'` rejects that fallback without adding adapter coverage. See [Primitive adaptation: Fallback](renderers/primitive-adaptation.md#fallback) and [Unsupported renderer claims](renderers/unsupported.md#no-transparent-full-catalog-replacement). + +## Server rendering crashes on a browser global + +Use the [UI foundation capability matrix](ui-foundation.md#capability-matrix) to check the server-rendering boundary for the component profile. For a custom portal container, resolve `document` inside `overlayEnvironment.getContainer` and return `null` when it is unavailable, as shown in [Choose an overlay container](Common/cratis-components-provider.md#choose-an-overlay-container). + +## See also + +For generated proxies, command authorization, command validation, and Arc request behavior, use [Arc troubleshooting](/arc/troubleshooting/). From db0e93119e6c7a53354c7bac5240d4fe5dab9b1d Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 09:50:32 +0200 Subject: [PATCH 06/13] Improve recipe paths and tutorial visibility --- Documentation/building-a-form.md | 5 +++-- Documentation/displaying-data.md | 6 ++++-- Documentation/getting-started.mdx | 1 + Documentation/index.mdx | 3 +++ Documentation/list-screen-with-actions.md | 6 ++++-- Documentation/multi-step-form.md | 7 ++++--- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Documentation/building-a-form.md b/Documentation/building-a-form.md index b94ae2f1..d2f90a8e 100644 --- a/Documentation/building-a-form.md +++ b/Documentation/building-a-form.md @@ -69,5 +69,6 @@ const [AddAuthorDialog, showAddAuthor] = useDialog(AddAuthor); ## Next -- [Displaying data](/components/displaying-data/) — render the results. -- The full field set and dialog options are in the Components reference and Storybook. +- [Displaying data](displaying-data.md) — render the results. +- [CommandDialog reference](CommandDialog/index.md) — execution callbacks, busy behavior, dialog options, and context. +- [CommandForm reference](CommandForm/index.md) — form binding, field discovery, and available field components. diff --git a/Documentation/displaying-data.md b/Documentation/displaying-data.md index 4a823bdc..d6c02734 100644 --- a/Documentation/displaying-data.md +++ b/Documentation/displaying-data.md @@ -41,7 +41,7 @@ For the common "table on the left, details on the right" screen, `DataPage` give import { DataPage } from '@cratis/components/DataPage'; ``` -See the DataPage reference for menu items, the details panel, and selection wiring. +See the [DataPage reference](DataPage/index.md) for menu items, the details panel, and selection wiring. ## Tips @@ -50,5 +50,7 @@ See the DataPage reference for menu items, the details panel, and selection wiri ## Next -- [Building a form](/components/building-a-form/) — the write side. +- [Building a form](building-a-form.md) — the write side. +- [DataTables reference](DataTables/index.md) — choose the Arc query wrapper and configure columns. +- [DataPage reference](DataPage/index.md) — compose a query-backed list screen with actions and details. - [Build a full-stack feature](/build-a-full-app/) — the table and the form together against one Arc slice. diff --git a/Documentation/getting-started.mdx b/Documentation/getting-started.mdx index 3add7e8d..3da7c292 100644 --- a/Documentation/getting-started.mdx +++ b/Documentation/getting-started.mdx @@ -168,6 +168,7 @@ You installed one UI package, imported Components-owned styles, and mounted a lo ## Where to go next +- [Build the library screen tutorial](/components/tutorial/) — follow one screen from a live table through command actions and list-and-detail composition - [Building a form](/components/building-a-form/) - [Displaying data](/components/displaying-data/) - [Choosing a component](/components/choosing-a-component/) diff --git a/Documentation/index.mdx b/Documentation/index.mdx index 2677ef4c..43deb33e 100644 --- a/Documentation/index.mdx +++ b/Documentation/index.mdx @@ -32,6 +32,9 @@ import TopicHero from '@components/TopicHero.astro'; > Understand what Components adds to Arc-generated command and query contracts. + + Build a live list-and-detail screen with query-backed tables and command dialogs. + ( ## When to use a wizard vs. a plain dialog -Reach for a wizard when the input is genuinely staged or long enough that one screen would overwhelm. For three or four fields, a single [CommandDialog](/components/building-a-form/) is friendlier — don't add steps for their own sake. +Reach for a wizard when the input is genuinely staged or long enough that one screen would overwhelm. For three or four fields, a single [CommandDialog](CommandDialog/index.md) is friendlier — don't add steps for their own sake. ## Next -- [Building a form](/components/building-a-form/) — the single-step version and the field set. -- The full stepper options are in the Components reference and Storybook. +- [Building a form](building-a-form.md) — the single-step recipe and the field set. +- [StepperCommandDialog reference](StepperCommandDialog/index.md) — modal navigation, validation, callbacks, cancellation, and busy state. +- [CommandStepper reference](CommandStepper/index.md) — execute the same kind of multi-step command inline. From 58c72b5a22452fc9f66320a9eb22abb4ab4dc9d9 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:32:32 +0200 Subject: [PATCH 07/13] docs: correct CommandStepper and StepperCommandDialog relationship - State that both components execute the command - Remove onSubmit from CommandStepper (not in CommandForm props) - Document inherited onSuccess, onValidationFailure, onFailed only - Clarify no outer dialog means no dialogPt/dialogUnstyled - Note dialog owns cancel, busy state, and authorization routing --- Documentation/CommandStepper/index.md | 12 ++++++------ Documentation/StepperCommandDialog/index.md | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/CommandStepper/index.md b/Documentation/CommandStepper/index.md index acd42943..deb569ac 100644 --- a/Documentation/CommandStepper/index.md +++ b/Documentation/CommandStepper/index.md @@ -9,7 +9,7 @@ The `CommandStepper` component executes one Arc command through an inline, multi Use `CommandStepper` when the wizard belongs directly in a page region, panel, or route. It establishes a `CommandForm`, renders `StepperPanel` steps with built-in navigation, and executes the command from the final step. -`CommandStepper` and [`StepperCommandDialog`](../StepperCommandDialog/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. Both execute the command. Choose `StepperCommandDialog` when the wizard should be modal; it also owns dialog dismissal, authorization-result routing, and its execution busy state. +`CommandStepper` and [`StepperCommandDialog`](../StepperCommandDialog/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. Both execute the command. Choose `StepperCommandDialog` when the wizard should be modal; the dialog also owns cancel, busy state, and authorization routing. ## Basic Usage @@ -49,15 +49,15 @@ export const ProjectWizard = () => { - `showSubmit`: Show the built-in submit action on the last step (default: `true`) - `okLabel`: Submit button label. Falls back to the provider's `messages.stepper.submit`, then `'Submit'` - `isBusy`: Disables the navigation controls while something is running -- `onSuccess`: Callback invoked with the typed response after successful command execution -- `onValidationFailure`: Callback invoked with validation results when command execution returns validation errors -- `onFailed`: Callback invoked with the full command result for an unsuccessful, non-validation result -- Other applicable `CommandForm` props, including `initialValues`, `currentValues`, `validateOnInit`, and field-validation callbacks +- Other applicable `CommandForm` props, including `initialValues`, `currentValues`, `validateOnInit`, field-validation callbacks, and inherited command execution callbacks: + - `onSuccess`: Callback invoked with the typed response after successful command execution + - `onValidationFailure`: Callback invoked with validation results when command execution returns validation errors + - `onFailed`: Callback invoked with the full command result for an unsuccessful, non-validation result - `onBeforeExecute`: Transform command values before execution — it must **return** the values to run with, and it runs only on submit, so it can never satisfy required-field validation (seed those through `initialValues`) - `linear` (default `true`), `orientation` (`'horizontal'` default / `'vertical'`), `headerPosition` (`'top'` default / `'bottom'`), `start`, `end`, `onChangeStep`, and `pt`: the active `StepperCustomizationProps` surface. It maps onto stable `root`, `list`, `step`, `header`, `number`, `title`, `separator`, `panels`, and `panel` parts. - `ptOptions` and `unstyled`: retained temporarily for source compatibility; ignored because Cratis part attributes always merge and styling is CSS-owned. -There is no outer dialog, so `CommandStepper` has no `dialogPt` or `dialogUnstyled` props. Its `pt` prop targets the stepper directly. +Because `CommandStepper` has no outer dialog, it has no `dialogPt` or `dialogUnstyled` props; `pt` targets the stepper directly. Conditional steps written as `{condition && }` are counted correctly — only the panels that actually render are counted, so navigation and the per-step validation state stay in step with what is on screen. A `<>…` fragment wrapping several panels still counts as **one** step. diff --git a/Documentation/StepperCommandDialog/index.md b/Documentation/StepperCommandDialog/index.md index 406c8ac0..8a5a3d3d 100644 --- a/Documentation/StepperCommandDialog/index.md +++ b/Documentation/StepperCommandDialog/index.md @@ -3,7 +3,7 @@ title: StepperCommandDialog description: Execute Arc commands through a multi-step dialog with validation-aware navigation. --- -The `StepperCommandDialog` component executes one Arc command through a modal, multi-step form. It and [`CommandStepper`](../CommandStepper/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. +The `StepperCommandDialog` component executes one Arc command through a modal, multi-step form. It and [`CommandStepper`](../CommandStepper/index.md) are sibling public components that share the private `CommandStepperContent` rendering primitive. Both execute the command. Choose `CommandStepper` when the wizard belongs inline; the dialog additionally owns cancel, busy state, and authorization routing. ## Purpose From dde189bf134cc82c956909a84a110c16c7611fc0 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:32:35 +0200 Subject: [PATCH 08/13] docs: add ActionMenubar link from Toolbar index - Link ActionMenubar reference from Toolbar page-action-row note --- Documentation/Toolbar/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Toolbar/index.md b/Documentation/Toolbar/index.md index 0adcf836..f806a390 100644 --- a/Documentation/Toolbar/index.md +++ b/Documentation/Toolbar/index.md @@ -7,7 +7,7 @@ The `Toolbar` component provides a canvas-style icon toolbar with support for or Toolbar belongs to the [Advanced React capability profile](../ui-foundation.md#capability-profiles) — a specialized, React-only surface with no Pixi dependency, despite its canvas-adjacent purpose. -**`Toolbar` is not a default page action row.** It is built for a canvas/tool-palette interaction — active tools, groups, slots, folders, and fan-out panels — not for an ordinary page's list of commands. `DataPage`'s built-in action row renders `ActionMenubar` (from `@cratis/components/Common`), not `Toolbar`. Reach for [`ActionMenubar`](../Common/action-menubar.md), or a product-owned action row, for flat page-level actions; reach for `Toolbar` only when the surface is genuinely a spatial tool palette. See [Choosing a component: Actions and tool palettes](../choosing-a-component.md#actions-and-tool-palettes). +**`Toolbar` is not a default page action row.** It is built for a canvas/tool-palette interaction — active tools, groups, slots, folders, and fan-out panels — not for an ordinary page's list of commands. `DataPage`'s built-in action row renders [`ActionMenubar`](../Common/action-menubar.md) (from `@cratis/components/Common`), not `Toolbar`. Reach for `ActionMenubar`, or a product-owned action row, for flat page-level actions; reach for `Toolbar` only when the surface is genuinely a spatial tool palette. See [Choosing a component: Actions and tool palettes](../choosing-a-component.md#actions-and-tool-palettes). Pass React icon nodes or product-owned SVGs for a dependency-free toolbar. Consumer-owned icon-font class strings remain accepted, but Components does not install an icon font or infer provider base classes; the product must load the matching stylesheet and pass the complete class string. From 5887d8dbb271843ba5de3d44b4a4c2bfc41e3b9f Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:32:40 +0200 Subject: [PATCH 09/13] docs: add troubleshooting reciprocal links - Add troubleshooting link from renderers index - Add troubleshooting link from Styling index - Promote troubleshooting in getting-started next steps --- Documentation/Styling/index.md | 2 +- Documentation/getting-started.mdx | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/Styling/index.md b/Documentation/Styling/index.md index 86c1bcfe..7ace2cd8 100644 --- a/Documentation/Styling/index.md +++ b/Documentation/Styling/index.md @@ -44,4 +44,4 @@ React Aria is internal. Never style React Aria class names or undocumented DOM s ## See also -- [Troubleshoot product CSS precedence](../troubleshooting.md#product-css-does-not-win-over-components-styles) +- [Troubleshooting](../troubleshooting.md) — installation, styling, rendering, and form symptoms, including product CSS precedence diff --git a/Documentation/getting-started.mdx b/Documentation/getting-started.mdx index 3da7c292..33f42c3d 100644 --- a/Documentation/getting-started.mdx +++ b/Documentation/getting-started.mdx @@ -166,12 +166,14 @@ Do not target React Aria class names or internal DOM structure. See [Styling](/c You installed one UI package, imported Components-owned styles, and mounted a locale/toast provider. Components owns the public React contract, Arc supplies command and query behavior, and React Aria supplies selected low-level interaction primitives internally. +Next, [build a live library screen](/components/tutorial/) — the tutorial guides you step by step through a list-and-detail page with query-backed tables and command dialogs. + ## Where to go next - [Build the library screen tutorial](/components/tutorial/) — follow one screen from a live table through command actions and list-and-detail composition - [Building a form](/components/building-a-form/) - [Displaying data](/components/displaying-data/) - [Choosing a component](/components/choosing-a-component/) +- [Troubleshooting](/components/troubleshooting/) — installation, styling, rendering, and form symptoms - [Migrate from Components 3](/components/migration/) - [Understand the UI foundation](/components/ui-foundation/) — including the capability profiles and capability matrix behind Foundation, Advanced React, and Spatial components -- [Troubleshoot a Components symptom](/components/troubleshooting/) From 2059edcb6e9c0626c5ef39c5940576ff94829897 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:32:46 +0200 Subject: [PATCH 10/13] docs: improve recipe exits and add tutorial visibility - Replace vague reference endings with concrete component links - Remove 'reference' label and trailing periods from Next sections - Add Tutorial as first Start-here card on root index - Add tutorial next-step link in getting-started Recap --- Documentation/building-a-form.md | 6 +++--- Documentation/displaying-data.md | 9 ++++----- Documentation/index.mdx | 6 +++--- Documentation/list-screen-with-actions.md | 7 +++---- Documentation/multi-step-form.md | 6 +++--- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Documentation/building-a-form.md b/Documentation/building-a-form.md index d2f90a8e..47dd1a1c 100644 --- a/Documentation/building-a-form.md +++ b/Documentation/building-a-form.md @@ -69,6 +69,6 @@ const [AddAuthorDialog, showAddAuthor] = useDialog(AddAuthor); ## Next -- [Displaying data](displaying-data.md) — render the results. -- [CommandDialog reference](CommandDialog/index.md) — execution callbacks, busy behavior, dialog options, and context. -- [CommandForm reference](CommandForm/index.md) — form binding, field discovery, and available field components. +- [Displaying data](displaying-data.md) — render the results +- [CommandDialog](CommandDialog/index.md) — execution callbacks, busy behavior, dialog options, and context +- [CommandForm](CommandForm/index.md) — form binding, field discovery, and available field components diff --git a/Documentation/displaying-data.md b/Documentation/displaying-data.md index d6c02734..e3ae0d2d 100644 --- a/Documentation/displaying-data.md +++ b/Documentation/displaying-data.md @@ -41,7 +41,7 @@ For the common "table on the left, details on the right" screen, `DataPage` give import { DataPage } from '@cratis/components/DataPage'; ``` -See the [DataPage reference](DataPage/index.md) for menu items, the details panel, and selection wiring. +See [DataPage](DataPage/index.md) for menu items, the details panel, and selection wiring. ## Tips @@ -50,7 +50,6 @@ See the [DataPage reference](DataPage/index.md) for menu items, the details pane ## Next -- [Building a form](building-a-form.md) — the write side. -- [DataTables reference](DataTables/index.md) — choose the Arc query wrapper and configure columns. -- [DataPage reference](DataPage/index.md) — compose a query-backed list screen with actions and details. -- [Build a full-stack feature](/build-a-full-app/) — the table and the form together against one Arc slice. +- [Building a form](building-a-form.md) — the write side +- [DataTables](DataTables/index.md) — choose the Arc query wrapper and configure columns +- [DataPage](DataPage/index.md) — compose a query-backed list screen with actions and details diff --git a/Documentation/index.mdx b/Documentation/index.mdx index 43deb33e..784b513b 100644 --- a/Documentation/index.mdx +++ b/Documentation/index.mdx @@ -21,6 +21,9 @@ import TopicHero from '@components/TopicHero.astro'; ## Start here + + Build a live list-and-detail screen with query-backed tables and command dialogs. + Install the package, mount the provider, and render your first proxy-driven screen. @@ -32,9 +35,6 @@ import TopicHero from '@components/TopicHero.astro'; > Understand what Components adds to Arc-generated command and query contracts. - - Build a live list-and-detail screen with query-backed tables and command dialogs. - Date: Thu, 10 Sep 2026 12:32:49 +0200 Subject: [PATCH 11/13] docs: refine choosing-a-component wording - Change 'non-modal command wizard' to 'inline command wizard' for CommandStepper --- Documentation/choosing-a-component.md | 46 +++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/Documentation/choosing-a-component.md b/Documentation/choosing-a-component.md index f7336e69..3f32c9bb 100644 --- a/Documentation/choosing-a-component.md +++ b/Documentation/choosing-a-component.md @@ -1,6 +1,6 @@ --- title: Choosing a component -description: A decision guide for the overlapping Components — CommandDialog vs StepperCommandDialog, DataPage vs DataTables, and Dialog vs CommandDialog. +description: Choose among Components command, data, action, filtering, feedback, structured-data, history, and conversation surfaces. --- Several Components solve similar-looking problems, and it's not always obvious which one to reach for. @@ -13,11 +13,13 @@ The question is whether confirming the form **runs a command**, and whether it's | You want to… | Use | Why | | -------------------------------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -| Collect a few fields and run one command | [`CommandDialog`](./CommandDialog/index.md) | Instantiates, validates, and executes the command; handles the footer and button states. The default. | -| Run a command, but gather input across **named steps** | [`StepperCommandDialog`](./StepperCommandDialog/index.md) | A wizard over a single command — validate per step, navigate back and forth, execute at the end. | -| Embed command fields **in a page**, not a dialog | [`CommandForm`](./CommandForm/index.md) | The same typed fields `CommandDialog` uses, without the dialog chrome. | -| Collect data and return it **without** running a command | [`Dialog`](./Dialogs/index.md) | A confirmation or data-entry dialog that hands values back to the caller. No command involved. | -| Edit ordinary local React state | [`Common` basic controls](./Common/basic-controls.md) | Native text and choice controls expose semantic values without binding an Arc command. | +| Collect a few fields and run one command | [`CommandDialog`](./CommandDialog/index.md) | Instantiates, validates, and executes the command; handles the footer and button states. The default. | +| Run a command through named steps in a modal | [`StepperCommandDialog`](./StepperCommandDialog/index.md) | A wizard over a single command — validate per step, navigate back and forth, execute at the end. | +| Run a command through named steps inline on the page | [`CommandStepper`](./CommandStepper/index.md) | The inline command wizard for a panel, route, or page region; it executes on the final step. | +| Embed command fields **in a page**, not a dialog | [`CommandForm`](./CommandForm/index.md) | The same typed fields `CommandDialog` uses, without the dialog chrome. | +| Collect data and return it **without** running a command | [`Dialog`](./Dialogs/dialog.md) | A confirmation or data-entry dialog that hands values back to the caller. No command involved. | +| Edit ordinary local React state | [`Common` basic controls](./Common/basic-controls.md) | Native text and choice controls expose semantic values without binding an Arc command. | +| Select one or more values in ordinary local React state | [`Dropdown`](./Dropdown/index.md) | Binds a value or array to local options without binding an Arc command. | Rule of thumb: **if confirming the dialog executes a generated command, it's a `CommandDialog`** (or its stepper variant). If it just gathers values and returns them, it's a `Dialog`. Never reach for @@ -40,10 +42,40 @@ If you're building a list-screen-with-actions from scratch, start with the [list screen recipe](./list-screen-with-actions.md), which composes `DataPage` with `CommandDialog` actions. +## Selection, status, and feedback + +| You want to… | Use | Why | +| ------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------- | +| Select one or more values from local options | [`Dropdown`](./Dropdown/index.md) | Supports single, filtered, and multiple selection through a controlled value. | +| Show status, counts, people, progress, or loading | [`Display`](./Display/index.md) | Provides tags, badges, chips, avatars, messages, progress indicators, and skeletons. | +| Send an app-wide transient notification | [`Notifications`](./Notifications/index.md) | Provides one shared toast queue, an imperative API, and an optional app-wide toaster. | + +### Filtering + +Choose the filtering surface by where its state belongs: + +| You want to… | Use | Why | +| ----------------------------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | +| Filter individual table columns | [`Column` filters](./DataTables/index.md#columnfiltermenu) | A column can use the built-in `ColumnFilterMenu`; the menu keeps draft changes until Apply. | +| Search configured fields in a `DataPage` | [`DataPage.globalFilterFields`](./DataPage/index.md#filtering-scope) | Adds global search over the rows in the currently loaded query page. | +| Present option, numeric-range, or custom filter groups | [`FilterPanel`](./Filter/index.md) | Supplies a standalone faceted panel while the host owns how its filter state applies to the data view. | + +Table column and `DataPage` global filters operate on the currently loaded query page. Filtering the complete result set belongs in query arguments and server logic before paging; see [`DataPage` filtering scope](./DataPage/index.md#filtering-scope). + ## Actions and tool palettes Use [`ActionMenubar`](./Common/action-menubar.md) or an ordinary product action row for flat page commands. `DataPage`'s built-in toolbar already renders `ActionMenubar`, not `Toolbar` — that is the default action row for a page, not a canvas tool palette. Use [`Toolbar`](./Toolbar/index.md) only for a genuine canvas/tool-palette interaction with active tools, groups, slots, folders, and fan-out panels. It is not a one-for-one replacement for a generic Prime Toolbar, and it is not a page-level action row wearing a different name. +## Structured data, history, and conversation + +| You want to… | Use | Why | +| ------------------------------------------------------ | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| Explore or edit an object through a JSON Schema | [`ObjectContentEditor`](./ObjectContentEditor/index.md) | Renders schema-aware properties and navigation through nested objects and arrays. | +| Create or edit a supported JSON Schema | [`SchemaEditor`](./SchemaEditor/index.md) | Edits properties, supported types, and formats in a validated table interface. | +| Add controlled breadcrumbs to hierarchical data | [`ObjectNavigationalBar`](./ObjectNavigationalBar/index.md) | Renders a host-owned navigation path with breadcrumb and back actions. | +| Explore supplied versions, events, and state changes | [`TimeMachine`](./TimeMachine/index.md) | Provides an interactive timeline while the host supplies the version data. | +| Build topic-based conversations from host-owned data | [`Chat`](./Chat/index.md) | Provides topic, conversation, mention, emoji, and message-action surfaces with callback outputs. | + ## Spatial workspaces Use [`Canvas`](./Canvas/index.md) for a pan/zoom workspace containing positioned DOM or Pixi items, optional minimap/controls, notes, regions, or collaborative chat shapes, or [`PivotViewer`](./PivotViewer/index.md) for a faceted, zoomable card grid over a large dataset. Both belong to the [Spatial capability profile](./ui-foundation.md#capability-profiles) and install the optional `pixi.js` peer — see [UI foundation: Optional Pixi, clean no-Pixi core](./ui-foundation.md#optional-pixi-clean-no-pixi-core). Spatial ships at the same version and quality bar as every other component; the profile label describes what it is for and what it costs to adopt, not a lower support tier. @@ -56,6 +88,6 @@ A typical CRUD screen combines these: a `DataPage` lists the rows, a toolbar but `CommandDialog` to add one, and selecting a row opens another `CommandDialog` to edit it. That whole screen is the [list screen with actions](./list-screen-with-actions.md) recipe. -Components does not attempt to replace every toolkit widget. Tabs, sidebars, timelines, knobs, select-button groups, general popovers, and specialized locale-aware inputs may remain product-owned or in a separately configured UI toolkit until an intentional Components API exists. +Components does not ship every toolkit widget. Tabs, general-purpose sidebars, knobs, select-button groups, general popovers, grouped or expandable tables, controlled lazy/server table sorting, and specialized locale-aware inputs remain product-owned or in a separately configured UI toolkit. See [Coming from PrimeReact](./coming-from-primereact.md) for the current replacement boundaries. Still deciding how to style any of this? See [Styling](./Styling/index.md). From 671f932ae035251947febc0e7bf5975e74a4e6e7 Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:32:54 +0200 Subject: [PATCH 12/13] docs: refocus Storybook browse page - Reduce Storybook body to brief browse orientation - Remove hardcoded counts and issue link - Correct Plain as conformance fixture, not adapter workspace - Add Storybook release-gate bullet to ui-foundation without counts --- Documentation/storybook.mdx | 8 +++----- Documentation/ui-foundation.md | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Documentation/storybook.mdx b/Documentation/storybook.mdx index cc047068..f2bdb255 100644 --- a/Documentation/storybook.mdx +++ b/Documentation/storybook.mdx @@ -6,12 +6,10 @@ tableOfContents: false import StorybookEmbed from '@components/StorybookEmbed.astro'; -Use the **Renderer** manager control to run the same stable story id with the zero-config Cratis built-in renderer, Material UI, PrimeReact 11, or PrimeReact 10. Changing renderer replaces the composed preview iframe. The manager preserves the current story id when the target preview contains it, but component-local state, unsaved control changes, open overlays, and in-progress interactions are reset by that remount. +Use the **Renderer** control to run a story with the built-in renderer, Material UI, PrimeReact 11, or PrimeReact 10. Changing renderer remounts the preview iframe. -Use the Appearance toolbar to compare the maintained baseline in light and dark modes with a representative product-owned token mapping. Every renderer preview owns its provider and theme boundary while preserving strict profile validation and Core fallback for slots outside the selected adapter's profile. Stories load the same prefixed, layered, no-Preflight Cratis CSS contract as the published package. +Use the **Appearance** toolbar to switch between light and dark baseline modes. -PrimeReact 10 and 11 are built as separate preview projects because their incompatible `primereact` peer majors must never enter one dependency graph. Each preview verifies the exact upstream version resolved from the checked-in adapter matrix. The PrimeReact 11 preview is a bounded test fixture: it uses PrimeReact's public contexts and the adapter's non-secret boolean setup attestation without mounting the real license manager. Components and this Storybook do not receive, read, store, log, serialize, bundle, or proxy a license key. - -Every story module also generates an autodocs page from the public component types and TSDoc. CI validates the metadata-discovered adapter inventory, type-checks the configuration, asserts peer-major isolation, builds and compares every preview index, then runs every discovered stable story in Playwright Chromium under baseline light and dark modes for the built-in renderer and every metadata-discovered public adapter. The current V4 inventory is four previews × 277 stories × two appearances: **2,216 story/appearance/axe cases**, with zero story or renderer exclusions. Generated preview indexes identify the exact stories; [#217](https://github.com/Cratis/Components/issues/217) tracks replacing release-snapshot count constants with generated reviewable inventories. Private adapters such as Plain are excluded from composition. Each `play()` interaction runs, and Accessibility-addon axe violations are errors. This is a browser component-test gate, not a claim of universal browser or assistive-technology conformance; keyboard, focus, busy, empty, invalid, disabled, open-overlay, and responsive states still require deliberate story coverage and release review. +Every story generates an autodocs page from public component types and TSDoc. diff --git a/Documentation/ui-foundation.md b/Documentation/ui-foundation.md index 285d573f..5076f635 100644 --- a/Documentation/ui-foundation.md +++ b/Documentation/ui-foundation.md @@ -217,7 +217,8 @@ The Components 4 major candidate uses these repository release checks: - The setup root and every non-spatial subpath load without Pixi, while Canvas and PivotViewer fail specifically on the missing optional peer until it is installed. - Declared Arc peer versions are exercised against the packed artifact. - Representative custom-theme and pass-through consumers compile after following the guide. -- Specs, Storybook, package exports, SSR, keyboard/focus behavior, responsive layouts, dark mode, forced colors, and reduced motion pass. +- Specs, package exports, SSR, keyboard/focus behavior, responsive layouts, dark mode, forced colors, and reduced motion pass. +- Storybook builds and runs under baseline light and dark modes for the built-in renderer and every metadata-discovered public adapter; private ui-adapter workspaces are excluded, and the Plain DOM renderer is a conformance fixture, not an adapter workspace. - The migration guide works without repository-specific knowledge. - Every packed public JavaScript subpath passes strict TypeScript 6 validation or matches a bounded machine-readable upstream exception with exact installed versions and an unmet removal condition. Components-owned cascades additionally require their matching upstream TS2834/TS2835 root cause in the same compiler run. From 7ab5733aac9862e4b83a7c80da57ef590ff67d2d Mon Sep 17 00:00:00 2001 From: woksin Date: Thu, 10 Sep 2026 12:36:13 +0200 Subject: [PATCH 13/13] docs: add choosing-a-component reciprocal link from Filter - Add filtering decision-guide link from FilterPanel description - Required by reviewed deep content plan task 5 --- Documentation/Filter/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Filter/index.md b/Documentation/Filter/index.md index 6186b3bd..2dfea4e3 100644 --- a/Documentation/Filter/index.md +++ b/Documentation/Filter/index.md @@ -3,7 +3,7 @@ title: FilterPanel description: Build reusable filter panels with option, range, and custom editors. --- -The `FilterPanel` component provides a standalone, reusable filter UI that can be placed next to any data view. It renders as a positioned dropdown anchored below a trigger button and supports single-select, multi-select, numeric range (with histogram), and fully custom filter editors declared as children. +The `FilterPanel` component provides a standalone, reusable filter UI that can be placed next to any data view. It renders as a positioned dropdown anchored below a trigger button and supports single-select, multi-select, numeric range (with histogram), and fully custom filter editors declared as children. If you are choosing between faceted, column, and global filtering, start with [Choosing a component](../choosing-a-component.md#filtering). ## Key Features