@kerfjs/ui 5.0.0-beta.49 → 5.0.0-beta.50
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/README.md +41 -11
- package/ai/catalog-authoring.json +12 -1
- package/ai/catalog-authoring.schema.json +49 -1
- package/ai/compile-time-contracts-v1.json +14 -0
- package/ai/compile-time-contracts-v1.schema.json +1 -0
- package/ai/component-catalog-v2-overrides.json +7 -0
- package/ai/component-catalog-v2.json +79 -23
- package/ai/component-catalog.json +86 -27
- package/ai/public-api-signatures-v1.md +217 -169
- package/ai/skill.md +23 -9
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/app-tab.d.ts +3 -1
- package/dist/app-tab.js +1 -1
- package/dist/badge.d.ts +24 -0
- package/dist/badge.js +3 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/list-header.js +1 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +24 -125
- package/dist/catalog.js +387 -261
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-OGTJNHRG.js → chunk-2WMSE4MK.js} +5 -3
- package/dist/chunk-2WMSE4MK.js.map +1 -0
- package/dist/{chunk-GYGM363P.js → chunk-2YOUUEWR.js} +16 -6
- package/dist/chunk-2YOUUEWR.js.map +1 -0
- package/dist/{chunk-UDHHKZWO.js → chunk-3V75EQIP.js} +8 -4
- package/dist/chunk-3V75EQIP.js.map +1 -0
- package/dist/{chunk-W2FK7ZNY.js → chunk-4R777DUZ.js} +10 -2
- package/dist/chunk-4R777DUZ.js.map +1 -0
- package/dist/{chunk-T7DOWS6T.js → chunk-54HM36IQ.js} +6 -3
- package/dist/chunk-54HM36IQ.js.map +1 -0
- package/dist/{chunk-DAO2VFTT.js → chunk-5CE64WGC.js} +6 -4
- package/dist/chunk-5CE64WGC.js.map +1 -0
- package/dist/{chunk-SOK5EUF7.js → chunk-6ZXOQEAN.js} +4 -2
- package/dist/chunk-6ZXOQEAN.js.map +1 -0
- package/dist/{chunk-OGNE3OFT.js → chunk-AQSKJ6U6.js} +4 -2
- package/dist/chunk-AQSKJ6U6.js.map +1 -0
- package/dist/{chunk-VDUJZF5G.js → chunk-CMUIXJZM.js} +2 -2
- package/dist/{chunk-VDUJZF5G.js.map → chunk-CMUIXJZM.js.map} +1 -1
- package/dist/{chunk-OMSRSL3B.js → chunk-COUPLRZG.js} +5 -3
- package/dist/chunk-COUPLRZG.js.map +1 -0
- package/dist/{chunk-2TYUFZUC.js → chunk-D7GWXIAS.js} +4 -2
- package/dist/chunk-D7GWXIAS.js.map +1 -0
- package/dist/{chunk-AQFWBG23.js → chunk-DARTMI5Z.js} +5 -3
- package/dist/chunk-DARTMI5Z.js.map +1 -0
- package/dist/{chunk-V6GQKOX2.js → chunk-DJKWFYAA.js} +5 -3
- package/dist/chunk-DJKWFYAA.js.map +1 -0
- package/dist/{chunk-6NDBE2OK.js → chunk-E36EVCKG.js} +5 -3
- package/dist/chunk-E36EVCKG.js.map +1 -0
- package/dist/{chunk-IU4QUY5I.js → chunk-ELRMBQEC.js} +4 -2
- package/dist/chunk-ELRMBQEC.js.map +1 -0
- package/dist/{chunk-TIGSG6BX.js → chunk-HJKRCKDR.js} +7 -3
- package/dist/chunk-HJKRCKDR.js.map +1 -0
- package/dist/{chunk-Y6LYKFXY.js → chunk-HMQ2ZDGG.js} +5 -3
- package/dist/chunk-HMQ2ZDGG.js.map +1 -0
- package/dist/{chunk-WN52USHV.js → chunk-J3EE6XWD.js} +2 -2
- package/dist/{chunk-WN52USHV.js.map → chunk-J3EE6XWD.js.map} +1 -1
- package/dist/{chunk-CK6P5AUK.js → chunk-KKNK3JUT.js} +7 -4
- package/dist/chunk-KKNK3JUT.js.map +1 -0
- package/dist/{chunk-ZPWZIVI6.js → chunk-N3GKMPDW.js} +7 -3
- package/dist/chunk-N3GKMPDW.js.map +1 -0
- package/dist/{chunk-DYBPI5O2.js → chunk-NDUGJ4TU.js} +4 -2
- package/dist/chunk-NDUGJ4TU.js.map +1 -0
- package/dist/{chunk-WSXUPSID.js → chunk-NN6GYOA2.js} +7 -3
- package/dist/chunk-NN6GYOA2.js.map +1 -0
- package/dist/{chunk-VXFGMDA7.js → chunk-OQI7RCRP.js} +10 -2
- package/dist/chunk-OQI7RCRP.js.map +1 -0
- package/dist/{chunk-E34TE2ZI.js → chunk-S6ZTTTV7.js} +5 -3
- package/dist/chunk-S6ZTTTV7.js.map +1 -0
- package/dist/{chunk-V6HCTCVD.js → chunk-SIU2AC5W.js} +8 -4
- package/dist/chunk-SIU2AC5W.js.map +1 -0
- package/dist/{chunk-WVLMZ5SG.js → chunk-UMGY5JSP.js} +4 -2
- package/dist/chunk-UMGY5JSP.js.map +1 -0
- package/dist/{chunk-I4V3UDSA.js → chunk-V6RZWDII.js} +7 -5
- package/dist/chunk-V6RZWDII.js.map +1 -0
- package/dist/{chunk-CAB6NQ2T.js → chunk-VOCPXGQN.js} +3 -1
- package/dist/chunk-VOCPXGQN.js.map +1 -0
- package/dist/chunk-XD7DWYXG.js +34 -0
- package/dist/chunk-XD7DWYXG.js.map +1 -0
- package/dist/{chunk-B6JYRX3P.js → chunk-ZIYOJFZD.js} +43 -4
- package/dist/chunk-ZIYOJFZD.js.map +1 -0
- package/dist/{chunk-EYALJQQD.js → chunk-ZK5EGVFP.js} +4 -2
- package/dist/chunk-ZK5EGVFP.js.map +1 -0
- package/dist/{chunk-6WTETUZ6.js → chunk-ZLWQZUGF.js} +8 -2
- package/dist/chunk-ZLWQZUGF.js.map +1 -0
- package/dist/{chunk-XKFRMGMW.js → chunk-ZNZ2JDBW.js} +3 -1
- package/dist/chunk-ZNZ2JDBW.js.map +1 -0
- package/dist/{chunk-I45QO2IZ.js → chunk-ZSYLBVWG.js} +6 -4
- package/dist/chunk-ZSYLBVWG.js.map +1 -0
- package/dist/collapsible-panel.d.ts +3 -1
- package/dist/collapsible-panel.js +4 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/disclosure-arrow.d.ts +3 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/empty-state.d.ts +3 -1
- package/dist/empty-state.js +1 -1
- package/dist/floating-toolbar.d.ts +3 -1
- package/dist/floating-toolbar.js +1 -1
- package/dist/grid.d.ts +3 -1
- package/dist/grid.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +33 -32
- package/dist/list-action-row.d.ts +3 -1
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.d.ts +6 -1
- package/dist/list-header.js +2 -1
- package/dist/list-inset-control.d.ts +3 -1
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +3 -1
- package/dist/list-inset-text.js +1 -1
- package/dist/list-item.d.ts +3 -1
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +3 -1
- package/dist/list.js +1 -1
- package/dist/loading-spinner.d.ts +3 -1
- package/dist/loading-spinner.js +1 -1
- package/dist/lucide-icon.d.ts +3 -1
- package/dist/lucide-icon.js +1 -1
- package/dist/nav-stack.d.ts +3 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +3 -1
- package/dist/pane.js +1 -1
- package/dist/resizable-region.d.ts +5 -2
- package/dist/resizable-region.js +1 -1
- package/dist/row.d.ts +3 -1
- package/dist/row.js +1 -1
- package/dist/segmented-control.d.ts +3 -1
- package/dist/segmented-control.js +1 -1
- package/dist/select.d.ts +3 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.d.ts +3 -1
- package/dist/skeleton.js +1 -1
- package/dist/spacer.d.ts +3 -1
- package/dist/spacer.js +1 -1
- package/dist/split-view.d.ts +3 -1
- package/dist/split-view.js +24 -5
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +3 -1
- package/dist/state-banner.js +2 -1
- package/dist/styles/badge.css +86 -0
- package/dist/styles/catalog/components/catalog-detail.css +35 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +6 -0
- package/dist/styles/catalog/components/catalog-example.css +35 -0
- package/dist/styles/catalog/components/catalog-resource-footer.css +37 -0
- package/dist/styles/catalog/components/catalog-secondary-sections.css +38 -0
- package/dist/styles/catalog/components/catalog-section-list.css +22 -0
- package/dist/styles/catalog/components/catalog-sidebar.css +82 -0
- package/dist/styles/catalog/components/catalog-stage.css +60 -0
- package/dist/styles/catalog/components/catalog.css +22 -0
- package/dist/styles/catalog.css +10 -587
- package/dist/styles/list-header.css +4 -60
- package/dist/styles/resizable-region.css +24 -0
- package/dist/styles/select.css +0 -3
- package/dist/styles/split-view.css +1 -1
- package/dist/styles/state-banner.css +0 -27
- package/dist/styles/styles.css +1 -0
- package/dist/styles/tab-bar.css +6 -1
- package/dist/styles/text.css +4 -0
- package/dist/styles/token-search-field.css +5 -40
- package/dist/styles/toolbar-control-group.css +110 -16
- package/dist/styles/toolbar-text.css +4 -0
- package/dist/styles/toolbar.css +72 -0
- package/dist/styles/webawesome.css +22 -7
- package/dist/sunken-panel.d.ts +3 -1
- package/dist/sunken-panel.js +1 -1
- package/dist/surface-scaffold.d.ts +6 -2
- package/dist/surface-scaffold.js +1 -1
- package/dist/tab-bar.d.ts +8 -1
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +3 -1
- package/dist/tab-scaffold.js +3 -1
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/text.d.ts +5 -2
- package/dist/text.js +1 -1
- package/dist/token-search-field.d.ts +5 -1
- package/dist/token-search-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +33 -3
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +3 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +9 -1
- package/dist/toolbar.js +1 -1
- package/dist/types-CzgSrFXP.d.ts +64 -0
- package/dist/value-table.d.ts +6 -2
- package/dist/value-table.js +1 -1
- package/dist/wire-resizable-regions.js +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +3 -1
- package/dist/workbench.js +3 -1
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +11 -1
- package/docs/catalog.md +25 -7
- package/docs/component-contract.md +71 -22
- package/docs/component-selection.md +11 -9
- package/docs/design-philosophy.md +6 -5
- package/docs/recipes.md +5 -5
- package/docs/type-contracts.md +1 -0
- package/docs/ux-demo.md +4 -4
- package/docs/webawesome-theme.md +5 -4
- package/llms.txt +30 -10
- package/package.json +9 -2
- package/ux-demo/recipes/app-shell.css +87 -0
- package/ux-demo/recipes/app-shell.tsx +207 -178
- package/ux-demo/recipes/collapsible-sidebar.css +83 -0
- package/ux-demo/recipes/collapsible-sidebar.tsx +152 -122
- package/ux-demo/recipes/compact-toolbar.css +35 -0
- package/ux-demo/recipes/compact-toolbar.tsx +104 -100
- package/ux-demo/recipes/composer-form.css +19 -0
- package/ux-demo/recipes/composer-form.tsx +19 -15
- package/ux-demo/recipes/list-detail-dialog.css +42 -0
- package/ux-demo/recipes/list-detail-dialog.tsx +127 -125
- package/ux-demo/recipes/list-workspace-states.css +30 -0
- package/ux-demo/recipes/list-workspace-states.tsx +66 -60
- package/ux-demo/recipes/loading-inspector.css +7 -0
- package/ux-demo/recipes/loading-inspector.tsx +151 -131
- package/ux-demo/recipes/navigation-sidebar.css +12 -0
- package/ux-demo/recipes/navigation-sidebar.tsx +116 -105
- package/ux-demo/recipes/navigation-stack.css +12 -0
- package/ux-demo/recipes/navigation-stack.tsx +47 -37
- package/ux-demo/recipes/recipe-root.css +67 -0
- package/ux-demo/recipes/recipe-root.tsx +87 -0
- package/ux-demo/recipes/workspace-header.css +7 -0
- package/ux-demo/recipes/workspace-header.tsx +60 -61
- package/dist/chunk-2TYUFZUC.js.map +0 -1
- package/dist/chunk-6NDBE2OK.js.map +0 -1
- package/dist/chunk-6WTETUZ6.js.map +0 -1
- package/dist/chunk-AQFWBG23.js.map +0 -1
- package/dist/chunk-B6JYRX3P.js.map +0 -1
- package/dist/chunk-CAB6NQ2T.js.map +0 -1
- package/dist/chunk-CK6P5AUK.js.map +0 -1
- package/dist/chunk-DAO2VFTT.js.map +0 -1
- package/dist/chunk-DYBPI5O2.js.map +0 -1
- package/dist/chunk-E34TE2ZI.js.map +0 -1
- package/dist/chunk-EYALJQQD.js.map +0 -1
- package/dist/chunk-GYGM363P.js.map +0 -1
- package/dist/chunk-I45QO2IZ.js.map +0 -1
- package/dist/chunk-I4V3UDSA.js.map +0 -1
- package/dist/chunk-IU4QUY5I.js.map +0 -1
- package/dist/chunk-OGNE3OFT.js.map +0 -1
- package/dist/chunk-OGTJNHRG.js.map +0 -1
- package/dist/chunk-OMSRSL3B.js.map +0 -1
- package/dist/chunk-SOK5EUF7.js.map +0 -1
- package/dist/chunk-T7DOWS6T.js.map +0 -1
- package/dist/chunk-TIGSG6BX.js.map +0 -1
- package/dist/chunk-UDHHKZWO.js.map +0 -1
- package/dist/chunk-V6GQKOX2.js.map +0 -1
- package/dist/chunk-V6HCTCVD.js.map +0 -1
- package/dist/chunk-VXFGMDA7.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-WSXUPSID.js.map +0 -1
- package/dist/chunk-WVLMZ5SG.js.map +0 -1
- package/dist/chunk-XKFRMGMW.js.map +0 -1
- package/dist/chunk-Y6LYKFXY.js.map +0 -1
- package/dist/chunk-ZPWZIVI6.js.map +0 -1
- package/ux-demo/recipes/recipes.css +0 -453
|
@@ -7,7 +7,7 @@ decision procedure.
|
|
|
7
7
|
|
|
8
8
|
1. Search the [Kerf UX catalog](./ux-demo.md) and the supported Web Awesome set.
|
|
9
9
|
2. Reuse a primitive when its purpose, anatomy, state, and interaction match.
|
|
10
|
-
3. Compose primitives for recurring layout
|
|
10
|
+
3. Compose primitives for recurring layout through public props and tokens. Do not select one component from another component's stylesheet.
|
|
11
11
|
4. Add a thin application adapter for product copy, domain mapping, actions, routing, persistence, permissions, and transport.
|
|
12
12
|
5. Use custom markup only when the semantic contract differs. If the pattern recurs across products, open an upstream component or recipe request.
|
|
13
13
|
|
|
@@ -15,12 +15,13 @@ The application adapter is usually a plain function that maps domain state to
|
|
|
15
15
|
component props plus stable `data-action` values. It is not a fork of package
|
|
16
16
|
markup or CSS.
|
|
17
17
|
|
|
18
|
-
**Don't fight the components.** The package is built to look right
|
|
19
|
-
|
|
20
|
-
`border`, `background`, a wrapper card, or a decoration, check whether
|
|
21
|
-
component, the pane, or the content-item already owns it — it almost always
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
**Don't fight the components.** The package is built to look right without an
|
|
19
|
+
application customization layer. Before adding `padding`, `margin`, `width`,
|
|
20
|
+
`height`, `border`, `background`, a wrapper card, or a decoration, check whether
|
|
21
|
+
the component, the pane, or the content-item already owns it — it almost always
|
|
22
|
+
does. Express presentation through props and tokens. Encapsulate genuinely new
|
|
23
|
+
structure in a self-styled application component, and never reach into a nested
|
|
24
|
+
Kerf or Web Awesome component from that stylesheet. See
|
|
24
25
|
[`design-philosophy.md`](./design-philosophy.md) "Reach for the primitive, not for
|
|
25
26
|
CSS".
|
|
26
27
|
|
|
@@ -121,9 +122,10 @@ an upstream component or recipe request.
|
|
|
121
122
|
| Interface need | Use when | Do not use when; nearest alternative | Required wiring | Application owns | Import | Recipe |
|
|
122
123
|
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
123
124
|
| Icon — `LucideIcon` | A decorative or explicitly labeled Lucide-compatible icon belongs in app UI. | Do not use an icon as the only name of an unfamiliar action; add visible or accessible text. Prefer it over Web Awesome `wa-icon`. | None. | Icon choice and meaningful label. | `@kerfjs/ui/lucide-icon` | [Accessibility](./accessibility.md#shared-rules) |
|
|
125
|
+
| Compact metadata — `Badge` | A short status, count, category, or metadata label needs self-owned visual treatment configured by semantic props. | Do not use it as a button, link, or removable chip. Do not restyle consuming-component descendants to create a badge. | Choose `tone`, `appearance`, `shape`, and `size`; supply `label` for abbreviated content or `ariaHidden` when a surrounding component already owns the same accessible text. | Metadata text, semantic tone mapping, and abbreviated-content labeling. | `@kerfjs/ui/badge` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
124
126
|
| Disclosure indicator — `DisclosureArrow` | A control needs one animated 18px root-scaled visual for open and closed state, including configurable directions or a replacement icon. | Do not use it as the interactive control or accessible name; place it inside the button or control that exposes expanded state. | Pass the controlled `open` state, render it inside the owning control, author replacement icon content facing right before transforms, and override `--kui-disclosure-arrow-size` only when another visual size is required. Direction changes use the shortest rotation path, with counterclockwise chosen for a 180-degree closed-to-open tie. | Open state, interaction, accessible name, size override, replacement glyph, direction choices, and shortest-path rotation. | `@kerfjs/ui/disclosure-arrow` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
125
127
|
| Application toolbar or heading — `Toolbar` | Leading identity, optional centered content, and trailing controls form one horizontal app bar or a page/panel/dialog heading. | Do not add bespoke heading geometry or a private wrapper; use the same zone contract everywhere. | Put identity/title text directly in a zone as `ToolbarText`; group controls and icon tiles in `ToolbarControlGroup`. | Actions, command availability, responsive relocation, state, and supporting copy below a heading. | `@kerfjs/ui/toolbar` | [Toolbar composition](../README.md#component-subpaths) |
|
|
126
|
-
| Toolbar control cluster — `ToolbarControlGroup`
|
|
128
|
+
| Toolbar control cluster — `ToolbarControlGroup`, `ToolbarActionLink` | Related toolbar buttons, semantic links, compact/tight controls, avatar actions, or a dropdown trigger/menu surface need one configured chrome contract. | Do not use it merely to align unrelated controls. Do not restyle anchors or dropdown parts in application CSS; use `ToolbarActionLink`, `overflow`, and `menuInset`. Web Awesome `wa-button-group` is only for an exceptional grouped-action contract. | Delegate child actions; use `ToolbarActionLink` for native navigation, `overflow="scroll"` for bounded action rows, and `menuInset` for dropdown surface padding. Use `avatarImage` instead of inserting an `img`; use `SegmentedControl` for an exclusive choice. | Actions, destinations, pressed/expanded state, content, and policy. | `@kerfjs/ui/toolbar-control-group` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
127
129
|
| Floating controls over content — `FloatingToolbar` | A small cluster of controls (e.g. a drawer restore) must float over scrolling content — distinct and forced-dark — inside a positioned container. | Do not use it for a primary page or panel toolbar (use `Toolbar`), or for anything that must sit above dialogs/overlays — it is not top-layer. | Compose `ToolbarControlGroup`s and delegate their actions; the app owns visibility and position. | Controls, visibility, and position. | `@kerfjs/ui/floating-toolbar` | [Component subpaths](../README.md#component-subpaths) |
|
|
128
130
|
| Toolbar identity text — `ToolbarText` | A toolbar needs extra-large (page/panel title), large, default, or compact textual identity. | Plain text is not a heading by default; when a title needs heading semantics pass `headingLevel`. | Optional `headingLevel` for `role="heading"` + `aria-level`. Defaults to one line, ellipsized when it does not fit; `wrap` flows onto multiple lines, `ellipsis` toggles the trailing …, and `maxLines` caps a wrap. | Text, heading level, overflow behavior, and responsive priority. | `@kerfjs/ui/toolbar-text` | [Toolbar composition](../README.md#component-subpaths) |
|
|
129
131
|
| Semantic heading or paragraph — `Text` | Ordinary application copy needs native `h1`–`h6` or `p` semantics plus standard geometry, or a semantic quiet/danger tone, compact size, or monospace font. | Do not choose heading levels for appearance alone or recreate muted, error, small, or code utility classes. Use `ToolbarText` for toolbar identity/title content and `ListInsetText` when list-aligned prose needs full margin/border/padding geometry. | Omit `variant` for the default `p`, or choose `h1`–`h6` from the document outline. Independently compose `tone="quiet | danger"`, `size="compact"`, and `font="monospace"`; ordinary native global, `data-_`, and `aria-_` attributes pass through. | Copy, localization, semantic variant, presentation roles, and document heading hierarchy. | `@kerfjs/ui/text` | [Text](./layout.md#text) |
|
|
@@ -144,7 +146,7 @@ an upstream component or recipe request.
|
|
|
144
146
|
| Menu composition | Navigation sections need full-size rows and the same content-item geometry as every other pane. | Do not add sidebar-specific wrapper padding, shrink targets to icon size, nest an interactive trailing control in `ListItem`, or use a chevron on a row that does not disclose content. Use ordinary links for a different navigation contract. | Compose `ListHeader`, `ListItem`, and `ListActionRow` in `.kui-content`; use `ListHeader` toggle mode with real controlled content, and use `.kui-content-item` for other surfaces plus a pane footer for toolbar actions. | Information architecture, disclosure content and state, responsive drawer/shell behavior, and token overrides. | `@kerfjs/ui/layout.css` | [Pane geometry](../README.md#pane-and-content-geometry) |
|
|
145
147
|
| Resizable application pane — `ResizableRegion`, `clampRegionSize`, `resizeRegionFromPointer` | A controlled split pane needs the Kerf separator, collapse state, pointer plus keyboard resizing, or a product-specific decorative grip. | Do not use it for static equal columns; use `Grid`. Use application CSS grid for static asymmetric or intrinsic tracks. Prefer it over Web Awesome `wa-split-panel` unless that component's distinct API is required. Keep `handleIcon` noninteractive. | Call `wireResizableRegions` from `@kerfjs/ui/wire-resizable-regions` once and retain its disposer. | Size signal, min/max policy, collapse policy, persistence, and optional decorative handle icon. | `@kerfjs/ui/resizable-region` | [ResizableRegion contract](./accessibility.md#resizableregion) |
|
|
146
148
|
| One application tab — `AppTab` | A controlled app tab needs selection, close, drag, leading/trailing anatomy, compact/segmented/icon-only presentation, label truncation, safe domain metadata, or a product-specific close glyph. | Do not render it alone or use it for a small settings choice; compose in `TabBar`, or use `SegmentedControl`. Keep `closeIcon` noninteractive. | Compose in `TabBar`; let `wireTabBars` manage interaction. Put only domain `data-*` values in `rootAttributes`; use typed appearance props instead of descendant CSS. | Tab identity, order, selection, close policy, content, domain metadata values, and outer placement. | `@kerfjs/ui/app-tab` | [Tabs contract](./accessibility.md#tabs) |
|
|
147
|
-
| Application tab strip — `TabBar`, `wireTabBars`, `reorderTabs` | Tabs switch page regions and may overflow, close, reorder, fill a segmented inspector strip,
|
|
149
|
+
| Application tab strip — `TabBar`, `wireTabBars`, `reorderTabs` | Tabs switch page regions and may overflow, close, reorder, fill a segmented inspector strip, sit beside a trailing action, or keep that adjacent action distinct from a far-edge end action. | Do not use it for a compact local view toggle; use `SegmentedControl`. Do not use it for a long choice list; use `Select`. Prefer it over Web Awesome `wa-tab-group`, `wa-tab`, and `wa-tab-panel` for Kerf app tabs. | Call `wireTabBars` once, retain the disposer, and apply `onReorder` synchronously; `reorderTabs` is the default array helper. Combine `trailingPlacement="adjacent"` with `end` for split actions; TabBar owns the shrinking/scrolling tab geometry and keeps both actions visible. Choose typed presentation/allocation props while the parent owns outer placement. | Ordered tabs, selection, panels, routing, closing, persistence, action content, and outer placement. | `@kerfjs/ui/tab-bar` plus `@kerfjs/ui/wire-tab-bars` | [Tabs contract](./accessibility.md#tabs) |
|
|
148
150
|
| Panel, dialog, or page heading — `Toolbar` + `ToolbarText` | A panel, dialog, or page needs an extra-large title, optional icon, grouped trailing actions, and optional supporting copy. | Do not add a private heading wrapper or bespoke layout. The toolbar supplies structure, not modal behavior; use an application overlay or Web Awesome `wa-dialog` for that behavior. | Connect title/supporting-copy ids to the host, group controls, and delegate actions. **For a page or view title set `headingLevel` (usually `1`)** on `ToolbarText`; omit it for a dialog title referenced by `aria-labelledby`. | Open state, focus lifecycle, dismissal, controls, ids, copy, and heading level. | `@kerfjs/ui/toolbar` + `@kerfjs/ui/toolbar-text` | [Toolbar headings](./accessibility.md#toolbar-headings) |
|
|
149
151
|
| Dialog or popup geometry — `DialogSurface`, `PopupSurface` | Recurring Web Awesome dialogs need standard sizes/presentations/body/footer insets, or dropdown menus need list-compatible inset ownership. | Do not use these wrappers as generic layout or to replace native dialog/dropdown behavior. Avoid consumer `::part()` overrides and do not stack a dialog body inset around list-owned child geometry. | Wrap one `wa-dialog` or `wa-dropdown`; choose the typed geometry while retaining native labeling, open state, focus, dismissal, and menu semantics. Compose a dialog body as a `List` by default, use `bodyInset="none"` when its children own list geometry, and wrap bare prose in `ListInsetText`. | State, focus lifecycle, dismissal, labels, content, and outer placement. | `@kerfjs/ui/surface-scaffold` | [Surface scaffolds](./surface-scaffold.md) |
|
|
150
152
|
| Key/value facts — `ValueTable`, `ValueTableRow` | Read-only labels and values form a semantic definition list, optionally with a leading icon. | Do not use it for editable form fields or a row/column data grid; use native form or table semantics. | Compose typed `ValueTableRow` entries; pass `icon` when a 24px leading icon adds useful context. | Values, formatting, icon meaning, and empty/loading policy. | `@kerfjs/ui/value-table` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
@@ -28,16 +28,17 @@ Establish one reading order and one dominant action per decision point. Group fi
|
|
|
28
28
|
|
|
29
29
|
The package is designed to look right _unstyled_. A screen built from the
|
|
30
30
|
primitives, their props, and the semantic tokens should already read well, so
|
|
31
|
-
|
|
31
|
+
applications do not carry a component-customization stylesheet. Before adding any `padding`, `margin`, `width`,
|
|
32
32
|
`height`, `border`, `background`, wrapper card, or decoration, check whether the
|
|
33
33
|
component, the pane, or the content-item already owns it — it almost always does,
|
|
34
34
|
and adding more usually **double-insets** or fights the component (the most common
|
|
35
35
|
mistake). Trust component defaults: render a control at its natural size and color
|
|
36
36
|
and fix the surrounding layout rather than overriding the control. Legitimate
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
never build a heading, toolbar, card,
|
|
37
|
+
CSS for genuinely new structure belongs to the application-owned component that
|
|
38
|
+
renders that structure. It must not select a nested Kerf or Web Awesome component;
|
|
39
|
+
configure those children through props and documented tokens instead. Never size,
|
|
40
|
+
space, or re-skin a primitive by hand, and never build a heading, toolbar, card,
|
|
41
|
+
or pane geometry that a primitive provides.
|
|
41
42
|
|
|
42
43
|
### Panes share one child-owned geometry
|
|
43
44
|
|
package/docs/recipes.md
CHANGED
|
@@ -28,7 +28,7 @@ specific dispatch; either way, wire once at a stable root and retain disposal.
|
|
|
28
28
|
|
|
29
29
|
## Desktop application shell
|
|
30
30
|
|
|
31
|
-
[Open the recipe](../ux-demo/?component=recipe-app-shell) · [TSX source](../ux-demo/recipes/app-shell.tsx) · [shared CSS](../ux-demo/recipes/
|
|
31
|
+
[Open the recipe](../ux-demo/?component=recipe-app-shell) · [TSX source](../ux-demo/recipes/app-shell.tsx) · [shared composition CSS](../ux-demo/recipes/recipe-components.css)
|
|
32
32
|
|
|
33
33
|
Use `Toolbar`, controlled `ResizableRegion` panes, and one
|
|
34
34
|
`.kui-pane__content` scroll owner per pane. The recipe owns the shell topology;
|
|
@@ -164,9 +164,9 @@ Chromium, Firefox, and WebKit by `tests/browser/collapsible-sidebar-recipe.spec.
|
|
|
164
164
|
- For direct `wa-*` JSX, import types from `@kerfjs/ui/webawesome`. Import only
|
|
165
165
|
individual Web Awesome registration modules and theme them with
|
|
166
166
|
`@kerfjs/ui/webawesome.css`.
|
|
167
|
-
- Prefer public props and variables at the composition boundary.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
- Prefer public props and variables at the composition boundary. A recipe's own
|
|
168
|
+
component may style the structure it renders, but its stylesheet must not
|
|
169
|
+
select nested Kerf or Web Awesome components. Add missing configuration to the
|
|
170
|
+
owning component instead of copying markup or reaching through its boundary.
|
|
171
171
|
- Start from the copyable mount adapter, or reproduce its complete boundary:
|
|
172
172
|
wire stable `data-action` hooks once and retain every disposer.
|
package/docs/type-contracts.md
CHANGED
|
@@ -26,6 +26,7 @@ public-signature artifact.
|
|
|
26
26
|
| `KUI-T011` | Semantic component zones use the recursive `KerfUiContent` type: `SafeHtml`, runtime-empty booleans/nullish values, and readonly nested arrays are valid; arbitrary strings, numbers, and signals are rejected. Explicit text positions such as `ListInsetText` retain their text exception. |
|
|
27
27
|
| `KUI-T012` | `List.gap` accepts finite `UiSpaceName` shorthands or a complete branded `CssLength`; raw strings and non-standalone `CssLengthExpression` arithmetic are rejected. `calc(plus(...))` promotes a typed expression to a complete value. |
|
|
28
28
|
| `KUI-T013` | CSS-valued props preserve property grammar: `List.flex` uses `CssFlex`, `Skeleton` dimensions use `CssSize`/`CssLength`, and choice icons use `CssColor`; row declaration strings are absent. |
|
|
29
|
+
| `KUI-T014` | Stable single-root visual components accept the explicit native `slot` attribute. Multi-root `ResizableRegion` and `CollapsiblePanel` remain excluded because no single returned element can own the assignment, and other arbitrary native attributes remain rejected. |
|
|
29
30
|
|
|
30
31
|
`KerfUiContent` lets conditionals and mapped component collections be direct
|
|
31
32
|
siblings without an otherwise-unnecessary `Fragment`:
|
package/docs/ux-demo.md
CHANGED
|
@@ -12,18 +12,18 @@ of the current `src/` and `ux-demo/` inputs, so a stale `dist-demo` cannot pass
|
|
|
12
12
|
after a route or component edit. `npm run demo:serve` remains a preview-only
|
|
13
13
|
command for an already-built catalog.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Ten lazy production-composition routes live under the `Recipes` category.
|
|
16
16
|
Each `?component=recipe-*` route uses public package primitives, real wiring,
|
|
17
17
|
deterministic state, and semantic layout owners from the [recipe guide](./recipes.md).
|
|
18
18
|
|
|
19
19
|
- It imports public component subpaths, exercising their browser-selected reachable CSS rather than a catalog-only style path.
|
|
20
20
|
- The `ListActionRow` route demonstrates sibling primary/trailing native controls, independent disabled states, controlled selection, first-line leading-icon alignment for wrapped labels, and an application-owned native popover relationship without nesting controls. The `ListItem` route demonstrates the same multiline leading-icon anchor alongside its single-control navigation contract.
|
|
21
|
-
- The `AppTab` and `TabBar` routes are focused component specimens: AppTab shows its selected, compact, segmented, icon-only, truncation, placeholder, metadata, and close-icon axes inside the required tablist context; TabBar shows its rail, segmented, inspector, allocation, placement, and accessory-zone axes without application readouts. The separate `Application tabs composition
|
|
21
|
+
- The `AppTab` and `TabBar` routes are focused component specimens: AppTab shows its selected, compact, segmented, icon-only, truncation, placeholder, metadata, and close-icon axes inside the required tablist context; TabBar shows its rail, segmented, inspector, allocation, placement, and accessory-zone axes, including an adjacent action plus a separately pinned end action whose tabs overflow at narrow widths, without application readouts. The separate `Application tabs` composition route demonstrates controlled selection, matching panel content, overflow, adding, closing, keyboard/pointer reordering, and application-owned ordering. The `ResizableRegion` route likewise replaces only the decorative handle glyph while retaining separator semantics and shared wiring.
|
|
22
22
|
- Every first-party visual component and every free Web Awesome 3.12 component has its own stable `?component=<id>` URL and focused demo. Composite header, menu, and feedback scenarios remain addressable alongside their subcomponents; the root opens the first Kerf component. The former aggregate Web Awesome theme specimen is intentionally omitted because its component families are covered by those focused routes.
|
|
23
|
-
- `ai/component-catalog.json` is the canonical catalog metadata. A deterministic checked-in projection supplies the demo's unique id, category, kind (`component`, `composition`, or `recipe`), source (`kerf` or `webawesome`), name, description, recommendation, direct `uses` dependencies, existing documentation path, and demo-source path; first-party, recipe, and Web Awesome renderer maps are exhaustively typed against its generated id unions. Non-supported Web Awesome recommendations project to a visible `Discouraged`
|
|
23
|
+
- `ai/component-catalog.json` is the canonical catalog metadata. A deterministic checked-in projection supplies the demo's unique id, category, kind (`component`, `composition`, or `recipe`), source (`kerf` or `webawesome`), name, description, recommendation, direct `uses` dependencies, existing documentation path, and demo-source path; first-party, recipe, and Web Awesome renderer maps are exhaustively typed against its generated id unions. Functional groups follow their authored importance order; components precede compositions inside each group, equal-importance entries use alphabetical order, and the Recipes group comes last. Composition names stay concise and project a visible `Composition` sidebar tag. Non-supported Web Awesome recommendations project to a visible `Discouraged` tag, with Popup as the deliberate conditional exception. Demo paths resolve to the matching `ui/ux-demo/demos/<id>.tsx` or `ui/ux-demo/recipes/*.tsx` file, or to `ui/ux-demo/webawesome-demos.tsx` for Web Awesome entries. `ui/ux-demo/main.tsx` owns only the catalog shell, shared state, routing, and interaction wiring. First-party component entries additionally derive `ui/src/<public-subpath>.tsx` from their canonical `delivery.browserImport` or opt-in `delivery.moduleImport`.
|
|
24
24
|
- Every detail footer groups compact `Demo source` and `Guidance` actions; first-party component details also expose `Component source`. Web Awesome details say `Integration guidance` to distinguish the local integration contract from the upstream component implementation. Each button retains its repository-relative path in the DOM for verification and uses a deploy-safe absolute GitHub blob URL with a contextual new-tab name; the demo does not depend on a local source server or add a package runtime export. At phone widths, the resource group and related-component selector stack as full-width rows, with any resource overflow contained locally so labels cannot overlap the selector or widen the document.
|
|
25
25
|
- The master/detail shell groups first-party routes by category with production `ListHeader` and `ListItem` components. Catalog entries can supply short reusable trailing tags; the Web Awesome projection uses them to label exactly the 15 discouraged choices. The 70 ecosystem components live in a separate `Web Awesome` disclosure with seven subgroups, so they remain discoverable without being presented as first-class `@kerfjs/ui` exports. Direct Web Awesome routes open the disclosure and reveal the selected row at wide sizes; narrow layouts keep the expanded list in document flow rather than introducing a competing nested scroller.
|
|
26
|
-
- The shell itself uses `@kerfjs/ui/layout.css`: sidebars, details, previews, dialogs, and resize specimens share unpadded panes plus self-contained content items. Its sidebar identity uses the Kerf logo beside a vertically centered title, with supporting copy in its own aligned row; the current-view heading is also a toolbar. Collapsing the catalog removes the pane completely and moves its restore action to the main toolbar's leading edge instead of leaving an icon-only rail. The selected view description remains inset below the page toolbar. The checkerboard belongs to the
|
|
26
|
+
- The shell itself uses `@kerfjs/ui/layout.css`: sidebars, details, previews, dialogs, and resize specimens share unpadded panes plus self-contained content items. Its sidebar identity uses the Kerf logo beside a vertically centered title, with supporting copy in its own aligned row; the current-view heading is also a toolbar. Collapsing the catalog removes the pane completely and moves its restore action to the main toolbar's leading edge instead of leaving an icon-only rail. The selected view description remains inset below the page toolbar. The checkerboard belongs to the preview scroll owner rather than a viewport-height stage or nested card, and one explicitly repeated SVG tile keeps the pattern continuous through below-fold content. A lightly separated footer keeps live status above compact source, guidance, and relationship groups. The focused `ResizableRegion` specimen stretches its surface through the available stage height and reports committed width in that shared status footer; narrow layouts retain local horizontal access when the pane is resized wider than the stage, and the split remains readable at 200% root scaling. Geometry coverage checks wide, intermediate, narrow, and 200% zoom layouts.
|
|
27
27
|
- The composer-form recipe demonstrates one coherent visible form surface with toolbar title/supporting-copy hierarchy, fields and actions on the shared 8px control gutter, and 24px major rhythm. Its conditional error or success `StateBanner` is the only nested semantic surface. Reset synchronizes the upgraded Web Awesome fields' live value properties with their empty controlled attributes and announces `Draft reset`; browser coverage preserves behavior and verifies wide, narrow, dark, validation, success, reset, 200% zoom, and forced-colors states.
|
|
28
28
|
- The list-detail dialog recipe places its header directly on the dialog edge while preserving the header's internal inset, gives the selected project title the complete outer-plus-inner content gutter, lets the value table fill the available detail column between the shared outer margins, and keeps record actions on one outer gutter without an extra content-item inset. Browser geometry coverage protects those relationships at wide and narrow widths.
|
|
29
29
|
- Catalog-only brand marks, preview dimensions, checkerboard tiles, and the compound display-settings control retain local geometry because they are specimen chrome or intrinsic control anatomy rather than reusable application spacing roles.
|
package/docs/webawesome-theme.md
CHANGED
|
@@ -97,10 +97,11 @@ tiers:
|
|
|
97
97
|
complete surface and the inset within it. Accordion applies the outer margin
|
|
98
98
|
once to the group rather than separating connected items; Card's header,
|
|
99
99
|
body, and footer all receive the full inset.
|
|
100
|
-
- Plain
|
|
101
|
-
|
|
102
|
-
sunken
|
|
103
|
-
|
|
100
|
+
- Plain Details use the 8px `--kui-wa-surface-inset` on the trigger and keep the
|
|
101
|
+
body flush; plain Accordion items use that 8px inset on both trigger and body.
|
|
102
|
+
Outlined and sunken Details use the 16px `--kui-wa-container-inset` on the
|
|
103
|
+
trigger and the 8px surface inset on the body, while framed Accordion items
|
|
104
|
+
use the 16px container inset for both regions.
|
|
104
105
|
- `appearance="sunken"` is a Kerf theme extension for Accordion, Card, and
|
|
105
106
|
Details. It removes raised chrome, paints the lowered semantic surface, and
|
|
106
107
|
uses the shared rounded-rectangle radius. Override
|
package/llms.txt
CHANGED
|
@@ -12,6 +12,10 @@ npm install kerfjs @kerfjs/ui # kerfjs is a peer; Web Awesome is an optional pee
|
|
|
12
12
|
Import each component from its own subpath (`@kerfjs/ui/list-item`, `@kerfjs/ui/toolbar`,
|
|
13
13
|
…); the browser build pulls that component's reachable CSS automatically, so do not
|
|
14
14
|
maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
15
|
+
For a public subpath containing several visual components, use a folder with one
|
|
16
|
+
component per source file and one owned stylesheet per visual component. Keep its
|
|
17
|
+
compatibility entrypoints implementation-free: JavaScript/TypeScript only re-exports
|
|
18
|
+
the folder modules, and CSS only imports their owner stylesheets.
|
|
15
19
|
|
|
16
20
|
## How to build a screen (retrieval order)
|
|
17
21
|
|
|
@@ -56,9 +60,17 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
56
60
|
`ListInsetText`. These are typed props, not native `<slot>` elements,
|
|
57
61
|
wrapper slot components, or a generic `slots` object. Leave unresolved
|
|
58
62
|
dynamic expressions unknown.
|
|
63
|
+
Stable single-root Kerf UI components separately accept the explicit native
|
|
64
|
+
`slot="name"` prop for light-DOM composition inside a custom element and
|
|
65
|
+
preserve it across rerenders. Do not infer arbitrary native-attribute
|
|
66
|
+
spreading from this narrow interop contract. `ResizableRegion` and
|
|
67
|
+
`CollapsiblePanel` remain excluded because their optional restore controls
|
|
68
|
+
make their output multi-root; `CollapsiblePanelToggle` remains slot-capable.
|
|
59
69
|
4. **When authoring a component gallery**, load
|
|
60
70
|
[catalog-authoring.json](./ai/catalog-authoring.json), then follow its
|
|
61
71
|
authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract).
|
|
72
|
+
Use its component/composition/recipe taxonomy and functional-group,
|
|
73
|
+
importance, alphabetical-tie, and recipes-last ordering policy.
|
|
62
74
|
5. **Apply the rules below and in** [skill.md](./ai/skill.md).
|
|
63
75
|
6. **Before calling an integration complete**, run
|
|
64
76
|
[`kerf-ui-doctor`](./docs/ui-doctor.md). Its portable JSON report merges
|
|
@@ -81,12 +93,12 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
81
93
|
## Core rules (do the right thing)
|
|
82
94
|
|
|
83
95
|
- **Reach for the primitive, not for CSS.** The package is built to look right
|
|
84
|
-
|
|
85
|
-
`background`, a wrapper card, or a decoration,
|
|
86
|
-
pane, or
|
|
87
|
-
component prop or
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
without an application customization layer. Before adding `padding`, `margin`,
|
|
97
|
+
`width`, `height`, `border`, `background`, a wrapper card, or a decoration,
|
|
98
|
+
check whether the component, pane, or content-item already owns it. Prefer a
|
|
99
|
+
component prop or documented `--kui-*` token. CSS for genuinely new structure
|
|
100
|
+
belongs to the application-owned component that renders it and must not select
|
|
101
|
+
nested Kerf or Web Awesome components.
|
|
90
102
|
- **Never double-inset.** A `.kui-pane` has no padding; its `.kui-content` children
|
|
91
103
|
own the geometry (8px inline margin + 1px border + 8px padding). Do not add a
|
|
92
104
|
container padding on top of a content-item's own margin — pick one owner. Use
|
|
@@ -116,8 +128,9 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
116
128
|
`--kui-wa-control-inset` (8px controls/items) and
|
|
117
129
|
`--kui-wa-surface-margin` / `--kui-wa-surface-inset` (8px around/inside
|
|
118
130
|
Accordion, Card, Details, Callout, and Include), while
|
|
119
|
-
plain
|
|
120
|
-
|
|
131
|
+
plain Details keep their body flush while plain Accordion items inset both
|
|
132
|
+
trigger and body, framed Details use the 16px container inset only on the
|
|
133
|
+
trigger, and framed Accordion items use it on both regions;
|
|
121
134
|
`--kui-wa-container-inset` keeps Tab Panel at 16px. Dialog body and footer use
|
|
122
135
|
the surface (8px) and container (16px) tiers respectively, independent of the
|
|
123
136
|
dialog's shared `--spacing`. Override the tier at the narrowest useful scope
|
|
@@ -207,7 +220,11 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
207
220
|
overflow autoscroll, drag preview, and
|
|
208
221
|
replacement focus after controlled automatic tab activation,
|
|
209
222
|
`wireResizableRegions` the live drag preview; they report committed changes via
|
|
210
|
-
callbacks.
|
|
223
|
+
callbacks. For a tab-local action plus a separate far-edge action, set
|
|
224
|
+
`TabBar trailingPlacement="adjacent"`, put the local action in `trailing`, and
|
|
225
|
+
the workspace action in `end`; the component keeps both visible while its tab
|
|
226
|
+
list shrinks and scrolls, without application descendant CSS. Managed
|
|
227
|
+
TokenSearchField clear also preserves open state and replacement
|
|
211
228
|
editor focus before the next input task, so shortcut-letter typing stays in search.
|
|
212
229
|
Select All deletion does the same; deletion
|
|
213
230
|
restoration finishes before the next keystroke rather than on a delayed frame.
|
|
@@ -244,10 +261,13 @@ maintain a central style list. Configure JSX with `"jsxImportSource": "kerfjs"`.
|
|
|
244
261
|
optional string `badge` for a terse count or status beside the title. It
|
|
245
262
|
inherits the banner tone and is announced with the banner, so keep its text
|
|
246
263
|
meaningful and never rely on color alone.
|
|
264
|
+
- **Use `Badge` for compact non-interactive metadata.** Configure its semantic
|
|
265
|
+
tone, appearance, shape, and size instead of creating badge CSS in an app or
|
|
266
|
+
consuming component. Use a real button or link for interactive content.
|
|
247
267
|
|
|
248
268
|
## Public exports
|
|
249
269
|
|
|
250
|
-
`LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `FloatingToolbar`, `ToolbarText`, `Text`,
|
|
270
|
+
`Badge`, `LucideIcon`, `DisclosureArrow`, `Toolbar`, `ToolbarControlGroup`, `ToolbarActionLink`, `FloatingToolbar`, `ToolbarText`, `Text`,
|
|
251
271
|
`ListItem`, `ListActionRow`, `ListHeader`, `ListInsetControl`,
|
|
252
272
|
`ListInsetText`, `SegmentedControl`,
|
|
253
273
|
`Select`, `TokenSearchField` (+ `readTokenSearchField`, `placeTokenSearchCaret`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kerfjs/ui",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.50",
|
|
4
4
|
"description": "Accessible, composable UI primitives for kerf applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,6 +58,11 @@
|
|
|
58
58
|
"browser": "./dist/browser/disclosure-arrow.js",
|
|
59
59
|
"import": "./dist/disclosure-arrow.js"
|
|
60
60
|
},
|
|
61
|
+
"./badge": {
|
|
62
|
+
"types": "./dist/badge.d.ts",
|
|
63
|
+
"browser": "./dist/browser/badge.js",
|
|
64
|
+
"import": "./dist/badge.js"
|
|
65
|
+
},
|
|
61
66
|
"./toolbar": {
|
|
62
67
|
"types": "./dist/toolbar.d.ts",
|
|
63
68
|
"browser": "./dist/browser/toolbar.js",
|
|
@@ -291,6 +296,7 @@
|
|
|
291
296
|
"./webawesome.css": "./dist/styles/webawesome.css",
|
|
292
297
|
"./styles.css": "./dist/styles/styles.css",
|
|
293
298
|
"./lucide-icon.css": "./dist/styles/lucide-icon.css",
|
|
299
|
+
"./badge.css": "./dist/styles/badge.css",
|
|
294
300
|
"./disclosure-arrow.css": "./dist/styles/disclosure-arrow.css",
|
|
295
301
|
"./toolbar.css": "./dist/styles/toolbar.css",
|
|
296
302
|
"./toolbar-control-group.css": "./dist/styles/toolbar-control-group.css",
|
|
@@ -360,6 +366,7 @@
|
|
|
360
366
|
"check:profile": "node scripts/check-application-ui-profile.mjs",
|
|
361
367
|
"check:demo-conformance": "node scripts/check-catalog-demo-conformance.mjs",
|
|
362
368
|
"check:recipes": "node scripts/check-recipes.mjs",
|
|
369
|
+
"check:css-ownership": "node scripts/check-css-ownership.mjs",
|
|
363
370
|
"check:ai-regressions": "node scripts/check-ai-regressions.mjs && node scripts/audit-ai-regression-results.mjs && node scripts/audit-ai-regression-results-v3.mjs",
|
|
364
371
|
"check:ai-signatures": "node scripts/sync-ai-public-signatures.mjs --check",
|
|
365
372
|
"ai:signatures:sync": "npm run build && node scripts/sync-ai-public-signatures.mjs",
|
|
@@ -385,7 +392,7 @@
|
|
|
385
392
|
"test:contract-types:packed": "node scripts/check-packed-type-contracts.mjs",
|
|
386
393
|
"test:consumer-types": "npm run test:contract-types:source && npm run build && node node_modules/typescript7/bin/tsc -p tests/consumer-types/webawesome/tsconfig.json && npm run test:contract-types:packed",
|
|
387
394
|
"test:e2e": "playwright test",
|
|
388
|
-
"check": "npm run check:catalog && npm run check:component-integrations && npm run check:profile && npm run check:demo-conformance && npm run check:recipes && npm run check:guidance && npm run check:ai-compatibility && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm run check:design-templates && npm pack --dry-run",
|
|
395
|
+
"check": "npm run check:catalog && npm run check:component-integrations && npm run check:profile && npm run check:demo-conformance && npm run check:recipes && npm run check:css-ownership && npm run check:guidance && npm run check:ai-compatibility && npm run check:ai-regressions && npm run lint && npm run typecheck && npm test && npm run test:consumer-types && npm run check:ai-signatures && npm run demo:build && npm run check:design-templates && npm pack --dry-run",
|
|
389
396
|
"prepublishOnly": "npm run check",
|
|
390
397
|
"check:design-templates": "node scripts/check-design-templates.mjs",
|
|
391
398
|
"check:design-templates:drift": "node scripts/check-design-templates-drift.mjs",
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
.recipe-shell {
|
|
2
|
+
display: grid;
|
|
3
|
+
height: min(37rem, 70vh);
|
|
4
|
+
grid-template-rows: auto minmax(0, 1fr);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.recipe-shell__body {
|
|
8
|
+
display: flex;
|
|
9
|
+
min-width: 0;
|
|
10
|
+
min-height: 0;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.recipe-shell__nav,
|
|
14
|
+
.recipe-shell__inspector {
|
|
15
|
+
display: grid;
|
|
16
|
+
min-height: 0;
|
|
17
|
+
background: var(--kui-color-surface);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.recipe-shell__nav-list,
|
|
21
|
+
.recipe-shell__inspector-body,
|
|
22
|
+
.recipe-shell__main-body {
|
|
23
|
+
min-height: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.recipe-shell__main {
|
|
27
|
+
display: grid;
|
|
28
|
+
min-width: 16rem;
|
|
29
|
+
min-height: 0;
|
|
30
|
+
flex: 1;
|
|
31
|
+
background: var(--kui-color-surface-lowered);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.recipe-shell__cards {
|
|
35
|
+
display: grid;
|
|
36
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
37
|
+
gap: var(--kui-layout-content-gap);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.recipe-shell__card {
|
|
41
|
+
--kui-content-item-border: var(--kui-color-border-quiet);
|
|
42
|
+
--kui-content-item-background: var(--kui-color-surface);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@container (max-width: 44rem) {
|
|
46
|
+
.recipe-shell__inspector-region {
|
|
47
|
+
display: none;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.recipe-shell[data-responsive-pane="inspector"] .recipe-shell__nav-region,
|
|
51
|
+
.recipe-shell[data-responsive-pane="inspector"] .recipe-shell__main {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.recipe-shell[data-responsive-pane="inspector"]
|
|
56
|
+
.recipe-shell__inspector-region {
|
|
57
|
+
display: flex;
|
|
58
|
+
min-width: 0;
|
|
59
|
+
flex: 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.recipe-shell__cards {
|
|
63
|
+
grid-template-columns: 1fr 1fr;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@container (max-width: 28rem) {
|
|
68
|
+
.recipe-shell__nav-region {
|
|
69
|
+
display: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.recipe-shell[data-responsive-pane="navigation"] .recipe-shell__main,
|
|
73
|
+
.recipe-shell[data-responsive-pane="navigation"]
|
|
74
|
+
.recipe-shell__inspector-region {
|
|
75
|
+
display: none;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.recipe-shell[data-responsive-pane="navigation"] .recipe-shell__nav-region {
|
|
79
|
+
display: flex;
|
|
80
|
+
min-width: 0;
|
|
81
|
+
flex: 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.recipe-shell__cards {
|
|
85
|
+
grid-template-columns: 1fr;
|
|
86
|
+
}
|
|
87
|
+
}
|