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
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
What changes between versions, what to do when you upgrade, and which changes a stable major
|
|
4
4
|
allows.
|
|
5
5
|
|
|
6
|
+
## Upgrading to 3.2
|
|
7
|
+
|
|
8
|
+
3.2 adds consumer diagnostics, complete reference workflows and optional `scopeKey` support
|
|
9
|
+
for asynchronous combobox lookups, alongside responsive grid, dialog and navigation fixes.
|
|
10
|
+
Applications already on 3.1 need no new codemod replacements. Applications upgrading from
|
|
11
|
+
3.0 or earlier must also follow [Upgrading to 3.1](#upgrading-to-31).
|
|
12
|
+
|
|
13
|
+
After updating the package, refresh the installed consumer skill with the
|
|
14
|
+
[packaged installer](verification.md#offline-diagnosis-and-skill-freshness). Review any
|
|
15
|
+
local edits before replacing them, then run the read-only diagnostics and your application's
|
|
16
|
+
type, build and interaction checks. The [structural guide](structure-and-spacing.md),
|
|
17
|
+
[blocks guide](blocks.md) and [complete workflows](reference-workflows.md) describe the
|
|
18
|
+
public composition contracts.
|
|
19
|
+
|
|
20
|
+
For lookups whose results depend on a workspace, tenant or similar context, pass a stable
|
|
21
|
+
`scopeKey` that changes with that context. The lookup aborts and invalidates old responses;
|
|
22
|
+
the application still owns clearing a selection or query that is no longer valid. See the
|
|
23
|
+
[scoped resource selection workflow](reference-workflows.md).
|
|
24
|
+
|
|
6
25
|
## Upgrading to 3.1
|
|
7
26
|
|
|
8
27
|
3.1 renames and removes public API as well as adding to it. Upgrade deliberately, not
|
|
@@ -83,8 +102,9 @@ selects `[data-row-density]`, `[data-media-density]` or `[data-activity-density]
|
|
|
83
102
|
colour a `light-dark(light, dark)` pair. For a theme of your own:
|
|
84
103
|
|
|
85
104
|
- Declare it on `:root` alone. The selector list 3.0 asked for (`:root, [data-ui-scope],
|
|
86
|
-
[data-density], [data-theme], .light, .dark`) is not needed:
|
|
87
|
-
|
|
105
|
+
[data-density], [data-theme], .light, .dark`) is not needed: component styles inherit the
|
|
106
|
+
root defaults. Explicit regional overrides and density presets replace their corresponding
|
|
107
|
+
inherited values; set a preset-specific spacing override on that preset.
|
|
88
108
|
- Write a dark value into the colour's pair, `--primary: light-dark(#2563eb, #60a5fa)`, rather
|
|
89
109
|
than a `.dark { … }` block, which colours a dark page but misses a dark region inside a light
|
|
90
110
|
one.
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Provider and scoping
|
|
2
2
|
|
|
3
|
+
Choose one document density owner, then use UIScope for a deliberately different region.
|
|
4
|
+
Changing density changes spacing; keep primary copy in Text and headings in Heading or their
|
|
5
|
+
component owners. Check the last field/next heading together: CardContent, FormSection and
|
|
6
|
+
Stack can each contribute separation. A portal must stay inside its intended token scope;
|
|
7
|
+
UIPortalHost provides that boundary. Test open popups as well as the page beneath them.
|
|
8
|
+
|
|
3
9
|
Three components, and the difference between them is what they are allowed to touch.
|
|
4
10
|
|
|
5
11
|
| | Renders | Reaches | Use for |
|
|
@@ -71,8 +77,10 @@ value, and a value is replaced, not merged.
|
|
|
71
77
|
|
|
72
78
|
That is the configuration components read, and the CSS follows it: each scope writes the
|
|
73
79
|
merged overrides on its element, so inside the nested scope above `--primary` is red and
|
|
74
|
-
`--secondary` is green.
|
|
75
|
-
|
|
80
|
+
`--secondary` is green. Component styles inherit global tokens rather than redeclaring
|
|
81
|
+
theme defaults. Explicit Scope/UIScope overrides replace inherited values; a density preset
|
|
82
|
+
also resets its spacing and control heights on that region. A value outside that boundary
|
|
83
|
+
does not override its local declaration; see
|
|
76
84
|
[Theming](theming.md#setting-a-theme).
|
|
77
85
|
|
|
78
86
|
## Scope — tokens only
|
|
@@ -85,17 +93,18 @@ inherits through any element, a `Scope` or a `data-density` region included; see
|
|
|
85
93
|
</Scope>
|
|
86
94
|
```
|
|
87
95
|
|
|
88
|
-
`Scope` renders a `div` without layout. `render` picks another element
|
|
89
|
-
|
|
96
|
+
`Scope` renders a `div` without layout. Its `render` prop picks another element
|
|
97
|
+
(`render={<section />}`), and `transparent={false}` gives it a box. Every
|
|
90
98
|
component inside reads the variables it sets, because components compute from the theme where
|
|
91
99
|
they use it; any element with a `style` does the same, and `Scope` only adds the missing
|
|
92
100
|
layout rule and the `data-ui-scope` marker.
|
|
93
101
|
|
|
94
102
|
## Portals and scopes
|
|
95
103
|
|
|
96
|
-
A scope
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
A scope uses CSS custom properties; its `data-density` and `data-theme` attributes establish
|
|
105
|
+
spacing and colour-scheme values that inherit through the DOM subtree. The attributes
|
|
106
|
+
themselves are not copied to descendants. A portal renders elsewhere in the document, so
|
|
107
|
+
those inherited values do not follow it by default:
|
|
99
108
|
|
|
100
109
|
```tsx fragment — a template with a hole in it
|
|
101
110
|
<UIScope config={{ density: "compact" }}>
|
|
@@ -136,7 +145,7 @@ in — a shadow root, or a positioned overlay element it manages itself.
|
|
|
136
145
|
|
|
137
146
|
## Strict Content Security Policy
|
|
138
147
|
|
|
139
|
-
Some Base UI-backed controls emit a tiny inline style or pre-hydration script for behavior
|
|
148
|
+
Some Base UI-backed controls emit a tiny inline style element or pre-hydration script for behavior
|
|
140
149
|
the component stylesheet cannot express. Put `CSPProvider` at the same application boundary
|
|
141
150
|
as `UIRoot` and pass the request nonce through:
|
|
142
151
|
|
|
@@ -154,7 +163,7 @@ React 19 hoists styles that carry `precedence`. During streaming SSR, configure
|
|
|
154
163
|
renderer with the same style nonce as the provider; otherwise React omits the attribute and
|
|
155
164
|
warns about the mismatch.
|
|
156
165
|
|
|
157
|
-
When the policy
|
|
166
|
+
When the policy forbids inline style elements, suppress Base UI's style elements and
|
|
158
167
|
ship the scrollbar rule in the consuming application's stylesheet:
|
|
159
168
|
|
|
160
169
|
```tsx fragment — App comes from the consuming application
|
|
@@ -171,6 +180,15 @@ ship the scrollbar rule in the consuming application's stylesheet:
|
|
|
171
180
|
`disableStyleElements` does not disable kit behavior; it moves those small rules into the
|
|
172
181
|
consuming app. It does not change how the kit's CSS loads.
|
|
173
182
|
|
|
183
|
+
This option does not remove inline scripts or `style` attributes. A nonce authorizes the
|
|
184
|
+
matching style/script elements; it does not authorize style attributes in server-rendered
|
|
185
|
+
HTML. Providers, responsive structure and popup positioning can use style attributes, so
|
|
186
|
+
a policy that blocks them needs a separate SSR strategy for the adopted components.
|
|
187
|
+
Inspect the rendered HTML and browser CSP reports; `disableStyleElements` alone does not
|
|
188
|
+
establish compatibility with that policy. See the
|
|
189
|
+
[Base UI CSP reference](https://base-ui.com/react/utils/csp-provider#inline-style-attributes)
|
|
190
|
+
for the distinction and available integration strategies.
|
|
191
|
+
|
|
174
192
|
## Reading the config
|
|
175
193
|
|
|
176
194
|
Resolution, in every component:
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Complete reference workflows
|
|
2
|
+
|
|
3
|
+
These sources use public package imports and fixed local mock operations. Copy the complete
|
|
4
|
+
workflow directory, including relative helpers, then replace its transport and policy with
|
|
5
|
+
your application's. The versioned inventory (`node_modules/themelia-ui/docs/generated/workflows/index.json`) lists every
|
|
6
|
+
file, import and API reference. Its package version must match the installed package.
|
|
7
|
+
|
|
8
|
+
| Workflow | Owners and application seam | Complete entry source |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| Record detail | Page owns route heading; sibling Cards own subjects; MetadataList owns facts; app owns record commands | Record detail (`node_modules/themelia-ui/docs/generated/workflows/record-detail/page-layout/record-detail-reference.tsx`) |
|
|
11
|
+
| Server resource index | DataView owns browser presentation; app owns server matching, unknown totals, cursor and page selection | Resource index (`node_modules/themelia-ui/docs/generated/workflows/resource-index/data-view/resource-index-reference.tsx`) |
|
|
12
|
+
| Multi-section form | Card owns surface; flat FormSections retain insets; FieldGroup and FormField own names; app owns validation and completion | Form (`node_modules/themelia-ui/docs/generated/workflows/multi-section-form/form-workflow/multi-section-reference.tsx`) |
|
|
13
|
+
| Scoped resource selection | ResourceCombobox owns lookup; app owns scopeKey and selection validity; Overlay owns task | Selector (`node_modules/themelia-ui/docs/generated/workflows/scoped-resource-selection/combobox/scoped-resource-reference.tsx`) |
|
|
14
|
+
| Nested action flow | Parent owns draft; child owns confirmation; app closes explicitly after successful mutation | Nested action (`node_modules/themelia-ui/docs/generated/workflows/nested-action-flow/action-overlays/nested-action-reference.tsx`) |
|
|
15
|
+
| Workspace navigation | Shell owns geometry; workspace owns disclosure; app owns router and same-app policy | Workspace (`node_modules/themelia-ui/docs/generated/workflows/workspace-navigation/app-shell/workspace-navigation-reference.tsx`) |
|
|
16
|
+
| Media picking | MediaLibraryDialog owns query/picking UI; app commits a separate picker draft on confirmation, pages through footer slots, hydrates saved ids independently, reports unavailable selection and authorizes fetches | Media (`node_modules/themelia-ui/docs/generated/workflows/media-picking/media-library/media-picking-reference.tsx`) |
|
|
17
|
+
| Communications overview | MetricGrid owns quantities; MetadataList owns prose facts; app owns period, delivery state and retry | Communications (`node_modules/themelia-ui/docs/generated/workflows/communications-overview/analytics/communications-reference.tsx`) |
|
|
18
|
+
| Website editor | RichTextEditor owns editing; app retains locale drafts and alt text; RichText sanitizes preview | Website editor (`node_modules/themelia-ui/docs/generated/workflows/website-content-editor/rich-text-editor/website-content-reference.tsx`) |
|
|
19
|
+
|
|
20
|
+
Forms using plain state need no form peer. The optional forms-rhf adapter connects existing
|
|
21
|
+
React Hook Form state without duplicating it. The resource-index workflow uses features/table and
|
|
22
|
+
needs its table peer; record-detail uses peer-free base/table; analytics and rich editing require the peers listed in their generated
|
|
23
|
+
API pages. The general reference consumer stays free of optional peers; the admin reference
|
|
24
|
+
consumer demonstrates adopted adapters.
|
|
25
|
+
|
|
26
|
+
Pending, empty, failed refresh, unavailable selection and resolved validation errors are
|
|
27
|
+
different states. These fixtures demonstrate local feedback and retained drafts. They do
|
|
28
|
+
not establish real persistence, permissions, cache invalidation or backend sanitization.
|
|
29
|
+
Exercise the named cases in your app; [record the evidence](verification.md#completion-record)
|
|
30
|
+
and identify conditions you could not inspect.
|
|
31
|
+
|
|
32
|
+
The inventory's `verification` entries map required cases to behavioral tests or visual
|
|
33
|
+
inspection conditions. They specify coverage to run, not a claim that your application passed.
|
|
34
|
+
`repositoryFile` identifies a maintainer test in the source repository; copy workflow files
|
|
35
|
+
from the inventory's generated source list and adapt the named behaviors to your test runner.
|
|
36
|
+
The browser cases use explicit mock actions; the read-only observer supplies advisory geometry
|
|
37
|
+
findings. Review screenshots and semantics separately in both themes and densities at mobile,
|
|
38
|
+
desktop and wide widths, including long copy and RTL. Build/type checks prove the complete
|
|
39
|
+
sources and public imports; rich-text security tests exercise the sanitization boundary.
|
|
40
|
+
|
|
41
|
+
When embedding a contained app shell in an existing main landmark, use `contentRender={<div />}`
|
|
42
|
+
so the composition keeps one main. For a shell that owns the application's main, omit that
|
|
43
|
+
override. The reference uses the embedded form because it also appears inside a documentation page.
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Structure and spacing
|
|
2
|
+
|
|
3
|
+
Choose the semantic owner first, then arrange its siblings. A Page owns route geometry;
|
|
4
|
+
Card owns an independent subject; ContentBlock owns supporting content; FormSection owns
|
|
5
|
+
an editable region. Stack and Grid arrange those owners without adding a heading, landmark,
|
|
6
|
+
surface or inset. See [Composition](composition.md#decide-the-owners-before-jsx) for names,
|
|
7
|
+
commands and field ownership, and [Blocks](blocks.md) for ready subject arrangements.
|
|
8
|
+
|
|
9
|
+
## Choose a structural block
|
|
10
|
+
|
|
11
|
+
| Need | Public owner | What it supplies |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| Route title, description and commands | `Page` from `layout/page` | Container, page header and body rhythm. It does not create a main landmark or own scrolling. |
|
|
14
|
+
| Page scroll inside a bounded shell | `PageViewport` from `layout/containers` | Scroll region and an inline-size query container. Focusable by default for keyboard scrolling. |
|
|
15
|
+
| Centred width and inline gutter | `Container` from `layout/containers` | Width and gutter only. Page already includes it. |
|
|
16
|
+
| Semantic section with rhythm between groups | `Section` from `layout/containers` | A native section and twice the group gap; supply its heading or accessible name. |
|
|
17
|
+
| Primary work beside a secondary summary | `TwoColumnLayout` from `layout/containers` | Main/aside arrangement, optional full-width header/footer; stacks below `lg`. Aside stays second in the DOM. |
|
|
18
|
+
| One row or column of passive siblings | `Stack` from `base/structure` | Direction, gap, alignment, distribution and optional wrapping. No padding prop. |
|
|
19
|
+
| An explicit column count | `Grid` and `GridCell` from `base/structure` | One to four columns, responsive gaps and cell spans. |
|
|
20
|
+
| As many equal columns as fit | `AdaptiveGrid` from `base/structure` | Auto-fit tracks; `minColumnWidth` is `default` (16rem), `sm` (12rem) or a CSS length. |
|
|
21
|
+
| A fluid main region and a constrained rail | `Split` from `base/structure` | Two direct children: main first, side second. `sideWidth` defaults to 18rem; `collapseBelow` defaults to `md`. |
|
|
22
|
+
| Intentional edge-to-edge content in an inset | `Bleed` from `base/structure` | Negative margins on the selected axis. Match `amount` to the inset it cancels. |
|
|
23
|
+
|
|
24
|
+
Read the exact structure API (`node_modules/themelia-ui/docs/generated/components/base--structure.md`),
|
|
25
|
+
containers API (`node_modules/themelia-ui/docs/generated/components/layout--containers.md`) and
|
|
26
|
+
page API (`node_modules/themelia-ui/docs/generated/components/layout--page.md`) before adding props. Container's
|
|
27
|
+
`maxWidth` (`sm`, `md`, `lg`, `xl`, `2xl`, `full`) and `gutter` (`none`, `sm`, `md`, `lg`)
|
|
28
|
+
are a different contract from Stack/Grid widths (`default`, `sm`, `full`, `none` or a CSS
|
|
29
|
+
length). Container gutters are zero, one, one-and-a-half or twice `--padding`; they do not
|
|
30
|
+
add spacing tokens. Stack/Grid `maxWidth` caps width without centring it or adding a gutter.
|
|
31
|
+
|
|
32
|
+
An app shell normally owns the single main landmark and page scroller. Do not add another
|
|
33
|
+
PageViewport around each section. For document scrolling without a bounded shell, Page can
|
|
34
|
+
live in the application's existing main. When embedding a shell inside another main, use
|
|
35
|
+
its documented `contentRender` seam; see [complete workflows](reference-workflows.md).
|
|
36
|
+
|
|
37
|
+
## Use the two spacing roles
|
|
38
|
+
|
|
39
|
+
| Role | Public tokens | Typical use |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| Container inset | `--padding` | Card regions and decorated ContentBlocks |
|
|
42
|
+
| Item inset | `--padding-sm` | Rows, cells and compact items |
|
|
43
|
+
| Between groups | `--gap`, `gap="default"` | Fields, sibling Cards, sections |
|
|
44
|
+
| Within a group | `--gap-sm`, `gap="sm"` | Title/description, icon/label, toolbar controls |
|
|
45
|
+
|
|
46
|
+
The omitted structure gap is `default`. `gap="none"` removes separation; it is not a third
|
|
47
|
+
spacing step. Insets belong to the child surface and gaps to the parent arrangement. Avoid
|
|
48
|
+
giving both the same separation job. Density changes these lengths together; it does not
|
|
49
|
+
choose smaller text roles. [Theming](theming.md#scale-and-density) explains density, scale
|
|
50
|
+
and typography scale, including overriding a preset's values.
|
|
51
|
+
|
|
52
|
+
CardContent supplies its inset and a group gap between direct children; it drops its top
|
|
53
|
+
padding after an undivided CardHeader. Card `surface="flat"` removes decoration and retains
|
|
54
|
+
region insets. FormSection is a Card composition, so a flat FormSection inside CardContent
|
|
55
|
+
still adds its own inset. Use `Stack gap="none"` between such sections when their insets
|
|
56
|
+
already supply the intended rhythm; do not assume flat means flush.
|
|
57
|
+
|
|
58
|
+
ContentBlock is different: its default `surface="plain"` supplies heading/content spacing
|
|
59
|
+
without an inset or frame. Its `bordered`, `muted` and `card` surfaces add an inset.
|
|
60
|
+
`flush` drops that decorated surface's inset for children that own their own padding.
|
|
61
|
+
Neither flat nor flush changes field associations or heading semantics.
|
|
62
|
+
|
|
63
|
+
```tsx compile
|
|
64
|
+
import { Card } from "themelia-ui/base/cards"
|
|
65
|
+
import { ContentBlock, MetadataList } from "themelia-ui/base/display"
|
|
66
|
+
import { Grid, Stack } from "themelia-ui/base/structure"
|
|
67
|
+
import { Text } from "themelia-ui/base/typography"
|
|
68
|
+
import { Page } from "themelia-ui/layout/page"
|
|
69
|
+
import { TwoColumnLayout } from "themelia-ui/layout/containers"
|
|
70
|
+
|
|
71
|
+
export function AccountOverview() {
|
|
72
|
+
return <Page header={{ title: "Account" }} maxWidth="lg">
|
|
73
|
+
<TwoColumnLayout
|
|
74
|
+
main={<Stack>
|
|
75
|
+
<Grid columns={{ base: 1, md: 2 }}>
|
|
76
|
+
<Card title="Contact" titleLevel={2}>
|
|
77
|
+
<MetadataList items={[{ id: "email", label: "Email", value: "alex@example.com" }]} />
|
|
78
|
+
</Card>
|
|
79
|
+
<Card title="Billing" titleLevel={2}>
|
|
80
|
+
<MetadataList items={[{ id: "status", label: "Status", value: "Active" }]} />
|
|
81
|
+
</Card>
|
|
82
|
+
</Grid>
|
|
83
|
+
<Card title="Notes" titleLevel={2}>
|
|
84
|
+
<ContentBlock description="Context for the next account review.">
|
|
85
|
+
<Text>The customer prefers email updates.</Text>
|
|
86
|
+
</ContentBlock>
|
|
87
|
+
</Card>
|
|
88
|
+
</Stack>}
|
|
89
|
+
aside={<Card title="Summary" titleLevel={2}><Text>Review due next month.</Text></Card>}
|
|
90
|
+
/>
|
|
91
|
+
</Page>
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The example has one route heading, three independent subjects in the main region and a
|
|
96
|
+
secondary summary. Page supplies the gutter; TwoColumnLayout supplies main/aside separation;
|
|
97
|
+
Stack/Grid separate subjects; each Card supplies its inset. The complete record and form
|
|
98
|
+
workflows add application-owned commands, validation and asynchronous states.
|
|
99
|
+
|
|
100
|
+
## Know which width drives responsiveness
|
|
101
|
+
|
|
102
|
+
A responsive structure prop accepts a single value or an object such as
|
|
103
|
+
`gap={{ base: "sm", md: "default" }}`. Values carry forward until another named step replaces
|
|
104
|
+
them; omitted lower steps use the component's defaults. `sm` as a gap value means the small
|
|
105
|
+
gap; `sm` as an object key means a breakpoint.
|
|
106
|
+
|
|
107
|
+
| Step | Viewport minimum | Grid's nearest query-container minimum |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| `base` | All widths | All widths |
|
|
110
|
+
| `sm` | 40rem | 24rem |
|
|
111
|
+
| `md` | 48rem | 32rem |
|
|
112
|
+
| `lg` | 64rem | 40rem |
|
|
113
|
+
| `xl` | 80rem | 52rem |
|
|
114
|
+
| `2xl` | 96rem | 64rem |
|
|
115
|
+
|
|
116
|
+
Grid uses viewport steps when no ancestor establishes inline-size containment. With a query
|
|
117
|
+
container, such as PageViewport or ContentBlock, Grid's columns, gaps, alignment and maximum
|
|
118
|
+
width use the nearest container and the smaller thresholds above. Grid does not create its
|
|
119
|
+
own query container. Stack, Split, Bleed, AdaptiveGrid's responsive gap/alignment and
|
|
120
|
+
GridCell spans use viewport steps. AdaptiveGrid's **column count** always follows available
|
|
121
|
+
width through auto-fit. TwoColumnLayout stacks below the viewport's `lg` step.
|
|
122
|
+
|
|
123
|
+
Grid defaults to one column and two from `md`; `columns={1}` stays one at every width.
|
|
124
|
+
Use `GridCell span="full"` for a full row at every width. Numeric spans must fit the current
|
|
125
|
+
column count; `span={{ base: 1, md: "full", xl: 2 }}` can switch between numeric and full
|
|
126
|
+
placement. Coordinate responsive spans with the Grid, especially inside a query
|
|
127
|
+
container where their thresholds differ. Prefer AdaptiveGrid when the available panel width
|
|
128
|
+
should decide the count without coordinating breakpoints. Visual side positioning in Split
|
|
129
|
+
or TwoColumnLayout does not change reading or keyboard order.
|
|
130
|
+
|
|
131
|
+
## Bleed, custom CSS and verification
|
|
132
|
+
|
|
133
|
+
Bleed's default amount is `none` and its default axis is `inline`. An intentional image
|
|
134
|
+
escape can use `amount="default"` inside an inset of `--padding`, or `sm` inside
|
|
135
|
+
`--padding-sm`. The shipped spacing pairs have matching padding/gap values; a custom theme
|
|
136
|
+
that separates those values must account for the actual inset. Bleed does not create a
|
|
137
|
+
surface or crop media. Check edges and focus visibility in the surrounding surface.
|
|
138
|
+
|
|
139
|
+
Application-specific geometry can use `className` and CSS over public tokens; use the
|
|
140
|
+
documented props first. Do not target private `--_…` variables or CSS Module hashes. Keep
|
|
141
|
+
copy in Text/Heading and field labels in FormField rather than setting local type styles.
|
|
142
|
+
For product CSS, prefer logical properties so inline start/end follow RTL.
|
|
143
|
+
|
|
144
|
+
Check a narrow **parent** as well as a narrow viewport, long headings and translated labels,
|
|
145
|
+
both themes and densities, and keyboard access to the scroller. Verify that additional
|
|
146
|
+
surfaces or gaps serve an independent subject. [Consumer verification](verification.md)
|
|
147
|
+
separates compiled examples, interaction evidence and visual inspection.
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
The theme is about eighty variables, declared once at `:root` in `src/styles/theme/`. Each
|
|
4
4
|
colour holds both modes as `light-dark(light, dark)`, and every length, shadow, tint and
|
|
5
5
|
duration comes as a pair. Components derive everything else where they use it, so a value
|
|
6
|
-
you set
|
|
6
|
+
you set on a region reaches its descendants unless another scope or preset overrides it.
|
|
7
|
+
`src/styles/TOKENS.md` (`node_modules/themelia-ui/src/styles/TOKENS.md`)
|
|
7
8
|
names the variable for each role.
|
|
8
9
|
|
|
9
10
|
## Setting a theme
|
|
@@ -22,7 +23,8 @@ for both modes:
|
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
That one block reaches every region, including popups portalled to `<body>` and a dark
|
|
25
|
-
region inside a light page
|
|
26
|
+
region inside a light page. Component styles do not redeclare theme colour defaults;
|
|
27
|
+
an explicit regional theme override takes precedence within that region.
|
|
26
28
|
|
|
27
29
|
The same values work on any element, for a region of their own:
|
|
28
30
|
|
|
@@ -139,6 +141,8 @@ and headings fall back to the interface font.
|
|
|
139
141
|
Compose title and description regions with CardHeader, ContentBlock or OverlayHeader, action
|
|
140
142
|
regions with CardFooter or OverlayFooter, and label/value facts with MetadataList. These
|
|
141
143
|
components own their spacing, so the application does not reproduce it.
|
|
144
|
+
See [Structure and spacing](structure-and-spacing.md) for the owner and responsive-width
|
|
145
|
+
contracts before changing layout values.
|
|
142
146
|
|
|
143
147
|
## Scale and density
|
|
144
148
|
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Troubleshooting
|
|
2
2
|
|
|
3
|
+
Before patching a shared component, trace its callers and inspect one representative of
|
|
4
|
+
every affected surface. Recheck open portals, nested forms and small screens when shared
|
|
5
|
+
spacing or naming changes. Use the [read-only diagnosis and completion record](verification.md)
|
|
6
|
+
to distinguish contract errors, advisory composition findings and unavailable coverage.
|
|
7
|
+
|
|
8
|
+
## A lookup still shows another workspace
|
|
9
|
+
|
|
10
|
+
Set `scopeKey` on ResourceCombobox, SuggestionsCombobox or useSuggestions. Callback identity is not an invalidation API.
|
|
11
|
+
The key invalidates answers and errors while keeping query/open/value ownership; explicitly
|
|
12
|
+
clear a selected id if it is invalid in the new scope. See the [complete selector](reference-workflows.md).
|
|
13
|
+
|
|
14
|
+
## Validation resolves but the dialog closes
|
|
15
|
+
|
|
16
|
+
Set `closeOnAsyncComplete={false}` and close controlled `open` after successful validation
|
|
17
|
+
and mutation. Use `formId` for native submission and keep one mutation owner. Nested child
|
|
18
|
+
cancel/Escape should leave the parent draft visible; verify focus returns to the child invoker.
|
|
19
|
+
|
|
3
20
|
## A component is unstyled
|
|
4
21
|
|
|
5
22
|
A component brings its own CSS in a bundler. When it arrives unstyled:
|
|
@@ -74,8 +91,8 @@ listed there, report it as a package containment defect.
|
|
|
74
91
|
|
|
75
92
|
## A theme or density override does not apply
|
|
76
93
|
|
|
77
|
-
|
|
78
|
-
an override does not show:
|
|
94
|
+
Theme defaults are declared at `:root` and inherit until an explicit scope override or
|
|
95
|
+
density preset establishes another value. When an override does not show:
|
|
79
96
|
|
|
80
97
|
- **Is it the theme's name?** A 3.0 name such as `--space-md`, `--control-h` or
|
|
81
98
|
`--primary-10` is gone; the codemod renames or reports each one, and
|
|
@@ -121,6 +138,10 @@ set `disableStyleElements` and serve the documented Base UI behaviour rules from
|
|
|
121
138
|
stylesheet. The kit's stylesheets are ordinary static CSS. See
|
|
122
139
|
[Provider and scoping](provider-and-scoping.md#strict-content-security-policy).
|
|
123
140
|
|
|
141
|
+
If the report names `style-src-attr`, a nonce or `disableStyleElements` will not authorize
|
|
142
|
+
server-rendered style attributes. Inspect the adopted components' SSR output and use the
|
|
143
|
+
separate attribute-policy strategy described in that guide.
|
|
144
|
+
|
|
124
145
|
In a bundled app the kit's CSS follows your own pipeline: stylesheet files in production,
|
|
125
146
|
while a dev server or `style-loader` that injects `<style>` elements needs the nonce, as your
|
|
126
147
|
own CSS does.
|
|
@@ -128,11 +149,13 @@ own CSS does.
|
|
|
128
149
|
## The design looks inconsistent after overrides
|
|
129
150
|
|
|
130
151
|
Override global semantic tokens first: colour roles, radius, spacing and density,
|
|
131
|
-
typography, and control geometry.
|
|
132
|
-
|
|
152
|
+
typography, and control geometry. Variables prefixed `--_` are private implementation detail.
|
|
153
|
+
Use a component-level variable only when its module reference documents a public extension
|
|
154
|
+
point. Do not target hashed CSS
|
|
133
155
|
Module names; use the stable `data-slot` attributes and BEM hooks such as
|
|
134
156
|
`{name}--component`, and for a state the attributes the primitives set (`data-open`, `data-checked`, `data-disabled`,
|
|
135
|
-
`data-highlighted`, `data-popup-open`). Radix's `[data-state="open"]`
|
|
157
|
+
`data-highlighted`, `data-popup-open`). Do not assume Radix's `[data-state="open"]` for Base
|
|
158
|
+
UI primitives. Use a module's own `data-state` only when its API documents that contract.
|
|
136
159
|
|
|
137
160
|
## Rich text and untrusted HTML
|
|
138
161
|
|
|
@@ -32,8 +32,9 @@ test("global search returns focus after dismissal", async ({ page }) => {
|
|
|
32
32
|
Prefer role- and name-based assertions over CSS Module selectors. When a visual or state
|
|
33
33
|
assertion needs a DOM hook, use `data-slot`, documented BEM hooks, or the state attributes
|
|
34
34
|
the primitives set (`data-open`, `data-checked`, `data-disabled`, `data-highlighted`,
|
|
35
|
-
`data-popup-open`).
|
|
36
|
-
|
|
35
|
+
`data-popup-open`). Use Base UI's documented attributes for its primitive states rather
|
|
36
|
+
than assuming Radix's `[data-state="open"]`. Some kit modules expose their own `data-state`
|
|
37
|
+
contract; use it only where the selected API documents it.
|
|
37
38
|
|
|
38
39
|
## Theme contract check
|
|
39
40
|
|
|
@@ -41,6 +42,61 @@ Create one application fixture that changes primary colour, surface/background r
|
|
|
41
42
|
radius, density, and typography scale at a scope boundary. If a component ignores it, report
|
|
42
43
|
the module and token before adding a local patch: the package may be missing a derivation.
|
|
43
44
|
|
|
45
|
+
## Offline diagnosis and skill freshness
|
|
46
|
+
|
|
47
|
+
Run the commands from the package installed in this application:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
node node_modules/themelia-ui/scripts/consumer/install-skill.mjs --project=. --check --json
|
|
51
|
+
node node_modules/themelia-ui/scripts/consumer/diagnose.mjs --project=. --json src/
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Both checks are read-only. Diagnostics use the consumer's installed TypeScript parser and
|
|
55
|
+
the package's generated export/migration facts. Supply explicit paths. Unsupported formats,
|
|
56
|
+
parse failures, missing paths, metadata or parser produce exit 2 (incomplete); definite
|
|
57
|
+
contract errors produce exit 1; complete checks without errors produce exit 0. Advisory
|
|
58
|
+
composition/private-style warnings do not establish a defect. Excluded build/dependency
|
|
59
|
+
directories and symlinks are not followed. Reports name the checked and skipped rules/files.
|
|
60
|
+
|
|
61
|
+
Freshness reports expected and installed versions plus missing, stale, modified or unmanaged
|
|
62
|
+
copies. Review modifications before reinstalling a generated copy. The installer refuses local edits
|
|
63
|
+
until `--overwrite-modified` explicitly replaces reviewed generated content. Keep application policy
|
|
64
|
+
in a separate skill; an unmanaged same-name skill is preserved. Missing metadata requires
|
|
65
|
+
repairing the package installation or consulting the matching release, never inventing an API.
|
|
66
|
+
|
|
67
|
+
If an installed copy's manifest is missing or invalid, the installer repairs it automatically
|
|
68
|
+
only when its remaining files match the packaged content. Differing or extra files require
|
|
69
|
+
review and `--overwrite-modified`, just like edits to a copy with a valid manifest.
|
|
70
|
+
|
|
71
|
+
Replacements are staged before writes, and caught write failures restore backups. An abrupt
|
|
72
|
+
process termination can leave mixed versions across targets and sibling `.backup-*` or
|
|
73
|
+
`.installing-*` directories. Run `--check`, review those retained directories, preserve any
|
|
74
|
+
local policy, and reinstall the intended generated copies. A backup-cleanup error means the
|
|
75
|
+
new copies were installed; the error names the retained backup for review and manual cleanup.
|
|
76
|
+
|
|
77
|
+
The browser observer (`node_modules/themelia-ui/docs/build/browser-composition-fixture.ts`) accepts an already open caller
|
|
78
|
+
fixture and observes overflow, repeated sibling headings and control visibility. It performs
|
|
79
|
+
no navigation, click or submission. These geometry/semantic observations are advisory; they
|
|
80
|
+
do not establish accessibility or business acceptance. Optional browser tooling belongs in
|
|
81
|
+
the application's test dependencies, not the UI runtime.
|
|
82
|
+
|
|
83
|
+
Opt into interaction tests only against explicit mock actions. The [complete workflows](reference-workflows.md)
|
|
84
|
+
provide scoped late responses, pending/empty/error lists, nested cancel, resolved validation,
|
|
85
|
+
workspace selection and retained locale drafts. Assert keyboard selection without accidental
|
|
86
|
+
form submission, one Escape layer at a time, focus return, associated errors and explicit
|
|
87
|
+
successful completion. Do not crawl unknown application routes or submit business forms.
|
|
88
|
+
|
|
89
|
+
## Completion record
|
|
90
|
+
|
|
91
|
+
Record installed package/skill versions; selected owners and seams; shared callers inspected;
|
|
92
|
+
fixture routes and states; viewport widths; themes, densities and locales; keyboard/focus
|
|
93
|
+
interactions; commands and observed results. Separate type/build evidence, behavior tests,
|
|
94
|
+
visual inspection and application acceptance. Name unavailable conditions explicitly.
|
|
95
|
+
|
|
96
|
+
When no browser is available, report types/build/static findings and mark interaction and
|
|
97
|
+
visual checks unverified. Passing named static/browser checks does not establish permissions,
|
|
98
|
+
data integrity, persistence, backend sanitization or every product workflow.
|
|
99
|
+
|
|
44
100
|
## Upgrade check
|
|
45
101
|
|
|
46
102
|
Read the changelog (`node_modules/themelia-ui/CHANGELOG.md`), run the package's codemod when a release names one
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 3.2.0 — 2026-10-04
|
|
4
|
+
|
|
5
|
+
- Skill installation preserves edits when installed metadata is missing and keeps installed
|
|
6
|
+
copies intact if backup cleanup fails. Diagnostics check namespace accesses, escaped CSS
|
|
7
|
+
imports and private variables from core styles.
|
|
8
|
+
- Nested action success closes both layers; nested-action and media references use packaged
|
|
9
|
+
triggers to restore focus in Safari. Escape leaves a modal child in control when its parent
|
|
10
|
+
is nonmodal. Scope changes abort old lookups before committed layout callbacks.
|
|
11
|
+
- The media-picking reference commits replacement ids only after explicit confirmation.
|
|
12
|
+
- Responsive GridCell spans support `full` at individual breakpoints and restore numeric spans.
|
|
13
|
+
- Consumer guides cover structural owners, spacing, responsive widths and subject blocks;
|
|
14
|
+
framework guidance distinguishes ordinary SSR from React Server Components boundaries.
|
|
15
|
+
- Mobile workspace disclosure keeps navigation open until a same-app destination is selected.
|
|
16
|
+
- ResourceCombobox, SuggestionsCombobox and useSuggestions accept `scopeKey` to invalidate
|
|
17
|
+
asynchronous lookups while retaining controlled selection and query state.
|
|
18
|
+
- Open combobox lists guard Enter during loading, empty results and IME composition;
|
|
19
|
+
nested native dialogs preserve their parent's draft and focus on child dismissal.
|
|
20
|
+
- Nine complete public-API reference workflows cover record details, server collections,
|
|
21
|
+
forms, scoped lookups, nested actions, navigation, media, communications and rich content.
|
|
22
|
+
- Context-aware discovery, ownership guides and the generated consumer skill share those
|
|
23
|
+
sources. Skill checks report version and content drift; reinstalling local edits requires
|
|
24
|
+
explicit `--overwrite-modified`.
|
|
25
|
+
- The packaged read-only diagnostic command checks imports and stylesheet contracts,
|
|
26
|
+
reports conservative composition warnings and identifies incomplete analysis.
|
|
27
|
+
|
|
3
28
|
## 3.1.0 — 2026-09-28
|
|
4
29
|
|
|
5
30
|
This release renames and removes public API. Read
|
package/README.md
CHANGED
|
@@ -314,11 +314,14 @@ Guides:
|
|
|
314
314
|
- [Theming and Tailwind CSS v4](docs/learn/theming.md)
|
|
315
315
|
- [Provider and scoping](docs/learn/provider-and-scoping.md)
|
|
316
316
|
- [Composition](docs/learn/composition.md)
|
|
317
|
+
- [Structure, spacing and responsive widths](docs/learn/structure-and-spacing.md)
|
|
318
|
+
- [Choosing and composing blocks](docs/learn/blocks.md)
|
|
317
319
|
- [Framework wiring](docs/learn/framework-wiring.md)
|
|
318
320
|
- [Forms](docs/learn/forms.md)
|
|
319
321
|
- [Localization](docs/learn/i18n.md)
|
|
320
322
|
- [Troubleshooting](docs/learn/troubleshooting.md)
|
|
321
323
|
- [Verifying a consuming application](docs/learn/verification.md)
|
|
324
|
+
- [Complete reference workflows](docs/learn/reference-workflows.md)
|
|
322
325
|
|
|
323
326
|
Reference, generated from the source when the package is built. It ships in the package
|
|
324
327
|
under `node_modules/themelia-ui/docs`, and the links open the latest published copy:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./cx--CBrhWH0.js";
|
|
2
|
-
import { n as t, r as n } from "./overlay-
|
|
2
|
+
import { n as t, r as n } from "./overlay-BuQOl8aP.js";
|
|
3
3
|
import "react";
|
|
4
4
|
import { jsx as r } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/base/alert-dialog/alert-dialog.tsx
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as e, n as t, r as n, t as r } from "../alert-dialog-
|
|
1
|
+
import { i as e, n as t, r as n, t as r } from "../alert-dialog-Cg2HhuBe.js";
|
|
2
2
|
export { r as AlertDialogAction, t as AlertDialogCancel, n as AlertDialogContent, e as AlertDialogMedia };
|
package/dist/base/cards.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, i as n, n as r, o as i, r as a, s as o, t as s } from "../cards-
|
|
2
|
+
import { a as e, c as t, i as n, n as r, o as i, r as a, s as o, t as s } from "../cards-Ddhz43Bz.js";
|
|
3
3
|
export { n as Card, r as CardActionStrip, e as CardContent, i as CardFooter, o as CardHeader, a as CardPrimaryAction, s as CardSkeleton, t as defaultCardStrings };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { _ as e, a as t, b as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _, v, x as y, y as b } from "../choice-inputs-
|
|
2
|
+
import { _ as e, a as t, b as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _, v, x as y, y as b } from "../choice-inputs-NwRxvmZN.js";
|
|
3
3
|
export { t as CardCheckboxGroup, f as CardRadioGroup, y as Checkbox, c as ListRadioGroup, m as PillRadioGroup, b as Radio, n as RadioGroup, h as Select, r as SelectIconPrimitive, l as SelectPopupContent, _ as SelectPopupGroup, i as SelectPopupItem, a as SelectPopupLabel, p as SelectPopupSeparator, u as SelectRoot, s as SelectTriggerPrimitive, o as SelectValuePrimitive, v as Switch, g as SwitchCard, d as ToggleField, e as defaultSelectStrings };
|
package/dist/base/combobox.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { C as e, E as t, S as n, T as r, _ as i, a, b as o, c as s, d as c, f as l, g as u, h as d, i as f, l as p, m, n as h, o as g, p as _, r as v, s as y, t as b, u as x, v as S, w as C, x as w, y as T } from "../combobox-
|
|
2
|
+
import { C as e, E as t, S as n, T as r, _ as i, a, b as o, c as s, d as c, f as l, g as u, h as d, i as f, l as p, m, n as h, o as g, p as _, r as v, s as y, t as b, u as x, v as S, w as C, x as w, y as T } from "../combobox-519ubijc.js";
|
|
3
3
|
export { h as ComboboxArrow, v as ComboboxBackdrop, f as ComboboxChip, a as ComboboxChips, g as ComboboxChipsInput, y as ComboboxClear, s as ComboboxCollection, p as ComboboxEmpty, x as ComboboxGroup, c as ComboboxGroupLabel, l as ComboboxInput, _ as ComboboxInputTrigger, m as ComboboxItem, d as ComboboxItemIndicator, u as ComboboxList, i as ComboboxPopup, S as ComboboxPopupInput, T as ComboboxPortal, o as ComboboxPositioner, w as ComboboxRoot, n as ComboboxSeparator, e as ComboboxStatus, C as ComboboxTrigger, r as ComboboxValue, t as defaultComboboxStrings, b as useComboboxFilter };
|
package/dist/base/command.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../command-
|
|
2
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../command-JjApYFds.js";
|
|
3
3
|
export { c as Command, i as CommandDialog, o as CommandEmpty, n as CommandGroup, e as CommandInput, a as CommandItem, s as CommandList, t as CommandSeparator, r as CommandShortcut, l as defaultCommandStrings };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "../date-pickers-
|
|
2
|
+
import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p } from "../date-pickers-BwCwKIVM.js";
|
|
3
3
|
export { n as Calendar, p as DatePicker, f as DatePickerFooter, s as DatePickerHeader, u as MonthYearPicker, i as MultipleDatePicker, e as RangeDatePicker, c as SingleDatePicker, t as TimePicker, d as createRangePresets, r as defaultCalendarStrings, l as defaultDatePickerStrings, o as defaultRangePresetStrings, a as defaultTimePickerStrings };
|
package/dist/base/dialog.js
CHANGED
package/dist/base/display.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g, v as _ } from "../display-
|
|
2
|
+
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g, v as _ } from "../display-a7AoX_u7.js";
|
|
3
3
|
export { i as BooleanIndicator, o as Collapsible, a as CollapsibleContent, e as CollapsibleTrigger, c as ContentBlock, n as DateBlock, g as IconBadge, h as InlineStat, t as Kbd, d as KbdGroup, u as MetadataList, s as MetadataValue, m as PlaceholderPattern, l as ScrollArea, _ as Separator, r as VisuallyHidden, f as defaultBooleanIndicatorStrings, p as defaultMetadataListStrings };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "../forms-numeric-
|
|
2
|
+
import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "../forms-numeric-IwQ1ltNf.js";
|
|
3
3
|
export { n as CURRENCY_SYMBOLS, s as CoordinatesInput, m as CurrencyInput, g as DecimalInput, t as DimensionsInput, h as MoneyInput, c as PercentageInput, u as RoundingModeSelect, d as WeightInput, r as applyRounding, f as defaultCoordinatesInputStrings, l as defaultCurrencyInputStrings, o as defaultDecimalInputStrings, a as defaultDimensionsInputStrings, p as defaultRoundingModeStrings, e as defaultUnitInputStrings, i as formatDecimal };
|
package/dist/base/forms.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../forms-
|
|
2
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../forms-C0WeNPFF.js";
|
|
3
3
|
export { c as DirtyStateBanner, i as ErrorSummary, r as FieldGroup, o as FormActionsBar, l as FormField, n as FormSection, e as SubmitStateButton, a as defaultDirtyStateBannerStrings, s as defaultErrorSummaryStrings, t as defaultSubmitStateButtonStrings };
|
package/dist/base/item.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../item-
|
|
2
|
+
import { a as e, c as t, i as n, l as r, n as i, o as a, r as o, s, t as c, u as l } from "../item-M2pmpWXh.js";
|
|
3
3
|
export { c as Item, i as ItemActions, o as ItemContent, n as ItemDescription, e as ItemFooter, a as ItemGroup, s as ItemHeader, t as ItemMedia, r as ItemSeparator, l as ItemTitle };
|
package/dist/base/navigation.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "../navigation-
|
|
2
|
+
import { a as e, c as t, d as n, f as r, g as i, h as a, i as o, l as s, m as c, n as l, o as u, p as d, r as f, s as p, t as m, u as h } from "../navigation-Bgu7Vc0M.js";
|
|
3
3
|
export { s as Breadcrumbs, m as LanguageSwitcher, f as NavigationTabs, l as OverflowTabBar, u as PageHeading, p as Pagination, h as Tab, n as TabList, r as TabPanel, d as Tabs, c as defaultBreadcrumbsStrings, o as defaultNavigationTabsStrings, e as defaultOverflowTabBarStrings, a as defaultPaginationStrings, i as defaultTabListStrings, t as paginationRange };
|
package/dist/base/otp-input.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import "#core.css";
|
|
3
3
|
import { c as e } from "../typography-DmeR05Er.js";
|
|
4
4
|
import { t } from "../cx--CBrhWH0.js";
|
|
5
|
-
import { d as n } from "../display-
|
|
5
|
+
import { d as n } from "../display-a7AoX_u7.js";
|
|
6
6
|
import * as r from "react";
|
|
7
7
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
8
8
|
import { OTPField as o } from "@base-ui/react/otp-field";
|