@kerfjs/ui 5.0.0-beta.56 → 5.0.0-beta.58
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 +81 -37
- package/ai/application-ui-diagnostic-ids-v1.json +9 -1
- package/ai/application-ui-profile-sync.cjs +1 -1
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +1 -1
- package/ai/component-catalog.json +211 -33
- package/ai/component-catalog.schema.json +2 -0
- package/ai/component-class-owners.cjs +83 -0
- package/ai/component-composition-extension.d.ts +7 -0
- package/ai/component-composition-extension.schema.json +7 -0
- package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +2 -1
- package/ai/{component-catalog-v2.d.ts → component-composition.d.ts} +9 -5
- package/ai/{component-catalog-v2.json → component-composition.json} +155 -24
- package/ai/{component-catalog-v2.schema.json → component-composition.schema.json} +21 -5
- package/ai/components/README.md +170 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +90 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +75 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/floating-toolbar.md +80 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +93 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +89 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +88 -0
- package/ai/components/list.md +103 -0
- package/ai/components/loading-spinner.md +72 -0
- package/ai/components/lucide-icon.md +66 -0
- package/ai/components/nav-stack.md +103 -0
- package/ai/components/pane.md +100 -0
- package/ai/components/popup-menu.md +82 -0
- package/ai/components/recipe-app-shell.md +57 -0
- package/ai/components/recipe-collapsible-sidebar.md +57 -0
- package/ai/components/recipe-compact-toolbar.md +57 -0
- package/ai/components/recipe-composer-form.md +57 -0
- package/ai/components/recipe-list-detail-dialog.md +57 -0
- package/ai/components/recipe-list-workspace-states.md +57 -0
- package/ai/components/recipe-loading-inspector.md +57 -0
- package/ai/components/recipe-navigation-sidebar.md +57 -0
- package/ai/components/recipe-navigation-stack.md +57 -0
- package/ai/components/recipe-workspace-header.md +57 -0
- package/ai/components/resize.md +101 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +107 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +102 -0
- package/ai/components/state-banner.md +92 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +78 -0
- package/ai/components/tab-bar.md +112 -0
- package/ai/components/tab-scaffold.md +94 -0
- package/ai/components/tabs.md +90 -0
- package/ai/components/text.md +82 -0
- package/ai/components/token-search-field.md +101 -0
- package/ai/components/toolbar-control-group.md +102 -0
- package/ai/components/toolbar-text.md +76 -0
- package/ai/components/toolbar.md +95 -0
- package/ai/components/value-table.md +72 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +59 -0
- package/ai/components/wa-button.md +55 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +114 -0
- package/ai/public-api-signatures-v1.md +174 -43
- package/ai/skill.md +100 -48
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/component-ownership.d.mts +56 -0
- package/analyzer/component-ownership.mjs +184 -0
- package/analyzer/index.d.mts +3 -0
- package/analyzer/index.mjs +274 -20
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/dist/browser/catalog.js +25 -0
- package/dist/browser/collapsible-panel.js +7 -0
- package/dist/browser/nav-stack.js +8 -0
- package/dist/browser/split-view.js +10 -0
- package/dist/browser/tab-scaffold.js +4 -0
- package/dist/browser/workbench.js +10 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +8 -7
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-QQOTQTDD.js → chunk-2CCMJTVY.js} +13 -10
- package/dist/chunk-2CCMJTVY.js.map +1 -0
- package/dist/{chunk-PK4N5QTO.js → chunk-553ASUK6.js} +2 -3
- package/dist/chunk-553ASUK6.js.map +1 -0
- package/dist/{chunk-G33XC2NB.js → chunk-6YFHCLHG.js} +2 -2
- package/dist/chunk-6YFHCLHG.js.map +1 -0
- package/dist/{chunk-ZIYOJFZD.js → chunk-7JUBXOIV.js} +17 -4
- package/dist/chunk-7JUBXOIV.js.map +1 -0
- package/dist/{chunk-T4UZTNZ4.js → chunk-EVYKTVBQ.js} +2 -11
- package/dist/chunk-EVYKTVBQ.js.map +1 -0
- package/dist/{chunk-AK67F6QN.js → chunk-EZVNC4J6.js} +4 -1
- package/dist/chunk-EZVNC4J6.js.map +1 -0
- package/dist/{chunk-MA6Z6EIM.js → chunk-F4QMLOXJ.js} +3 -2
- package/dist/chunk-F4QMLOXJ.js.map +1 -0
- package/dist/chunk-JCV4GXWB.js +249 -0
- package/dist/chunk-JCV4GXWB.js.map +1 -0
- package/dist/chunk-K47P7QZC.js +17 -0
- package/dist/chunk-K47P7QZC.js.map +1 -0
- package/dist/{chunk-MOBRFZH3.js → chunk-OUK6QRDR.js} +2 -12
- package/dist/chunk-OUK6QRDR.js.map +1 -0
- package/dist/{chunk-VNPQDCQZ.js → chunk-QOWG4ZCL.js} +3 -2
- package/dist/chunk-QOWG4ZCL.js.map +1 -0
- package/dist/{chunk-V65EOWNF.js → chunk-QPUPLNNB.js} +20 -8
- package/dist/chunk-QPUPLNNB.js.map +1 -0
- package/dist/{chunk-O3EXIBEZ.js → chunk-W4XKTST6.js} +8 -7
- package/dist/chunk-W4XKTST6.js.map +1 -0
- package/dist/{chunk-K6UNVKDK.js → chunk-XDKAYSVD.js} +3 -1
- package/dist/chunk-XDKAYSVD.js.map +1 -0
- package/dist/collapsible-panel.d.ts +9 -9
- package/dist/collapsible-panel.js +2 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11 -9
- package/dist/list-action-row.js +2 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +2 -1
- package/dist/nav-stack.d.ts +13 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +20 -3
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-C8sF-YZC.d.ts → panel-toolbar-DqwtBxQL.d.ts} +13 -13
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +3 -3
- package/dist/split-view.js +3 -2
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/app-tab.css +31 -0
- package/dist/styles/badge.css +19 -11
- package/dist/styles/collapsible-panel.css +13 -9
- package/dist/styles/floating-toolbar.css +25 -6
- package/dist/styles/list-header.css +0 -12
- package/dist/styles/list.css +4 -4
- package/dist/styles/nav-stack.css +46 -19
- package/dist/styles/pane.css +50 -0
- package/dist/styles/popup-menu.css +151 -0
- package/dist/styles/resizable-region.css +22 -10
- package/dist/styles/select.css +28 -14
- package/dist/styles/skeleton.css +30 -3
- package/dist/styles/split-view.css +10 -7
- package/dist/styles/state-banner.css +0 -19
- package/dist/styles/surface-scaffold.css +8 -3
- package/dist/styles/tab-bar.css +79 -28
- package/dist/styles/tab-scaffold.css +25 -1
- package/dist/styles/text.css +16 -0
- package/dist/styles/toolbar-control-group.css +121 -66
- package/dist/styles/toolbar-text.css +21 -0
- package/dist/styles/toolbar.css +8 -32
- package/dist/styles/workbench.css +18 -18
- package/dist/tab-scaffold.d.ts +11 -1
- package/dist/tab-scaffold.js +2 -0
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/toolbar-control-group.d.ts +3 -1
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +7 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +8 -1
- package/dist/toolbar.js +1 -1
- package/dist/{types-DXAGogOS.d.ts → types-BuHELdXR.d.ts} +1 -1
- package/dist/wire-catalog.d.ts +3 -1
- package/dist/wire-catalog.js +2 -0
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-scroll-dividers.d.ts +69 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/workbench.d.ts +17 -16
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +9 -1
- package/docs/catalog.md +10 -5
- package/docs/collapsible-panel.md +22 -13
- package/docs/component-contract.md +147 -21
- package/docs/component-selection.md +21 -8
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
- package/docs/design/templates/tab-bar-dark.svg +1 -1
- package/docs/design/templates/tab-bar.svg +1 -1
- package/docs/design-philosophy.md +30 -3
- package/docs/examples/application-ui-profile.json +4 -4
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +3 -3
- package/docs/layout.md +82 -3
- package/docs/nav-stack.md +33 -3
- package/docs/split-view.md +10 -5
- package/docs/tab-scaffold.md +23 -1
- package/docs/type-contracts.md +4 -3
- package/docs/ui-analyzer.md +99 -5
- package/docs/ui-doctor.md +10 -0
- package/docs/workbench.md +31 -20
- package/doctor/index.mjs +6 -1
- package/llms.txt +85 -20
- package/package.json +17 -5
- package/ux-demo/recipes/collapsible-sidebar.tsx +0 -1
- package/ux-demo/recipes/composer-form.tsx +0 -1
- package/ux-demo/recipes/list-detail-dialog.tsx +0 -2
- package/ux-demo/recipes/list-workspace-states.tsx +0 -1
- package/ux-demo/recipes/loading-inspector.tsx +0 -1
- package/ux-demo/recipes/workspace-header.tsx +0 -1
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/dist/chunk-AK67F6QN.js.map +0 -1
- package/dist/chunk-G33XC2NB.js.map +0 -1
- package/dist/chunk-K6UNVKDK.js.map +0 -1
- package/dist/chunk-MA6Z6EIM.js.map +0 -1
- package/dist/chunk-MOBRFZH3.js.map +0 -1
- package/dist/chunk-O3EXIBEZ.js.map +0 -1
- package/dist/chunk-PK4N5QTO.js.map +0 -1
- package/dist/chunk-QQOTQTDD.js.map +0 -1
- package/dist/chunk-T4UZTNZ4.js.map +0 -1
- package/dist/chunk-V65EOWNF.js.map +0 -1
- package/dist/chunk-VNPQDCQZ.js.map +0 -1
- package/dist/chunk-ZIYOJFZD.js.map +0 -1
package/README.md
CHANGED
|
@@ -39,13 +39,15 @@ npm install kerfjs @kerfjs/ui
|
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
```tsx
|
|
42
|
+
import { mount } from "kerfjs";
|
|
42
43
|
import { ListItem } from "@kerfjs/ui/list-item";
|
|
43
44
|
import { ListHeader } from "@kerfjs/ui/list-header";
|
|
44
45
|
import { ListActionRow } from "@kerfjs/ui/list-action-row";
|
|
45
46
|
import { Toolbar } from "@kerfjs/ui/toolbar";
|
|
46
|
-
import { ToolbarControlGroup } from "@kerfjs/ui/toolbar-control-group";
|
|
47
47
|
import { ToolbarText } from "@kerfjs/ui/toolbar-text";
|
|
48
48
|
|
|
49
|
+
const root = document.getElementById("app")!;
|
|
50
|
+
|
|
49
51
|
mount(root, () => (
|
|
50
52
|
<>
|
|
51
53
|
<Toolbar
|
|
@@ -80,7 +82,7 @@ mount(root, () => (
|
|
|
80
82
|
label="src/main.ts"
|
|
81
83
|
trailingAction="open-file-actions"
|
|
82
84
|
trailingActionLabel="Actions for src/main.ts"
|
|
83
|
-
trailingActionIcon={
|
|
85
|
+
trailingActionIcon={<span aria-hidden="true">⋯</span>}
|
|
84
86
|
/>
|
|
85
87
|
<div id="workspace-actions" popover="auto">
|
|
86
88
|
Application-owned actions
|
|
@@ -97,7 +99,7 @@ primary region, while semantic positions and replacement content use explicit
|
|
|
97
99
|
named `SafeHtml` props such as `header`, `footer`, `leading`, `trailing`,
|
|
98
100
|
`icon`, and `action`. These named `SafeHtml` prop slots are ordinary typed
|
|
99
101
|
function-component props—not native `<slot>` elements, wrapper slot
|
|
100
|
-
components, or a generic `slots` object. The
|
|
102
|
+
components, or a generic `slots` object. The composition catalog publishes
|
|
101
103
|
sound prop bindings as `zone.jsx.prop`, allowing ESLint to validate statically
|
|
102
104
|
visible content and cardinality without guessing from zone names.
|
|
103
105
|
|
|
@@ -214,6 +216,7 @@ interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
|
|
|
214
216
|
| `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
|
|
215
217
|
| `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
|
|
216
218
|
| `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
|
|
219
|
+
| `wireScrollDividers` | `@kerfjs/ui/wire-scroll-dividers` | — |
|
|
217
220
|
| `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
|
|
218
221
|
| `Skeleton` | `@kerfjs/ui/skeleton` | `@kerfjs/ui/skeleton.css` |
|
|
219
222
|
| `SunkenPanel` | `@kerfjs/ui/sunken-panel` | `@kerfjs/ui/sunken-panel.css` |
|
|
@@ -225,13 +228,24 @@ interchangeable. `ListItem` and `ListActionRow` deliberately expose no raw
|
|
|
225
228
|
| `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
|
|
226
229
|
| `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
|
|
227
230
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
+
Application layouts are separate component subpaths. Browser-condition imports
|
|
232
|
+
include their reachable CSS; use the matching manual CSS export when your
|
|
233
|
+
bundler does not select the browser condition. Add a wire subpath when the
|
|
234
|
+
layout has interactive behavior. The catalog
|
|
231
235
|
entries for `nav-stack`, `split-view`, `tab-scaffold`, `workbench`, and
|
|
232
236
|
`collapsible-panel` document their selection rules, ownership boundaries,
|
|
233
237
|
public classes, tokens, and focused demos. See
|
|
234
238
|
[`docs/app-layouts.md`](./docs/app-layouts.md) for the layout decision matrix.
|
|
239
|
+
`NavStack` and `TabScaffold` expose `chromeDividers="scroll" | "always" |
|
|
240
|
+
"none"` for their chrome lines; `SplitView` forwards the setting to its
|
|
241
|
+
compact stack. A sole `Pane` in a view or scene fills it, keeping the Pane's
|
|
242
|
+
header in place while its own content scrolls.
|
|
243
|
+
|
|
244
|
+
For a `Workbench` or `CollapsiblePanel`, place panel toolbar groups in its
|
|
245
|
+
`leading`, `center`, and `trailing` zones. Add `relocateOnCollapse` to each
|
|
246
|
+
`ToolbarControlGroup` that should remain available in the work-area toolbar
|
|
247
|
+
while the panel is closed. The panel collects marked groups in zone order;
|
|
248
|
+
its toggle follows them. See [Workbench panel toolbars](./docs/workbench.md#panel-toolbars).
|
|
235
249
|
|
|
236
250
|
Compose panel, dialog, and page headings directly with `Toolbar`: put an optional
|
|
237
251
|
icon in a `ToolbarControlGroup`, use a direct extra-large `ToolbarText` for the
|
|
@@ -271,7 +285,19 @@ action at the logical end. Its visible action glyph defaults to 18px through
|
|
|
271
285
|
|
|
272
286
|
## Machine-readable catalog
|
|
273
287
|
|
|
274
|
-
AI
|
|
288
|
+
AI assistants should start from the generated markdown reference,
|
|
289
|
+
[`ai/components/README.md`](./ai/components/README.md): a one-line index of
|
|
290
|
+
every entry grouped like the catalog, plus one short page per entry
|
|
291
|
+
(`ai/components/<id>.md`) covering when to use and avoid it, imports and
|
|
292
|
+
CSS/registration side effects, where its exact props live, legal parents,
|
|
293
|
+
zones with their JSX props and child counts, app- and wiring-owned state,
|
|
294
|
+
geometry ownership, accessibility obligations, the styling boundary
|
|
295
|
+
(configure through props; never override internals), and its composition
|
|
296
|
+
diagnostics. The pages are projected from the two JSON catalogs by
|
|
297
|
+
`scripts/sync-component-docs.mjs` (`npm run catalog:sync`), and
|
|
298
|
+
`npm run check:catalog` fails when any page drifts.
|
|
299
|
+
|
|
300
|
+
Tools can retrieve the shipped [`ai/component-catalog.json`](./ai/component-catalog.json)
|
|
275
301
|
for the exhaustive component and composition inventory. It is the canonical
|
|
276
302
|
source for ids, public exports, purpose and selection guidance, relationships,
|
|
277
303
|
delivery and side effects, companion wiring, application-owned policy,
|
|
@@ -291,14 +317,16 @@ Keeping this as a companion artifact prevents per-entry selection facts from
|
|
|
291
317
|
duplicating presentation rules.
|
|
292
318
|
|
|
293
319
|
Tools that evaluate composition may additionally load
|
|
294
|
-
[`component-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
320
|
+
[`component-composition.json`](./ai/component-composition.json). It is a
|
|
321
|
+
generated composition layer beside `component-catalog.json`, not a newer
|
|
322
|
+
version of it: a deterministic, package-qualified projection of every
|
|
323
|
+
component-catalog entry with formal parent/context, zone/cardinality, child,
|
|
324
|
+
state ownership, wiring, responsive, layout, accessibility, public-boundary,
|
|
325
|
+
and stable-diagnostic fields. `component-catalog.json` remains the selection
|
|
326
|
+
and delivery surface. Composition defaults are
|
|
299
327
|
deliberately permissive; only documented objective rules receive an
|
|
300
328
|
authoritative override and enforceable diagnostic. The adjacent schema and
|
|
301
|
-
[`component-
|
|
329
|
+
[`component-composition.d.ts`](./ai/component-composition.d.ts) types describe
|
|
302
330
|
the same contract.
|
|
303
331
|
|
|
304
332
|
Applications and downstream design systems should publish the same facts for
|
|
@@ -314,9 +342,9 @@ tool reason about both sides of a composition using one vocabulary without
|
|
|
314
342
|
pretending app-local components are `@kerfjs/ui` exports.
|
|
315
343
|
|
|
316
344
|
Composition-aware consumers use
|
|
317
|
-
[`component-
|
|
345
|
+
[`component-composition-extension.schema.json`](./ai/component-composition-extension.schema.json),
|
|
318
346
|
its shipped TypeScript types, and the checked
|
|
319
|
-
[`component-
|
|
347
|
+
[`component-composition-extension.json`](./docs/examples/component-composition-extension.json)
|
|
320
348
|
example. Preserve each catalog's package and qualify every identity and
|
|
321
349
|
cross-catalog reference as `package:id`; never merge entries by bare id.
|
|
322
350
|
|
|
@@ -327,7 +355,7 @@ rejects. The package gate compiles one positive/negative consumer fixture agains
|
|
|
327
355
|
both source and declarations extracted from the real packed tarball. The
|
|
328
356
|
[compile-time contract guide](./docs/type-contracts.md) documents migrations and
|
|
329
357
|
the dynamic DOM/children relationships that remain runtime or catalog checks.
|
|
330
|
-
Packages scaffolded by `create-kerf-component` maintain this
|
|
358
|
+
Packages scaffolded by `create-kerf-component` maintain this composition input from
|
|
331
359
|
`kerf.components.json`: `npm run catalog:generate` emits the catalog and
|
|
332
360
|
`npm run catalog:check` verifies source files, named public exports, explicit
|
|
333
361
|
author decisions, and byte-for-byte drift. Tools index the generated consumer
|
|
@@ -350,9 +378,9 @@ token overrides, layout/responsive conventions, and narrow rule exceptions.
|
|
|
350
378
|
Profiles contain policy only—never product records, user data, or broad styling
|
|
351
379
|
waivers.
|
|
352
380
|
|
|
353
|
-
Catalog declarations always provide a
|
|
381
|
+
Catalog declarations always provide a `composition` location. Consumer
|
|
354
382
|
packages generated with composition-only metadata omit `selection`;
|
|
355
|
-
`@kerfjs/ui` continues to require its
|
|
383
|
+
`@kerfjs/ui` continues to require its `component-catalog.json` selection catalog.
|
|
356
384
|
|
|
357
385
|
Node-based AI and static-analysis tools may import the shipped discovery API
|
|
358
386
|
from `@kerfjs/ui/ai/application-ui-profile.mjs`. It discovers package defaults,
|
|
@@ -376,9 +404,12 @@ Run `kerf-ui-analyze --root . src` (or import
|
|
|
376
404
|
composition catalogs and application profile. It catches provable private
|
|
377
405
|
selector reach-through, unknown tokens, competing geometry owners, nested
|
|
378
406
|
scroll owners, and cataloged CSS-value violations in JavaScript/TypeScript
|
|
379
|
-
component calls and JSX
|
|
380
|
-
|
|
381
|
-
|
|
407
|
+
component calls and JSX, plus component-ownership overrides: CSS that makes
|
|
408
|
+
another package's component its subject, touches its private variables,
|
|
409
|
+
overrides a token its typed prop sets, or styles it through a hook class on
|
|
410
|
+
its root (`KUI-L019`–`KUI-L022`; forcing a component's dimensions is one such
|
|
411
|
+
restyle). It reports repeated insets, exceptional spacing shorthands, and
|
|
412
|
+
dynamic classes separately as review findings. Text, versioned JSON,
|
|
382
413
|
and SARIF outputs carry stable `KUI-L###` ids, repository-relative locations,
|
|
383
414
|
evidence, and ownership chains. See the [analyzer guide](./docs/ui-analyzer.md).
|
|
384
415
|
|
|
@@ -435,7 +466,10 @@ file.
|
|
|
435
466
|
|
|
436
467
|
`npm run check:css-ownership` keeps that boundary honest: application CSS may
|
|
437
468
|
style only application-owned structure, never package component classes or
|
|
438
|
-
Web Awesome descendants
|
|
469
|
+
Web Awesome descendants, and a package component's stylesheet styles only
|
|
470
|
+
itself (in a composing parent's context when needed) — never another kerf
|
|
471
|
+
component's root, the `wa-*` tags it renders, its variables, or a hook class on
|
|
472
|
+
its root. The UX catalog's `style.css` contains document-shell
|
|
439
473
|
mechanics only, recipes ship no stylesheets (`npm run check:recipes` rejects
|
|
440
474
|
route stylesheets, inline styles, and styling-only classes), and `catalog.css`
|
|
441
475
|
remains a
|
|
@@ -461,23 +495,29 @@ component browser imports. See [Document baseline](./docs/document-baseline.md).
|
|
|
461
495
|
|
|
462
496
|
## Pane and content geometry
|
|
463
497
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
an optional
|
|
467
|
-
|
|
498
|
+
Render `Pane` (`@kerfjs/ui/pane`) for a sidebar, main area, inspector, or
|
|
499
|
+
dialog: the same structural vocabulary everywhere. Its `.kui-pane` root is
|
|
500
|
+
unpadded and contains an optional header, one scrolling `.kui-pane__content`,
|
|
501
|
+
and an optional footer; the content slot already carries `.kui-content`, which
|
|
502
|
+
makes its major children a vertical stack with 24px gaps. Choose landmark
|
|
503
|
+
semantics with `element` / `contentElement` rather than writing the pane
|
|
504
|
+
classes onto your own elements — `eslint-plugin-kerfjs` reports a component's
|
|
505
|
+
anatomy class on an application-owned element as `KUI-L103`.
|
|
468
506
|
|
|
469
507
|
```tsx
|
|
470
|
-
<
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
<
|
|
479
|
-
|
|
480
|
-
</
|
|
508
|
+
<Pane
|
|
509
|
+
element="aside"
|
|
510
|
+
label="Workspace"
|
|
511
|
+
contentElement="nav"
|
|
512
|
+
header={<Toolbar label="Workspace" ... />}
|
|
513
|
+
>
|
|
514
|
+
<section>
|
|
515
|
+
<ListHeader label="Workspace" count={3} countLabel="3 workspaces" />
|
|
516
|
+
<ListItem action="open" label="Inbox" icon={inboxIcon} />
|
|
517
|
+
<ListItem action="open" label="Drafts" />
|
|
518
|
+
</section>
|
|
519
|
+
<ContentItem>Workspace details</ContentItem>
|
|
520
|
+
</Pane>
|
|
481
521
|
```
|
|
482
522
|
|
|
483
523
|
Ordinary children use `ContentItem` (`@kerfjs/ui/content-item`): 8px inline
|
|
@@ -553,6 +593,10 @@ arrays support diagnostics, tooling, browser assertions, and package-owned
|
|
|
553
593
|
composition; they are not an application styling API. Application-owned CSS may
|
|
554
594
|
style new structure rendered by its own component, but it must not select a
|
|
555
595
|
nested Kerf or Web Awesome component. Add missing configuration to the owner.
|
|
596
|
+
Markup follows the same rule: write only an entry's `placeableClasses` (layout
|
|
597
|
+
utilities, `kui-app-root`, `kui-content-item` on a non-div carrier) onto your
|
|
598
|
+
own elements; any other public class recreates a component by class, which
|
|
599
|
+
`eslint-plugin-kerfjs` reports as `KUI-L103` with the component to render.
|
|
556
600
|
|
|
557
601
|
`StateBanner` has opinionated `neutral`, `info`, `pop`, `success`, `warning`,
|
|
558
602
|
and `danger` palettes. Override an individual banner with
|
|
@@ -47,9 +47,14 @@
|
|
|
47
47
|
"KUI-L016",
|
|
48
48
|
"KUI-L017",
|
|
49
49
|
"KUI-L018",
|
|
50
|
+
"KUI-L019",
|
|
51
|
+
"KUI-L020",
|
|
52
|
+
"KUI-L021",
|
|
53
|
+
"KUI-L022",
|
|
50
54
|
"KUI-L090",
|
|
51
55
|
"KUI-L101",
|
|
52
56
|
"KUI-L102",
|
|
57
|
+
"KUI-L103",
|
|
53
58
|
"KUI-L201",
|
|
54
59
|
"KUI-L202",
|
|
55
60
|
"KUI-L203",
|
|
@@ -97,5 +102,8 @@
|
|
|
97
102
|
"KUI-T009",
|
|
98
103
|
"KUI-T010",
|
|
99
104
|
"KUI-T011"
|
|
100
|
-
]
|
|
105
|
+
],
|
|
106
|
+
"retired": {
|
|
107
|
+
"KUI-L005": "Folded into KUI-L019: any application rule whose subject is a cataloged component, forced dimensions included. Kept in ids so existing profile exceptions that name it still load."
|
|
108
|
+
}
|
|
101
109
|
}
|
|
@@ -202,7 +202,7 @@ function validateApplicationUiProfile(profile, options = {}) {
|
|
|
202
202
|
add(
|
|
203
203
|
'KUI-P005',
|
|
204
204
|
`${path}.selection`,
|
|
205
|
-
'The @kerfjs/ui catalog requires its
|
|
205
|
+
'The @kerfjs/ui catalog requires its component-catalog.json selection location.',
|
|
206
206
|
);
|
|
207
207
|
for (const kind of ['selection', 'composition']) {
|
|
208
208
|
if (kind === 'selection' && !catalog[kind]) continue;
|
|
@@ -5,22 +5,77 @@
|
|
|
5
5
|
"catalogs": [
|
|
6
6
|
{
|
|
7
7
|
"package": "@kerfjs/ui",
|
|
8
|
-
"selection": {
|
|
8
|
+
"selection": {
|
|
9
|
+
"path": "./component-catalog.json",
|
|
10
|
+
"schemaVersion": 1
|
|
11
|
+
},
|
|
9
12
|
"composition": {
|
|
10
|
-
"path": "./component-
|
|
11
|
-
"schemaVersion":
|
|
13
|
+
"path": "./component-composition.json",
|
|
14
|
+
"schemaVersion": 1
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
],
|
|
15
18
|
"preferences": {
|
|
16
|
-
"application-shell": {
|
|
19
|
+
"application-shell": {
|
|
20
|
+
"preferred": "@kerfjs/ui:recipe-app-shell"
|
|
21
|
+
},
|
|
22
|
+
"application-tabs": {
|
|
23
|
+
"preferred": "@kerfjs/ui:tab-bar",
|
|
24
|
+
"avoid": [
|
|
25
|
+
"@kerfjs/ui:wa-tab-group",
|
|
26
|
+
"@kerfjs/ui:wa-tab",
|
|
27
|
+
"@kerfjs/ui:wa-tab-panel"
|
|
28
|
+
],
|
|
29
|
+
"rationale": "Render TabBar (or SegmentedControl for a view switch) instead of composing Web Awesome tabs directly."
|
|
30
|
+
},
|
|
31
|
+
"command-menu": {
|
|
32
|
+
"preferred": "@kerfjs/ui:popup-menu",
|
|
33
|
+
"avoid": ["@kerfjs/ui:wa-dropdown", "@kerfjs/ui:wa-dropdown-item"],
|
|
34
|
+
"rationale": "Render PopupMenu, which wraps wa-dropdown with the shared popup contract; use Select when choosing a value."
|
|
35
|
+
},
|
|
36
|
+
"embedded-media": {
|
|
37
|
+
"preferred": "@kerfjs/ui:content-item",
|
|
38
|
+
"avoid": [
|
|
39
|
+
"@kerfjs/ui:wa-animated-image",
|
|
40
|
+
"@kerfjs/ui:wa-comparison",
|
|
41
|
+
"@kerfjs/ui:wa-zoomable-frame"
|
|
42
|
+
],
|
|
43
|
+
"rationale": "Keep media behavior application-owned: place a native img, video, or iframe in a ContentItem. Record a narrow KUI-L301 profile exception only when a concrete product requirement needs this Web Awesome element."
|
|
44
|
+
},
|
|
17
45
|
"exclusive-choice": {
|
|
18
46
|
"preferred": "@kerfjs/ui:segmented-control",
|
|
19
|
-
"avoid": ["@kerfjs/ui:wa-button-group"]
|
|
47
|
+
"avoid": ["@kerfjs/ui:wa-button-group"],
|
|
48
|
+
"rationale": "Render SegmentedControl for one-of-N choices instead of a Web Awesome button group."
|
|
49
|
+
},
|
|
50
|
+
"hierarchy-navigation": {
|
|
51
|
+
"preferred": "@kerfjs/ui:list",
|
|
52
|
+
"avoid": ["@kerfjs/ui:wa-tree", "@kerfjs/ui:wa-tree-item"],
|
|
53
|
+
"rationale": "Present hierarchy as List rows (or NavStack drill-in levels). Record a narrow KUI-L301 profile exception only when the product requires tree behavior."
|
|
54
|
+
},
|
|
55
|
+
"icon": {
|
|
56
|
+
"preferred": "@kerfjs/ui:lucide-icon",
|
|
57
|
+
"avoid": ["@kerfjs/ui:wa-icon"],
|
|
58
|
+
"rationale": "Render LucideIcon; Web Awesome icons are not part of the Kerf icon contract."
|
|
20
59
|
},
|
|
21
|
-
"navigation-row": {
|
|
22
|
-
|
|
23
|
-
|
|
60
|
+
"navigation-row": {
|
|
61
|
+
"preferred": "@kerfjs/ui:list-item"
|
|
62
|
+
},
|
|
63
|
+
"panel-heading": {
|
|
64
|
+
"preferred": "@kerfjs/ui:toolbar"
|
|
65
|
+
},
|
|
66
|
+
"resizable-pane": {
|
|
67
|
+
"preferred": "@kerfjs/ui:resize",
|
|
68
|
+
"avoid": ["@kerfjs/ui:wa-split-panel"],
|
|
69
|
+
"rationale": "Render ResizableRegion for application panes instead of a Web Awesome split panel."
|
|
70
|
+
},
|
|
71
|
+
"structured-search": {
|
|
72
|
+
"preferred": "@kerfjs/ui:token-search-field"
|
|
73
|
+
},
|
|
74
|
+
"value-selection": {
|
|
75
|
+
"preferred": "@kerfjs/ui:select",
|
|
76
|
+
"avoid": ["@kerfjs/ui:wa-select", "@kerfjs/ui:wa-option"],
|
|
77
|
+
"rationale": "Render Select, which wraps wa-select and wa-option with Kerf's popup and spacing contract."
|
|
78
|
+
}
|
|
24
79
|
},
|
|
25
80
|
"theme": {
|
|
26
81
|
"colorScheme": "light",
|
|
@@ -289,7 +289,7 @@ export function validateApplicationUiProfile(
|
|
|
289
289
|
add(
|
|
290
290
|
'KUI-P005',
|
|
291
291
|
`${path}.selection`,
|
|
292
|
-
'The @kerfjs/ui catalog requires its
|
|
292
|
+
'The @kerfjs/ui catalog requires its component-catalog.json selection location.',
|
|
293
293
|
);
|
|
294
294
|
for (const kind of ['selection', 'composition']) {
|
|
295
295
|
if (kind === 'selection' && !catalog?.selection) continue;
|