themelia-ui 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/themelia-ui/SKILL.md +38 -9
- package/.agents/skills/themelia-ui/manifest.json +23 -0
- package/.agents/skills/themelia-ui/references/api-compatibility.md +3 -2
- package/.agents/skills/themelia-ui/references/blocks.md +123 -0
- package/.agents/skills/themelia-ui/references/composition-ladder.md +8 -8
- package/.agents/skills/themelia-ui/references/composition.md +98 -1
- package/.agents/skills/themelia-ui/references/forms.md +23 -3
- package/.agents/skills/themelia-ui/references/framework-wiring.md +34 -6
- package/.agents/skills/themelia-ui/references/i18n.md +4 -2
- package/.agents/skills/themelia-ui/references/imports.md +1 -1
- package/.agents/skills/themelia-ui/references/installation.md +5 -4
- package/.agents/skills/themelia-ui/references/migration.md +22 -2
- package/.agents/skills/themelia-ui/references/provider-and-scoping.md +27 -9
- package/.agents/skills/themelia-ui/references/reference-workflows.md +43 -0
- package/.agents/skills/themelia-ui/references/structure-and-spacing.md +147 -0
- package/.agents/skills/themelia-ui/references/theming.md +6 -2
- package/.agents/skills/themelia-ui/references/troubleshooting.md +28 -5
- package/.agents/skills/themelia-ui/references/verification.md +58 -2
- package/CHANGELOG.md +25 -0
- package/README.md +3 -0
- package/dist/{alert-dialog-Bmo1YrTm.js → alert-dialog-Cg2HhuBe.js} +1 -1
- package/dist/base/alert-dialog.js +1 -1
- package/dist/base/cards.js +1 -1
- package/dist/base/choice-inputs.js +1 -1
- package/dist/base/combobox.js +1 -1
- package/dist/base/command.js +1 -1
- package/dist/base/date-pickers.js +1 -1
- package/dist/base/dialog.js +1 -1
- package/dist/base/display.js +1 -1
- package/dist/base/forms-numeric.js +1 -1
- package/dist/base/forms.js +1 -1
- package/dist/base/item.js +1 -1
- package/dist/base/navigation.js +1 -1
- package/dist/base/otp-input.js +1 -1
- package/dist/base/overlay.js +1 -1
- package/dist/base/popover-menu.js +1 -1
- package/dist/base/repeaters.js +1 -1
- package/dist/base/sheet.js +1 -1
- package/dist/base/sidebar.js +1 -1
- package/dist/base/skeleton.js +1 -1
- package/dist/base/structure.js +1 -1
- package/dist/base/timeline.js +1 -1
- package/dist/base/upload.js +1 -1
- package/dist/base/value-inputs.js +1 -1
- package/dist/blocks/admin/access.js +2 -2
- package/dist/blocks/admin/commerce.js +9 -9
- package/dist/blocks/analytics.js +3 -3
- package/dist/blocks/onboarding.js +1 -1
- package/dist/blocks/timelines.js +1 -1
- package/dist/{cards-DdiICdMM.js → cards-Ddhz43Bz.js} +2 -2
- package/dist/{choice-inputs-CCw-0gD6.js → choice-inputs-NwRxvmZN.js} +2 -2
- package/dist/combobox-519ubijc.js +292 -0
- package/dist/{command-CnB_IZSo.js → command-JjApYFds.js} +2 -2
- package/dist/{comments-C6Y_ddMt.js → comments-CCQ2QRaU.js} +4 -4
- package/dist/components/base/display/icon-badge.d.ts +2 -2
- package/dist/components/base/forms/form-field.d.ts +2 -2
- package/dist/components/base/structure/bleed.d.ts +1 -0
- package/dist/components/base/structure/grid.d.ts +8 -2
- package/dist/components/base/structure/split.d.ts +1 -0
- package/dist/components/features/combobox/fetching-combobox.d.ts +2 -1
- package/dist/components/features/combobox/resource-combobox.d.ts +3 -0
- package/dist/components/features/combobox/use-suggestions.d.ts +7 -0
- package/dist/css/structure.css +1 -1
- package/dist/{date-pickers-C2HgjpFU.js → date-pickers-BwCwKIVM.js} +1 -1
- package/dist/{dialog-0nRFg5Zs.js → dialog-CAnwRNrm.js} +1 -1
- package/dist/{display-BGN834xV.js → display-a7AoX_u7.js} +1 -1
- package/dist/features/actions.js +1 -1
- package/dist/features/activities.js +3 -3
- package/dist/features/ai-chat.js +2 -2
- package/dist/features/combobox.js +285 -273
- package/dist/features/comments.js +1 -1
- package/dist/features/data-view.js +5 -5
- package/dist/features/event-calendar.js +3 -3
- package/dist/features/filters.js +1 -1
- package/dist/features/global-search.js +4 -4
- package/dist/features/map.js +2 -2
- package/dist/features/media-library.js +8 -8
- package/dist/features/mentions.js +1 -1
- package/dist/features/overlays.js +1 -1
- package/dist/features/products.js +9 -9
- package/dist/features/resource-assignment.js +3 -3
- package/dist/features/resource.js +3 -3
- package/dist/features/schema-form.js +6 -6
- package/dist/features/sync.js +2 -2
- package/dist/features/table.js +1 -1
- package/dist/features/theme-tweaker.js +10 -10
- package/dist/{filters-geLuSlFL.js → filters-BhsTkWpZ.js} +9 -9
- package/dist/{forms-NxbJK4Mh.js → forms-C0WeNPFF.js} +1 -1
- package/dist/{forms-numeric-C6NMdj6G.js → forms-numeric-IwQ1ltNf.js} +1 -1
- package/dist/hooks/use-native-dialog.d.ts +1 -1
- package/dist/{item-CuUJyETl.js → item-M2pmpWXh.js} +1 -1
- package/dist/layout/app-shell.js +1 -1
- package/dist/layout/auth.js +1 -1
- package/dist/layout/header.js +3 -3
- package/dist/layout/navigation.js +1 -1
- package/dist/layout/page.js +2 -2
- package/dist/layout/settings.js +2 -2
- package/dist/layout/sidebar.js +10 -6
- package/dist/layout/workspace.js +3 -3
- package/dist/lib/ui-provider/ui-scope.d.ts +1 -1
- package/dist/{mentions-oeYNv_j1.js → mentions-BOxbigwp.js} +2 -2
- package/dist/{navigation-BTX5Ti0Z.js → navigation-Bgu7Vc0M.js} +2 -2
- package/dist/{navigation-WYKjDhZq.js → navigation-DiYACqpE.js} +2 -2
- package/dist/{overlay-C8RAgi2_.js → overlay-BuQOl8aP.js} +5 -5
- package/dist/{overlays-9BxwFTou.js → overlays-1sULyytH.js} +5 -5
- package/dist/{popover-menu-DcLeiw9r.js → popover-menu-QXgQeWeG.js} +1 -1
- package/dist/{repeaters-DfptvbGA.js → repeaters-CeH20dvr.js} +4 -4
- package/dist/{sheet-D-DVZH_b.js → sheet-CJ1-OAla.js} +1 -1
- package/dist/{sidebar-DXQOy_Cb.js → sidebar-D8uGqxio.js} +4 -4
- package/dist/{skeleton-CubvHel9.js → skeleton-BTKNKTdj.js} +1 -1
- package/dist/{structure-B9Y5NkP_.js → structure-CynEZ-OY.js} +1 -2
- package/dist/style.css +1 -1
- package/dist/styles/TOKENS.md +4 -3
- package/dist/{table-DT_20ity.js → table-B7dtIFUx.js} +4 -4
- package/dist/{timeline-BRZbSdhf.js → timeline-BR_jNgvz.js} +1 -1
- package/dist/{timelines-DczZKW5p.js → timelines-DXG1BfIN.js} +1 -1
- package/dist/{upload-C_6mlbfl.js → upload-CYuoJykZ.js} +1 -1
- package/dist/{value-inputs-CnO6RZeT.js → value-inputs-ng8aVJJZ.js} +4 -4
- package/docs/README.md +11 -1
- package/docs/build/browser-composition-fixture.ts +28 -0
- package/docs/build/recipes.md +398 -1
- package/docs/generated/component-index.json +1993 -862
- package/docs/generated/components/base--display.md +2 -2
- package/docs/generated/components/base--forms.md +72 -1
- package/docs/generated/components/base--structure.md +56 -5
- package/docs/generated/components/base--typography.md +38 -0
- package/docs/generated/components/blocks--admin--access.md +10 -0
- package/docs/generated/components/blocks--analytics.md +44 -0
- package/docs/generated/components/features--combobox.md +67 -0
- package/docs/generated/components/features--data-view.md +59 -3
- package/docs/generated/components/features--filters.md +10 -0
- package/docs/generated/components/features--media-library.md +68 -0
- package/docs/generated/components/features--overlays.md +54 -0
- package/docs/generated/components/features--rich-text-editor.md +38 -0
- package/docs/generated/components/layout--app-shell.md +31 -0
- package/docs/generated/components/layout--containers.md +40 -0
- package/docs/generated/components/layout--page.md +30 -1
- package/docs/generated/components/layout--sidebar.md +41 -0
- package/docs/generated/components/ui-provider.md +1 -1
- package/docs/generated/composition-ladder.md +8 -8
- package/docs/generated/consumer-contract.json +5736 -0
- package/docs/generated/imports.md +1 -1
- package/docs/generated/recipes.json +171 -1
- package/docs/generated/workflows/communications-overview/analytics/communications-reference.tsx +19 -0
- package/docs/generated/workflows/index.json +691 -0
- package/docs/generated/workflows/media-picking/media-library/media-picking-reference.tsx +63 -0
- package/docs/generated/workflows/media-picking/media-library/reference-data.ts +3 -0
- package/docs/generated/workflows/multi-section-form/form-workflow/multi-section-reference.tsx +46 -0
- package/docs/generated/workflows/nested-action-flow/action-overlays/nested-action-reference.tsx +39 -0
- package/docs/generated/workflows/record-detail/page-layout/record-detail-reference.tsx +24 -0
- package/docs/generated/workflows/resource-index/data-view/resource-index-reference.tsx +51 -0
- package/docs/generated/workflows/scoped-resource-selection/combobox/scoped-resource-reference.tsx +50 -0
- package/docs/generated/workflows/website-content-editor/media-library/reference-data.ts +3 -0
- package/docs/generated/workflows/website-content-editor/rich-text-editor/website-content-reference.tsx +33 -0
- package/docs/generated/workflows/workspace-navigation/app-shell/workspace-navigation-reference.tsx +26 -0
- package/docs/learn/api-compatibility.md +3 -2
- package/docs/learn/blocks.md +123 -0
- package/docs/learn/composition.md +98 -1
- package/docs/learn/forms.md +23 -3
- package/docs/learn/framework-wiring.md +34 -6
- package/docs/learn/i18n.md +4 -2
- package/docs/learn/installation.md +5 -4
- package/docs/learn/migration.md +22 -2
- package/docs/learn/provider-and-scoping.md +27 -9
- package/docs/learn/reference-workflows.md +43 -0
- package/docs/learn/structure-and-spacing.md +147 -0
- package/docs/learn/theming.md +6 -2
- package/docs/learn/troubleshooting.md +28 -5
- package/docs/learn/verification.md +58 -2
- package/package.json +4 -1
- package/scripts/consumer/codemod.mjs +3 -24
- package/scripts/consumer/contract-reader.mjs +42 -0
- package/scripts/consumer/css-scan.mjs +51 -0
- package/scripts/consumer/diagnose.mjs +136 -0
- package/scripts/consumer/find-component.mjs +28 -13
- package/scripts/consumer/install-skill.mjs +93 -11
- package/src/styles/TOKENS.md +4 -3
- package/dist/combobox-Byu8N-Oe.js +0 -274
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: themelia-ui
|
|
3
|
-
description: Use when a React consumer is selecting, importing, composing, theming, localizing, integrating or upgrading themelia-ui components — forms, routing, data, SSR, CSP, consumer CSS overrides, Tailwind, and migrating between versions with the packaged codemod. Do not use for maintaining package internals.
|
|
3
|
+
description: Use when a React consumer is selecting, importing, composing, theming, localizing, integrating or upgrading themelia-ui components — structural layouts, blocks, spacing, responsive grids, forms, routing, data, SSR, CSP, consumer CSS overrides, Tailwind, and migrating between versions with the packaged codemod. Do not use for maintaining package internals.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!-- GENERATED by themelia-ui/scripts/gen-agent-skill.mjs -->
|
|
@@ -13,8 +13,14 @@ uses CSS Modules over Base UI, publishes exact module subpaths, and has no `ui/`
|
|
|
13
13
|
|
|
14
14
|
## Workflow
|
|
15
15
|
|
|
16
|
-
1.
|
|
17
|
-
|
|
16
|
+
1. Read the application's instructions and policy skills; they own domain decisions. Identify
|
|
17
|
+
the installed package version and check this copy with the packaged installer `--check`.
|
|
18
|
+
Review drift before reinstalling; keep application policy in a separate skill.
|
|
19
|
+
2. Map owners: route, surface, section, fact, metric, editable group, field, transport and command.
|
|
20
|
+
Read `references/composition.md` for their insets, names and parent responsibilities. Search
|
|
21
|
+
the catalogue by job and context; read `chooseWhen`, `avoidWhen`, alternatives and peers.
|
|
22
|
+
For page geometry, gaps and responsive widths, read `references/structure-and-spacing.md`;
|
|
23
|
+
for analytics, onboarding, timelines and admin presentation, read `references/blocks.md`.
|
|
18
24
|
3. Open that module's generated API reference before writing JSX. It contains every public
|
|
19
25
|
declaration, inherited prop contract, dependency, and attributed live-preview recipe.
|
|
20
26
|
4. Prefer the highest ready module that owns the behavior, then customize it at the lowest
|
|
@@ -24,6 +30,16 @@ uses CSS Modules over Base UI, publishes exact module subpaths, and has no `ui/`
|
|
|
24
30
|
6. Keep application policy in the application, then verify the composed result in its real
|
|
25
31
|
route, theme, density, data states, keyboard flow, and production bundle.
|
|
26
32
|
|
|
33
|
+
For a shared component/style change, trace its callers first. Select representatives of each
|
|
34
|
+
affected surface and check the initiating control, parent width, inset and portal owners.
|
|
35
|
+
Use `references/reference-workflows.md` when several modules meet; copy the complete source
|
|
36
|
+
directory including helpers. Run the packaged read-only diagnostics against explicit source
|
|
37
|
+
paths and treat advisory findings as review prompts. Read only the relevant guide.
|
|
38
|
+
If the catalogue or declaration is absent, name the missing path and use the installed package's
|
|
39
|
+
export map/types or request the missing artifact. Do not infer an API from another version.
|
|
40
|
+
If browser access is unavailable, finish independent type/build work and report browser
|
|
41
|
+
behavior and appearance as unverified.
|
|
42
|
+
|
|
27
43
|
**Upgrading between versions** comes before any of that. Read the version's section in
|
|
28
44
|
`references/migration.md`, then run the packaged codemod — dry first — and handle what it
|
|
29
45
|
reports (removed tokens, overrides that now set a shared name, look-alike Tailwind utilities)
|
|
@@ -33,6 +49,7 @@ by hand. Re-run the skill installer afterwards so this skill matches the install
|
|
|
33
49
|
node node_modules/themelia-ui/scripts/consumer/codemod.mjs --dry-run src/
|
|
34
50
|
node node_modules/themelia-ui/scripts/consumer/codemod.mjs src/
|
|
35
51
|
node node_modules/themelia-ui/scripts/consumer/install-skill.mjs --project=.
|
|
52
|
+
node node_modules/themelia-ui/scripts/consumer/install-skill.mjs --project=. --check --json
|
|
36
53
|
```
|
|
37
54
|
|
|
38
55
|
## Installed-package authorities
|
|
@@ -65,7 +82,7 @@ node node_modules/themelia-ui/scripts/consumer/find-component.mjs --peer=@tansta
|
|
|
65
82
|
node node_modules/themelia-ui/scripts/consumer/find-component.mjs --help
|
|
66
83
|
```
|
|
67
84
|
|
|
68
|
-
It indexes 97 modules,
|
|
85
|
+
It indexes 97 modules, 404 attributed live recipes, and
|
|
69
86
|
119 live preview routes by public symbol, module id, recipe title, preview route,
|
|
70
87
|
component capabilities, descriptions, and positive selection guidance. Negative `avoidWhen` guidance is never treated as a
|
|
71
88
|
recommendation. `--json` includes the exact
|
|
@@ -132,7 +149,10 @@ analytics, persistence, translation orchestration, and domain decisions. Pass th
|
|
|
132
149
|
documented props, callbacks, accessors, slots, render props, hooks, and provider seams.
|
|
133
150
|
|
|
134
151
|
Read `references/composition.md` for page examples and
|
|
135
|
-
`references/composition-ladder.md` for
|
|
152
|
+
`references/composition-ladder.md` for available extension seams. Structural helpers arrange
|
|
153
|
+
siblings; subject blocks own a recognizable presentation. Stack has gap and alignment props,
|
|
154
|
+
no padding prop. Page already supplies a Container, and DataView already supplies its frame.
|
|
155
|
+
Check child insets before adding parent gaps; flat FormSections retain their inset.
|
|
136
156
|
|
|
137
157
|
## Imports and CSS delivery
|
|
138
158
|
|
|
@@ -224,10 +244,11 @@ export function ScopedPreview() {
|
|
|
224
244
|
|
|
225
245
|
Theme through the public contract in `node_modules/themelia-ui/src/styles/TOKENS.md`: about
|
|
226
246
|
eighty variables, declared once at `:root`, each colour a `light-dark(light, dark)` pair. Set
|
|
227
|
-
the ones you change on `:root` (or on any element, for a region)
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
247
|
+
the ones you change on `:root` (or on any element, for a region). Component defaults inherit
|
|
248
|
+
them; explicit scope overrides and density presets establish new values on their regions.
|
|
249
|
+
`density` changes spacing and control heights; `scale` also changes icons and type;
|
|
250
|
+
`typography.scale` changes type alone. A component's own variables are private (`--_x`), never
|
|
251
|
+
an override surface.
|
|
231
252
|
|
|
232
253
|
Kit component rules are layered, so ordinary unlayered consumer CSS wins whatever its order,
|
|
233
254
|
without `!important`. Target stable documented `data-slot` or
|
|
@@ -265,6 +286,9 @@ portals, strict CSP, or streaming SSR. Read `references/theming.md` before defin
|
|
|
265
286
|
| `references/theming.md` | changing color, radius, density, scale, typography, DTCG, or Tailwind integration |
|
|
266
287
|
| `references/provider-and-scoping.md` | configuring roots, nested regions, portals, CSP, or SSR |
|
|
267
288
|
| `references/composition.md` | building application-specific pages and business components |
|
|
289
|
+
| `references/structure-and-spacing.md` | choosing structural blocks, insets/gaps, widths, responsive grids, scroll owners or bleed |
|
|
290
|
+
| `references/blocks.md` | choosing analytics, onboarding, timelines or admin blocks and their application seams |
|
|
291
|
+
| `references/reference-workflows.md` | complete compositions, state ownership and helper sources |
|
|
268
292
|
| `references/composition-ladder.md` | choosing the highest ready tier and lowest extension seam |
|
|
269
293
|
| `references/framework-wiring.md` | connecting router, data, permissions, persistence, and rendering boundaries |
|
|
270
294
|
| `references/forms.md` | binding fields to React state, react-hook-form, or another controller |
|
|
@@ -276,6 +300,11 @@ portals, strict CSP, or streaming SSR. Read `references/theming.md` before defin
|
|
|
276
300
|
|
|
277
301
|
## Consumer completion checklist
|
|
278
302
|
|
|
303
|
+
Record the package/skill versions, selected owners and public seams, changed callers, tested
|
|
304
|
+
routes and states, widths/themes/densities/locales, keyboard/focus interactions, exact commands
|
|
305
|
+
and observed results. List unavailable checks and application acceptance still required.
|
|
306
|
+
Only claim checks you executed; a successful typecheck cannot establish visual or workflow success.
|
|
307
|
+
|
|
279
308
|
- Exact module import and its CSS resolve from the installed package.
|
|
280
309
|
- Only the selected modules' optional peers are installed and bundled.
|
|
281
310
|
- Public props and slots are used; no internal path, hash class, or undocumented token leaks in.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"packageVersion": "3.2.0",
|
|
4
|
+
"files": {
|
|
5
|
+
"SKILL.md": "c9a3884bc4315abd7425417e64aa68460a3a890c3f93f8f201d6dd0e3f79209d",
|
|
6
|
+
"references/api-compatibility.md": "7ecd0b9be0eff433391709fdf08321885d9ac4f1f30d99579b9ec179ea070da2",
|
|
7
|
+
"references/blocks.md": "42772d3390cdb22d0aac25dd47ddc0ed7de18159a760b3f8dc09eb9346b386c3",
|
|
8
|
+
"references/composition-ladder.md": "f02ee3b3f55464684ba993d7e129915d5c4732b329d8b9f702ab7579ef6322f2",
|
|
9
|
+
"references/composition.md": "ccf8fa769cc605c9f7d59ec939e3be5873f97b5d4158eee5eb04dc62d523f270",
|
|
10
|
+
"references/forms.md": "8e1b86b5da221f04855b59f1ebcf90c7cc6fe63284be34b30afd09e4d978fafb",
|
|
11
|
+
"references/framework-wiring.md": "c98ca307c33c0e89ba4371d3d893af2aa0fd219aeea7413d534c3ac83d4cbf20",
|
|
12
|
+
"references/i18n.md": "74759967f8460ceb2e41c18d6ff20c62f40ccd745bbc87b645106360be3d7c59",
|
|
13
|
+
"references/imports.md": "c45ff607b729b9b00b8a58ed62bf0da9f12c355a554f3ef7b0aa5f17d9b7b684",
|
|
14
|
+
"references/installation.md": "60e3ca9ac46f5d43f27cb3eacf482bb4bbae05f5bc673f10a3fe7aa6fd34b5ed",
|
|
15
|
+
"references/migration.md": "e8e3875e4db01b6ed32246733e493f8077db8dd1b18ca82a8309af0889e74381",
|
|
16
|
+
"references/provider-and-scoping.md": "71a9844192804c3be7c604545b9592bf17e6f591595553d6a91b1de9b954259a",
|
|
17
|
+
"references/reference-workflows.md": "9f7a02aa3d34934cd8a22fbabcc377a880513c251bba0b2a49f5ecdc50f7c47c",
|
|
18
|
+
"references/structure-and-spacing.md": "e44c3f90e2d3c4aa590c7a88115e7806d6e0fdff1c7bba9ce862894fdd671653",
|
|
19
|
+
"references/theming.md": "f5e14f5c72274a7b58a1148a8365334aafdbb884bac2ed6854022a895e3c9023",
|
|
20
|
+
"references/troubleshooting.md": "f81f8fb782933bedadf347efbc15898bd531b0719d9ffe6f1ff2cc6d309837d8",
|
|
21
|
+
"references/verification.md": "c8a8f2313021d7f15fe02a6f49f46b5bf457ffba69ece9f962c836bd1a1a3a3e"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# API compatibility
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Exact package subpaths, exported names, callable signatures, and
|
|
4
4
|
exported props/type members are compatibility surfaces. Public global theme tokens, documented
|
|
5
5
|
`data-slot` and BEM hooks, and the `strings` contracts are also consumer contracts.
|
|
6
6
|
|
|
@@ -15,7 +15,8 @@ exported props/type members are compatibility surfaces. Public global theme toke
|
|
|
15
15
|
| a documented default changes | behavioural change; release notes required |
|
|
16
16
|
| component token or hashed CSS Module name changes | internal unless documented as an extension point |
|
|
17
17
|
|
|
18
|
-
3.1
|
|
18
|
+
3.1 includes breaking changes despite its minor version number: it removes obsolete aliases
|
|
19
|
+
and adapters. Removed names do not stay available solely for an
|
|
19
20
|
upgrade window. A breaking release records the replacement in the migration reference and
|
|
20
21
|
the changelog; consumers pin the old version until they are ready to update.
|
|
21
22
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Choosing and composing blocks
|
|
2
|
+
|
|
3
|
+
A structural block arranges regions; a subject block renders a recognizable job such as
|
|
4
|
+
metrics, onboarding or an order summary. Use [Structure and spacing](structure-and-spacing.md)
|
|
5
|
+
for page geometry, surfaces and gaps. Start with a ready subject block when its vocabulary
|
|
6
|
+
fits the product, then use its documented props, callbacks or parts. The application keeps
|
|
7
|
+
data, permission checks, routing, mutation and persistence.
|
|
8
|
+
|
|
9
|
+
## Published subject modules
|
|
10
|
+
|
|
11
|
+
| Job | Exact subpath and examples | Application owns | Optional peers |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| Quantities, changes and plots | `themelia-ui/blocks/analytics`: MetricGrid, Metric, MetricComparison, ChartCard, ActivityHeatmap | Measures, period, comparison meaning, loading/errors and metric actions | `recharts`, for the module even when the adopted block has no plot |
|
|
14
|
+
| Setup tasks completed over time | `themelia-ui/blocks/onboarding`: Checklist | Step status, content, submission and persistence | None |
|
|
15
|
+
| Milestones, changelog or linear progress | `themelia-ui/blocks/timelines`: MilestonesTimeline, ChangelogTimeline, Steps, StepsBar | Sequence, status, dates and navigation | None |
|
|
16
|
+
| Permissions and credential management | `themelia-ui/blocks/admin/access`: RolePermissions, CredentialList, SensitiveAction | Authorization, actual secrets, deletion confirmation and mutations | None |
|
|
17
|
+
| Orders, invoices, inventory and payment summaries | `themelia-ui/blocks/admin/commerce`: OrderSummary, InvoiceLineItems, InventorySection, PaymentTimeline | Commerce records, calculation policy, commands and transport | None |
|
|
18
|
+
|
|
19
|
+
These are modules, not broad barrels: there is no `themelia-ui/blocks` import. General and
|
|
20
|
+
admin profiles come from the same installation. Admin is presentation vocabulary rather
|
|
21
|
+
than an authorization layer; importing an admin block does not protect its actions or data.
|
|
22
|
+
The generated [import table](imports.md) is authoritative for optional peers.
|
|
23
|
+
Do not assume a symbol is peer-free because its own UI looks simple.
|
|
24
|
+
|
|
25
|
+
Open the selected API before JSX: analytics (`node_modules/themelia-ui/docs/generated/components/blocks--analytics.md`),
|
|
26
|
+
onboarding (`node_modules/themelia-ui/docs/generated/components/blocks--onboarding.md`),
|
|
27
|
+
timelines (`node_modules/themelia-ui/docs/generated/components/blocks--timelines.md`),
|
|
28
|
+
admin access (`node_modules/themelia-ui/docs/generated/components/blocks--admin--access.md`), or
|
|
29
|
+
admin commerce (`node_modules/themelia-ui/docs/generated/components/blocks--admin--commerce.md`).
|
|
30
|
+
They list exact record shapes, defaults, strings, dependencies and preview recipes.
|
|
31
|
+
|
|
32
|
+
## Facts versus quantities
|
|
33
|
+
|
|
34
|
+
MetadataList owns label/value facts such as owner, status, address or a date. A numeric
|
|
35
|
+
identifier is still a fact. MetricGrid/Metric own measures such as delivered messages,
|
|
36
|
+
revenue or a conversion rate, with optional comparison and trend. Put prose facts beside
|
|
37
|
+
quantities rather than turning every value into a metric tile.
|
|
38
|
+
|
|
39
|
+
```tsx compile
|
|
40
|
+
import { ContentBlock, MetadataList } from "themelia-ui/base/display"
|
|
41
|
+
import { Stack } from "themelia-ui/base/structure"
|
|
42
|
+
import { MetricGrid, type MetricData } from "themelia-ui/blocks/analytics"
|
|
43
|
+
import { Page } from "themelia-ui/layout/page"
|
|
44
|
+
|
|
45
|
+
const metrics: MetricData[] = [
|
|
46
|
+
{ id: "delivered", label: "Delivered", value: 248 },
|
|
47
|
+
{ id: "opened", label: "Opened", value: null, subtitle: "Tracking unavailable" },
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
export function DeliveryOverview() {
|
|
51
|
+
return <Page header={{ title: "Delivery overview", description: "Current campaign" }}>
|
|
52
|
+
<Stack>
|
|
53
|
+
<MetricGrid metrics={metrics} variant="card" />
|
|
54
|
+
<ContentBlock title="Campaign details">
|
|
55
|
+
<MetadataList items={[
|
|
56
|
+
{ id: "owner", label: "Owner", value: "Alex" },
|
|
57
|
+
{ id: "status", label: "Status", value: "Sending" },
|
|
58
|
+
]} />
|
|
59
|
+
</ContentBlock>
|
|
60
|
+
</Stack>
|
|
61
|
+
</Page>
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Use `null` for an unavailable MetricData value; zero means a measured zero. MetricGrid's
|
|
66
|
+
loading contract is for initial loading. For error or refresh behavior, inspect the adopted
|
|
67
|
+
component's exact API rather than assuming every analytics block accepts the same props.
|
|
68
|
+
The [communications workflow](reference-workflows.md) demonstrates retained figures,
|
|
69
|
+
failure feedback, retry, unknown tracking and a separate facts region.
|
|
70
|
+
|
|
71
|
+
## Compose without duplicating owners
|
|
72
|
+
|
|
73
|
+
Inspect whether a block already owns its title, surface, controls and responsive layout
|
|
74
|
+
before surrounding it with another Card or Grid. MetricGrid already arranges tiles;
|
|
75
|
+
ChartCard already owns its chart frame; FormSection already owns an editable section's
|
|
76
|
+
header and inset. Use a sibling surface for an independent subject and ContentBlock for
|
|
77
|
+
supporting prose inside one. [Composition](composition.md#decide-the-owners-before-jsx)
|
|
78
|
+
describes the owners in detail.
|
|
79
|
+
|
|
80
|
+
Keep default typography and spacing with those owners. Do not invent `size`, `padding`,
|
|
81
|
+
`error` or `strings` props by analogy with another block. Use a documented slot or render
|
|
82
|
+
prop for one region; use public parts or an application composition when the arrangement
|
|
83
|
+
must differ. No block needs every extension seam. The [composition ladder](composition-ladder.md)
|
|
84
|
+
is a discovery aid; the selected API remains the contract.
|
|
85
|
+
|
|
86
|
+
## Compose your own subject
|
|
87
|
+
|
|
88
|
+
When the ready block's vocabulary cannot express the product, start from its public
|
|
89
|
+
lower-tier recipe rather than copying internals. The live block pages include these
|
|
90
|
+
compose-your-own examples; their source is also embedded in
|
|
91
|
+
recipes.json (`node_modules/themelia-ui/docs/generated/recipes.json`) under the exact id below and in the
|
|
92
|
+
recipe book (`node_modules/themelia-ui/docs/build/recipes.md`). The recipe imports identify the adopted modules and
|
|
93
|
+
their peer requirements; they do not require importing the corresponding ready block.
|
|
94
|
+
|
|
95
|
+
| Subject | Recipe id | Public building blocks |
|
|
96
|
+
| --- | --- | --- |
|
|
97
|
+
| A custom measure | `analytics-blueprint` | Card, Stack, Money, Badge, Sparkline |
|
|
98
|
+
| Setup checklist | `blocks-checklist-blueprint` | Progress, Accordion, IconBadge, Text, Button |
|
|
99
|
+
| Release timeline | `blocks-changelog-blueprint` | Timeline, MonoValue, Badge |
|
|
100
|
+
| Role/permission summary | `blocks-roles-blueprint` | Table, Badge, VisuallyHidden |
|
|
101
|
+
| Custom order summary | `cart-summary-blueprint` | Card, MetadataList, Money, Button, toast |
|
|
102
|
+
|
|
103
|
+
For example, retrieve the exact checklist source from the installed package:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
node <<'NODE'
|
|
107
|
+
const fs = require('node:fs')
|
|
108
|
+
const { recipes } = JSON.parse(fs.readFileSync('node_modules/themelia-ui/docs/generated/recipes.json', 'utf8'))
|
|
109
|
+
const recipe = recipes.find(item => item.id === 'blocks-checklist-blueprint')
|
|
110
|
+
if (!recipe) throw new Error('Recipe missing from this installed version')
|
|
111
|
+
process.stdout.write(recipe.code)
|
|
112
|
+
NODE
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
These examples establish presentation seams, with fixed sample data and mock callbacks.
|
|
116
|
+
Keep the application's real permission model, calculations and completion state in its
|
|
117
|
+
own component. Use the [complete workflows](reference-workflows.md) when the task needs
|
|
118
|
+
submission, lookup, selection or retained-draft behavior beyond a presentation recipe.
|
|
119
|
+
|
|
120
|
+
For translated copy, use the selected module's typed strings and exported defaults. Product
|
|
121
|
+
labels and record content remain application copy. Test permissions, loading/empty/error
|
|
122
|
+
states, long labels, keyboard interaction, RTL and the adopted density in the real route;
|
|
123
|
+
the package's previews do not establish application acceptance.
|
|
@@ -10,9 +10,9 @@ The rungs are ordinary props; controlled state and callbacks when state exists;
|
|
|
10
10
|
named slots; render props; exported parts; headless hooks; and complete recipes. Passive
|
|
11
11
|
modules may stop at the first rung. Interaction features normally expose several.
|
|
12
12
|
|
|
13
|
-
This table
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
This table summarizes detected declarations and recipes. It is a discovery aid, not a
|
|
14
|
+
prop contract: open the selected module API for exact signatures and supported seams.
|
|
15
|
+
It focuses on feature modules; the columns start at accessors.
|
|
16
16
|
|
|
17
17
|
| module | accessors | slots | render props | headless hook | partials | recipe |
|
|
18
18
|
| --- | :-: | :-: | :-: | :-: | :-: | :-: |
|
|
@@ -41,7 +41,7 @@ higher rungs are meaningful; the columns start at accessors.
|
|
|
41
41
|
| `features/table` | ● | ● | · | ● | ● | ● |
|
|
42
42
|
| `features/theme-tweaker` | · | ● | · | ● | ● | ● |
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## Four feature examples
|
|
45
45
|
|
|
46
46
|
Global Search, Filters, Comments and Data View are the demonstration cases, because a
|
|
47
47
|
ladder that only works on a Badge proves nothing. Each is usable at three heights:
|
|
@@ -50,7 +50,7 @@ ladder that only works on a Badge proves nothing. Each is usable at three height
|
|
|
50
50
|
|
|
51
51
|
**Ready-made** — `GlobalSearch`, dropped in with props and callbacks.
|
|
52
52
|
|
|
53
|
-
**Region-customized** —
|
|
53
|
+
**Region-customized** — 7 other public exports to inspect for region customization: `GlobalSearchDialog`, `GlobalSearchEmptyState`, `GlobalSearchFooter`, `GlobalSearchIdleState`, `GlobalSearchInput`, and 2 more.
|
|
54
54
|
|
|
55
55
|
**Headless** — `useGlobalSearch`, for presentation the parts cannot express.
|
|
56
56
|
|
|
@@ -58,7 +58,7 @@ ladder that only works on a Badge proves nothing. Each is usable at three height
|
|
|
58
58
|
|
|
59
59
|
**Ready-made** — `FilterLayout`, dropped in with props and callbacks.
|
|
60
60
|
|
|
61
|
-
**Region-customized** —
|
|
61
|
+
**Region-customized** — 17 other public exports to inspect for region customization: `AsyncFilterEditor`, `DateFilterEditor`, `FilterEditor`, `FilterErrorBoundary`, `FilterOperator`, and 12 more.
|
|
62
62
|
|
|
63
63
|
**Headless** — `useAsyncOptions`, `useFilterCache`, `useFilterGroups`, `useFilters`, for presentation the parts cannot express.
|
|
64
64
|
|
|
@@ -66,7 +66,7 @@ ladder that only works on a Badge proves nothing. Each is usable at three height
|
|
|
66
66
|
|
|
67
67
|
**Ready-made** — `Comments`, dropped in with props and callbacks.
|
|
68
68
|
|
|
69
|
-
**Region-customized** —
|
|
69
|
+
**Region-customized** — 5 other public exports to inspect for region customization: `CommentAttachmentChip`, `CommentComposer`, `CommentContent`, `CommentItem`, `CommentTimeline`.
|
|
70
70
|
|
|
71
71
|
**Headless** — `useAttachmentUpload`, `useComments`, for presentation the parts cannot express.
|
|
72
72
|
|
|
@@ -74,6 +74,6 @@ ladder that only works on a Badge proves nothing. Each is usable at three height
|
|
|
74
74
|
|
|
75
75
|
**Ready-made** — `DataView`, dropped in with props and callbacks.
|
|
76
76
|
|
|
77
|
-
**Region-customized** —
|
|
77
|
+
**Region-customized** — 5 other public exports to inspect for region customization: `DataViewPagination`, `DataViewShell`, `DataViewTableFrame`, `DataViewToolbar`, `SavedViewTabs`.
|
|
78
78
|
|
|
79
79
|
**Headless** — `useDataView`, for presentation the parts cannot express.
|
|
@@ -20,6 +20,10 @@ ready-made surface does not express the job.
|
|
|
20
20
|
compose both; neither may import a block. The complete generated graph is in
|
|
21
21
|
Profiles (`node_modules/themelia-ui/docs/generated/profiles.md`).
|
|
22
22
|
|
|
23
|
+
For structural blocks, spacing roles and responsive widths, use
|
|
24
|
+
[Structure and spacing](structure-and-spacing.md). For ready analytics, onboarding,
|
|
25
|
+
timeline and admin presentations, use [Choosing blocks](blocks.md).
|
|
26
|
+
|
|
23
27
|
## The composition ladder
|
|
24
28
|
|
|
25
29
|
Use the lowest rung that solves the real requirement:
|
|
@@ -142,6 +146,13 @@ The invoice example above is the canonical shape: `Page` for route geometry,
|
|
|
142
146
|
`MetadataList` and primitives for facts, then domain callbacks on package actions. Keep the
|
|
143
147
|
record type out of the package.
|
|
144
148
|
|
|
149
|
+
When the task also fits the standard loading, empty, error and retry presentation, use
|
|
150
|
+
`ResourceShowShell` or `ResourceIndexShell` from `features/resource`. Those shells already
|
|
151
|
+
own a header, body and state replacement; do not duplicate that route header by wrapping
|
|
152
|
+
them in another Page. Page remains appropriate for a custom record arrangement where the
|
|
153
|
+
application already owns lifecycle feedback. Read the
|
|
154
|
+
resource API (`node_modules/themelia-ui/docs/generated/components/features--resource.md`) for state and slot contracts.
|
|
155
|
+
|
|
145
156
|
### Form
|
|
146
157
|
|
|
147
158
|
```tsx fragment — validation, field values, submit mutation, and product copy remain in the app
|
|
@@ -191,7 +202,7 @@ documentation tree whose vocabulary is not settings.
|
|
|
191
202
|
|
|
192
203
|
Look up a specific task with the offline finder. Exact symbols take priority; `--explain`
|
|
193
204
|
shows matched components, selection reasons and direct API anchors. `--json` exposes the
|
|
194
|
-
same records for tools. Guidance marked `
|
|
205
|
+
same records for tools. Guidance marked `module` is a fallback, not a component-specific
|
|
195
206
|
recommendation. An empty result means refine the query or inspect the catalogue, not invent
|
|
196
207
|
an export.
|
|
197
208
|
|
|
@@ -314,6 +325,92 @@ Only use states the selected module exposes; the API reference is authoritative.
|
|
|
314
325
|
complete examples above type-check against the built package, but their application
|
|
315
326
|
callbacks are illustrative: verify persistence and browser behaviour in your app.
|
|
316
327
|
|
|
328
|
+
## Decide the owners before JSX
|
|
329
|
+
|
|
330
|
+
| Owner | Insets and type | Name and command scope | Parent responsibility |
|
|
331
|
+
| --- | --- | --- | --- |
|
|
332
|
+
| `Page` | Route geometry; header owns heading type | One route heading; route commands | Data, routing and independent subjects |
|
|
333
|
+
| `Card` / parts | Surface and content inset; header owns title/description | A bounded subject; commands for that subject | Arrange sibling subjects, choose heading level |
|
|
334
|
+
| `ContentBlock` | Title/content gap; `plain` has no inset, decorated surfaces add one | Supporting content within a subject | Decide whether another independent surface is warranted |
|
|
335
|
+
| `MetadataList` / values | Fact layout; labels and semantic value formatting | Read-only facts, not editable labels | Permission-filtered records and value descriptors |
|
|
336
|
+
| Analytics blocks | Quantity hierarchy and responsive metric arrangement | Measures and their period; metric actions | Query, unknown quantities and interpretation |
|
|
337
|
+
| `FormSection` | Section inset and heading; `flat` retains its padding | Editable region title; section-specific actions | Form, values, validation and completion |
|
|
338
|
+
| `FieldGroup` | Related control arrangement and support line | Fieldset/legend for a group; children retain distinct labels | Group disabled state and validation policy |
|
|
339
|
+
| `FormField` / binding | Label and support typography, control association | One editable field | Value, mutation and explicit name/ARIA overrides |
|
|
340
|
+
| `Stack` / `Grid` | Shared gaps; no new typography owner | Passive arrangement | Choose whether child insets already supply separation |
|
|
341
|
+
| `DataView` | Filter/table shell and responsive filter presentation | Resource-browser commands | Transport, page totals and selection lifetime |
|
|
342
|
+
| `DataTable` | Tabular interaction and table geometry | Column/row names and row commands | Filters, surrounding surface and server transport |
|
|
343
|
+
| `FilterLayout` / slots | Responsive controls and sheet | Filter controls only | Shared filter state; put export/create in action slots |
|
|
344
|
+
|
|
345
|
+
`surface="flat"` changes decoration, not the inset contract. Several flat FormSections
|
|
346
|
+
inside CardContent accumulate the card content inset and each section's inset. Use the
|
|
347
|
+
ready Card body when that separation is useful; use parts when you need a different region
|
|
348
|
+
arrangement. `Stack gap="none"` is appropriate when adjacent sections already own their
|
|
349
|
+
vertical separation. Do not compensate by assigning private padding variables or local type.
|
|
350
|
+
|
|
351
|
+
These are fragments; the [complete workflows](reference-workflows.md) include state,
|
|
352
|
+
helpers and submission behavior.
|
|
353
|
+
|
|
354
|
+
```tsx fragment — fields and subject data come from the application
|
|
355
|
+
<Card title="Account details">
|
|
356
|
+
<Stack gap="none">
|
|
357
|
+
<FormSection surface="flat" title="Contact">{contactFields}</FormSection>
|
|
358
|
+
<FormSection surface="flat" title="Billing">{billingFields}</FormSection>
|
|
359
|
+
</Stack>
|
|
360
|
+
</Card>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
```tsx fragment — parts expose the same owners; table rows and columns are application data
|
|
364
|
+
<Card>
|
|
365
|
+
<CardHeader title="Related records" titleLevel={2} />
|
|
366
|
+
<CardContent><DataTable data={rows} columns={columns} /></CardContent>
|
|
367
|
+
</Card>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Use sibling Cards for independent subjects. Use ContentBlock inside a Card for supporting
|
|
371
|
+
prose. Repeating the route heading as each Card title adds no new subject. Repeating a
|
|
372
|
+
FormField label in a nested DisplayLabel creates competing names; supply the field label
|
|
373
|
+
once and let FormField associate it. A FieldGroup legend names the group, so its children's
|
|
374
|
+
labels should identify their distinct values. Labels on different records may repeat.
|
|
375
|
+
|
|
376
|
+
```tsx fragment — each subject supplies its own application-owned facts
|
|
377
|
+
<Grid columns={{ base: 1, md: 2 }}>
|
|
378
|
+
<Card title="Contact"><MetadataList items={contactFacts} /></Card>
|
|
379
|
+
<Card title="Billing"><MetadataList items={billingFacts} /></Card>
|
|
380
|
+
</Grid>
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Grid owns separation between the sibling subjects and their responsive columns. Each Card
|
|
384
|
+
owns its header and body inset. For a resource browser, DataView already owns the filter/table
|
|
385
|
+
frame: put a Heading and supporting Text beside that frame instead of wrapping it in another
|
|
386
|
+
Card. The [resource workflow](reference-workflows.md) demonstrates a constrained parent;
|
|
387
|
+
the detail workflow demonstrates a secondary table within an independent titled subject.
|
|
388
|
+
|
|
389
|
+
Keep a record's command beside that record, a page command in the page header, and a
|
|
390
|
+
selected-row command in the table's bulk-action seam. Filter toolbars communicate query
|
|
391
|
+
state; export and create belong in the action slots. Applications decide destructive policy,
|
|
392
|
+
field-per-row arrangements and permission boundaries.
|
|
393
|
+
|
|
394
|
+
For server filtering, use `filtering.filterRows: ({ data }) => [...data]` when the server
|
|
395
|
+
already matched the page. DataView's default filtering is local and can remove valid server
|
|
396
|
+
matches whose search fields are absent from the visible columns. Use an app-owned cursor
|
|
397
|
+
footer when totals are unknown; never invent a page count. Drop to DataTable when the app
|
|
398
|
+
already owns the browser shell, filters and command placement.
|
|
399
|
+
|
|
400
|
+
Selector variants serve different lifecycles: SuggestionsCombobox uses the generic lookup
|
|
401
|
+
hook; AsyncCombobox accepts application-owned results; ResourceCombobox owns the ready
|
|
402
|
+
single-resource fetching presentation. Use `scopeKey` on SuggestionsCombobox or ResourceCombobox when workspace or permission context changes without a
|
|
403
|
+
query change. It invalidates lookup results, not the controlled selection. The application
|
|
404
|
+
clears a value that is invalid in the new context.
|
|
405
|
+
|
|
406
|
+
```bash
|
|
407
|
+
node node_modules/themelia-ui/scripts/consumer/find-component.mjs "editable section" --context=existing-surface --context=editable --explain
|
|
408
|
+
node node_modules/themelia-ui/scripts/consumer/find-component.mjs "resource selector" --context=changing-scope --json
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
Context matches are positive evidence. Uncurated exports remain visible with unknown
|
|
412
|
+
context coverage; they do not become recommendations by omission.
|
|
413
|
+
|
|
317
414
|
## When to wrap, compose, or contribute
|
|
318
415
|
|
|
319
416
|
- **Wrap** when the product needs a stable local name or defaults around one module.
|
|
@@ -69,9 +69,10 @@ consumer on plain state never resolves react-hook-form.
|
|
|
69
69
|
|
|
70
70
|
## Field chrome
|
|
71
71
|
|
|
72
|
-
`FormField` renders
|
|
73
|
-
hint`. They replace each other rather than stacking
|
|
74
|
-
|
|
72
|
+
`FormField` renders at most **one** supporting message, resolved as `error || helperText ||
|
|
73
|
+
hint`. They replace each other rather than stacking. A message can wrap, and adding or
|
|
74
|
+
changing it can change field height; check long translated errors at narrow widths.
|
|
75
|
+
It also owns the wiring: it associates the label, points
|
|
75
76
|
`aria-describedby` at the supporting line, and sets `aria-invalid` on the control when there
|
|
76
77
|
is an error, without overriding any of these that the caller set explicitly. Errors are
|
|
77
78
|
announced politely (`role="status"`), so validation firing on each keystroke does not
|
|
@@ -80,6 +81,25 @@ interrupt typing.
|
|
|
80
81
|
`FieldGroup` covers several controls sharing one label and one supporting line — a date
|
|
81
82
|
range, a name split in two.
|
|
82
83
|
|
|
84
|
+
## Sections and completion
|
|
85
|
+
|
|
86
|
+
Use FormSection for an editable region inside a form, Card for an independent subject,
|
|
87
|
+
and ContentBlock for supporting read-only prose. Flat FormSections retain region padding;
|
|
88
|
+
an enclosing Stack can use `gap="none"` when that padding supplies the desired separation.
|
|
89
|
+
FieldGroup supplies fieldset/legend semantics. Each child FormField still needs a distinct
|
|
90
|
+
label. A section heading is not a field label.
|
|
91
|
+
|
|
92
|
+
A resolved promise is not evidence that validation succeeded. ActionDialog normally closes
|
|
93
|
+
after its confirmation callback resolves. Set `closeOnAsyncComplete={false}` when the app
|
|
94
|
+
resolves with errors, and close controlled `open` only after explicit success. For a native
|
|
95
|
+
form, use `formId` to associate the dialog's submit action with that form; avoid also invoking
|
|
96
|
+
the mutation in `onConfirm`. Native constraint validation, the submit handler and domain
|
|
97
|
+
validation then each have one owner. Prevent duplicate submissions while pending, retain
|
|
98
|
+
drafts after rejection and associate errors with the relevant field or root region.
|
|
99
|
+
|
|
100
|
+
See the complete [multi-section form and nested action](reference-workflows.md) sources.
|
|
101
|
+
For the inset and gap contract, see [Structure and spacing](structure-and-spacing.md#use-the-two-spacing-roles).
|
|
102
|
+
|
|
83
103
|
## Generated forms
|
|
84
104
|
|
|
85
105
|
When the fields come from a schema at runtime, use `features/schema-form`. When they are
|
|
@@ -22,7 +22,9 @@ cells. Write it once:
|
|
|
22
22
|
import type { LinkRenderer } from "themelia-ui/layout/sidebar"
|
|
23
23
|
|
|
24
24
|
export const renderLink: LinkRenderer = ({ href, children, active, disabled, external, ...rest }) =>
|
|
25
|
-
disabled || !href ? <span {...rest}>{children}</span>
|
|
25
|
+
disabled || !href ? <span {...rest}>{children}</span>
|
|
26
|
+
: external ? <a href={href} {...rest}>{children}</a>
|
|
27
|
+
: <AppLink to={href} {...rest}>{children}</AppLink>
|
|
26
28
|
```
|
|
27
29
|
|
|
28
30
|
Return one element and spread the rest of the props onto it: they carry the class, the
|
|
@@ -50,6 +52,20 @@ async lifecycle; the application decides cache invalidation, retries, and error
|
|
|
50
52
|
</ResourceIndexShell>
|
|
51
53
|
```
|
|
52
54
|
|
|
55
|
+
## Lookup and navigation lifetimes
|
|
56
|
+
|
|
57
|
+
Pass a stable `scopeKey` to ResourceCombobox, SuggestionsCombobox or useSuggestions when the lookup's workspace, locale or
|
|
58
|
+
permission context changes. Changing callback identity alone does not refetch. A scope
|
|
59
|
+
change aborts old work, hides old results/errors and refetches an eligible open query while
|
|
60
|
+
retaining query, controlled value and open state. Late responses from an old scope cannot
|
|
61
|
+
complete the current lookup. The app owns whether the selected id remains valid.
|
|
62
|
+
|
|
63
|
+
Sidebar workspace disclosure keeps the mobile sheet open. A selected workspace marked
|
|
64
|
+
`external: false` dismisses the sheet after selection; external destinations retain native
|
|
65
|
+
target/rel behavior. Forward renderer props, including the click handler, to the real link.
|
|
66
|
+
The app's router handles same-app addresses and preserves modifiers and new-tab gestures.
|
|
67
|
+
See the [workspace reference](reference-workflows.md).
|
|
68
|
+
|
|
53
69
|
## Permissions
|
|
54
70
|
|
|
55
71
|
Resolve authorization before constructing actions. Omit an action the user cannot perform;
|
|
@@ -58,16 +74,28 @@ through the module's tooltip or description seam.
|
|
|
58
74
|
|
|
59
75
|
## Translation
|
|
60
76
|
|
|
61
|
-
Supply
|
|
77
|
+
Supply component-owned copy through the selected API's documented `strings` prop. Passive
|
|
78
|
+
components whose copy comes from children need no strings object. Keep product copy
|
|
62
79
|
in application data or children. The default objects are exported so a locale can start
|
|
63
80
|
from the complete shape rather than guessing keys; see [Internationalization](i18n.md).
|
|
64
81
|
|
|
65
82
|
## Server rendering and client boundaries
|
|
66
83
|
|
|
67
|
-
|
|
68
|
-
`
|
|
69
|
-
|
|
70
|
-
|
|
84
|
+
Interactive and provider-dependent entrypoints carry `"use client"`, including
|
|
85
|
+
`themelia-ui/primitives` and `themelia-ui/ui-provider`; passive modules such as
|
|
86
|
+
`themelia-ui/base/structure` can remain server-pure. Inspect the exact published entrypoint
|
|
87
|
+
rather than inferring its boundary from its name. In a React Server Components framework, a server component
|
|
88
|
+
can render those client components with serializable props; callbacks, hooks and live
|
|
89
|
+
controlled state belong in an application client component. A provider can receive server
|
|
90
|
+
rendered children, so keep the boundary around the interactive region rather than the whole
|
|
91
|
+
page. Check your framework's serialization rules for config containing functions or modules.
|
|
92
|
+
|
|
93
|
+
Formatting helpers exported from `primitives` share its client boundary: do not call them
|
|
94
|
+
from an RSC server component as if they came from a server-pure subpath. Format server data
|
|
95
|
+
with the application's server utilities or render the corresponding display primitive.
|
|
96
|
+
`themelia-ui/theming` exports pure derivation helpers without a client directive. Exact
|
|
97
|
+
subpaths also keep optional peers isolated. Ordinary Node SSR can load and render the
|
|
98
|
+
component modules; that does not make their exports server-callable in RSC.
|
|
71
99
|
|
|
72
100
|
For CSP, portals, nested theme regions, and defaults, use
|
|
73
101
|
[Provider and scoping](provider-and-scoping.md). Do not recreate provider context in an
|
|
@@ -5,8 +5,10 @@ overridable, and nothing in it inspects `navigator.language` or imports a transl
|
|
|
5
5
|
|
|
6
6
|
## Strings
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
Components that own visible or accessible copy document a `strings` prop; their modules
|
|
9
|
+
export the matching `*Strings` interface and `default*Strings` object. Passive structures
|
|
10
|
+
and components whose copy comes entirely from children need no strings object. Read the
|
|
11
|
+
selected API rather than adding `strings` by analogy:
|
|
10
12
|
|
|
11
13
|
```tsx fragment — shape only, not a program
|
|
12
14
|
<Copyable strings={{ copy: "Kopieren", copied: "Kopiert" }} value={apiKey} />
|
|
@@ -7,7 +7,7 @@ siblings do not exist, because one specifier would pull an entire tier and every
|
|
|
7
7
|
peer inside it. The root carries the provider and the display primitives, both peer-free.
|
|
8
8
|
|
|
9
9
|
A component brings its own CSS in a bundled app. Pages with no bundler link `style.css`; see
|
|
10
|
-
|
|
10
|
+
[Installation](installation.md).
|
|
11
11
|
|
|
12
12
|
## general profile — 95 modules
|
|
13
13
|
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
npm install themelia-ui
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
React 19 and `react-dom` are required peers.
|
|
8
|
-
|
|
7
|
+
React 19 and `react-dom` are required peers. The package's regular dependencies install
|
|
8
|
+
automatically; additional peer packages are optional and resolved only by the modules
|
|
9
|
+
that need them. See [Optional peers](#optional-peers).
|
|
9
10
|
|
|
10
11
|
## Browser support
|
|
11
12
|
|
|
@@ -107,8 +108,8 @@ releases.
|
|
|
107
108
|
|
|
108
109
|
## Optional peers
|
|
109
110
|
|
|
110
|
-
Every peer other than
|
|
111
|
-
use it: a consumer who never imports `features/map` never resolves Leaflet.
|
|
111
|
+
Every peer other than `react` and `react-dom` is optional, and each is reachable only from
|
|
112
|
+
the modules that use it: a consumer who never imports `features/map` never resolves Leaflet.
|
|
112
113
|
|
|
113
114
|
The peer-to-module table is in [`docs/generated/imports.md`](imports.md).
|
|
114
115
|
|