@kerfjs/ui 5.0.0-beta.17 → 5.0.0-beta.21
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 +221 -81
- package/ai/application-ui-diagnostic-ids-v1.json +92 -0
- package/ai/application-ui-profile-sync.cjs +529 -0
- package/ai/application-ui-profile.d.mts +1 -0
- package/ai/application-ui-profile.d.ts +102 -0
- package/ai/application-ui-profile.defaults.json +41 -0
- package/ai/application-ui-profile.mjs +626 -0
- package/ai/application-ui-profile.schema.json +130 -0
- package/ai/catalog-authoring.json +25 -0
- package/ai/catalog-authoring.schema.json +61 -0
- package/ai/compile-time-contracts-v1.json +101 -0
- package/ai/compile-time-contracts-v1.schema.json +49 -0
- package/ai/component-catalog-extension-v2.d.ts +7 -0
- package/ai/component-catalog-extension-v2.schema.json +7 -0
- package/ai/component-catalog-extension.schema.json +79 -0
- package/ai/component-catalog-v2-overrides.json +326 -0
- package/ai/component-catalog-v2.d.ts +67 -0
- package/ai/component-catalog-v2.json +4441 -0
- package/ai/component-catalog-v2.schema.json +246 -0
- package/ai/component-catalog.json +649 -6
- package/ai/component-catalog.schema.json +15 -0
- package/ai/public-api-signatures-v1.md +357 -91
- package/ai/skill.md +95 -50
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/cli.mjs +46 -0
- package/analyzer/index.d.mts +45 -0
- package/analyzer/index.mjs +743 -0
- package/analyzer/report.schema.json +66 -0
- package/dist/app-tab.d.ts +1 -1
- package/dist/app-tab.js +1 -1
- package/dist/browser/pane.js +3 -0
- package/dist/browser/sunken-panel.js +3 -0
- package/dist/catalog-resources.d.ts +34 -0
- package/dist/catalog-resources.js +22 -0
- package/dist/catalog-resources.js.map +1 -0
- package/dist/catalog.d.ts +29 -4
- package/dist/catalog.js +302 -84
- package/dist/catalog.js.map +1 -1
- package/dist/chunk-5VTB2BKP.js +35 -0
- package/dist/chunk-5VTB2BKP.js.map +1 -0
- package/dist/chunk-6WTETUZ6.js +21 -0
- package/dist/chunk-6WTETUZ6.js.map +1 -0
- package/dist/chunk-7KEUJIIC.js +218 -0
- package/dist/chunk-7KEUJIIC.js.map +1 -0
- package/dist/chunk-7L6EHUMV.js +31 -0
- package/dist/chunk-7L6EHUMV.js.map +1 -0
- package/dist/{chunk-XXMOARTH.js → chunk-AASLYRGE.js} +57 -16
- package/dist/chunk-AASLYRGE.js.map +1 -0
- package/dist/chunk-BBRXX6PF.js +108 -0
- package/dist/chunk-BBRXX6PF.js.map +1 -0
- package/dist/{chunk-6NLRBSVX.js → chunk-CN2XNTAM.js} +129 -72
- package/dist/chunk-CN2XNTAM.js.map +1 -0
- package/dist/chunk-DPDBVKNA.js +113 -0
- package/dist/chunk-DPDBVKNA.js.map +1 -0
- package/dist/chunk-DSNIYOZ3.js +114 -0
- package/dist/chunk-DSNIYOZ3.js.map +1 -0
- package/dist/chunk-ELSJX4W7.js +68 -0
- package/dist/chunk-ELSJX4W7.js.map +1 -0
- package/dist/{chunk-AHQI52QO.js → chunk-FEY65TBV.js} +6 -2
- package/dist/chunk-FEY65TBV.js.map +1 -0
- package/dist/chunk-JRKSK2HX.js +79 -0
- package/dist/chunk-JRKSK2HX.js.map +1 -0
- package/dist/chunk-K57KRAOV.js +117 -0
- package/dist/chunk-K57KRAOV.js.map +1 -0
- package/dist/chunk-LPOMRC4C.js +25 -0
- package/dist/chunk-LPOMRC4C.js.map +1 -0
- package/dist/chunk-M7JBER5U.js +41 -0
- package/dist/chunk-M7JBER5U.js.map +1 -0
- package/dist/chunk-NENBUYX5.js +79 -0
- package/dist/chunk-NENBUYX5.js.map +1 -0
- package/dist/chunk-OHU6CI22.js +83 -0
- package/dist/chunk-OHU6CI22.js.map +1 -0
- package/dist/{chunk-YGN7OMLT.js → chunk-OZWU5ZPZ.js} +2 -2
- package/dist/chunk-OZWU5ZPZ.js.map +1 -0
- package/dist/chunk-PIDTEQ3U.js +105 -0
- package/dist/chunk-PIDTEQ3U.js.map +1 -0
- package/dist/chunk-PX3YSS5C.js +32 -0
- package/dist/chunk-PX3YSS5C.js.map +1 -0
- package/dist/chunk-PZQVSDLH.js +61 -0
- package/dist/chunk-PZQVSDLH.js.map +1 -0
- package/dist/chunk-QO55FN2Y.js +20 -0
- package/dist/chunk-QO55FN2Y.js.map +1 -0
- package/dist/chunk-QQFJMRIB.js +45 -0
- package/dist/chunk-QQFJMRIB.js.map +1 -0
- package/dist/chunk-RYRIFZCT.js +58 -0
- package/dist/chunk-RYRIFZCT.js.map +1 -0
- package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
- package/dist/chunk-SRSJO5QE.js.map +1 -0
- package/dist/chunk-VLYV65LK.js +38 -0
- package/dist/chunk-VLYV65LK.js.map +1 -0
- package/dist/chunk-W4CXQYSG.js +23 -0
- package/dist/chunk-W4CXQYSG.js.map +1 -0
- package/dist/{chunk-WXMGNX2Y.js → chunk-W7YD6E4N.js} +2 -2
- package/dist/chunk-W7YD6E4N.js.map +1 -0
- package/dist/{chunk-56RJXPHG.js → chunk-Y6LYKFXY.js} +1 -1
- package/dist/{chunk-56RJXPHG.js.map → chunk-Y6LYKFXY.js.map} +1 -1
- package/dist/collapsible-panel.d.ts +2 -2
- package/dist/collapsible-panel.js +47 -6
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/device-class.js +33 -5
- package/dist/device-class.js.map +1 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/empty-state.d.ts +1 -1
- package/dist/empty-state.js +1 -1
- package/dist/floating-toolbar.d.ts +1 -1
- package/dist/floating-toolbar.js +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +27 -25
- package/dist/list-action-row.d.ts +1 -1
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.d.ts +30 -9
- package/dist/list-header.js +1 -1
- package/dist/list-inset-control.d.ts +1 -1
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +1 -1
- package/dist/list-inset-text.js +1 -1
- package/dist/list-item.d.ts +1 -1
- package/dist/list-item.js +1 -1
- package/dist/loading-spinner.js +1 -1
- package/dist/nav-stack.d.ts +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +49 -0
- package/dist/pane.js +4 -0
- package/dist/pane.js.map +1 -0
- package/dist/panel-header.d.ts +10 -4
- package/dist/panel-header.js +1 -1
- package/dist/resizable-region.d.ts +1 -1
- package/dist/resizable-region.js +1 -1
- package/dist/segmented-control.d.ts +6 -6
- package/dist/segmented-control.js +1 -1
- package/dist/select.d.ts +11 -5
- package/dist/select.js +1 -1
- package/dist/skeleton.d.ts +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/split-view.d.ts +1 -1
- package/dist/split-view.js +70 -10
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +4 -3
- package/dist/state-banner.js +1 -1
- package/dist/styles/catalog.css +32 -6
- package/dist/styles/layout.css +2 -20
- package/dist/styles/pane.css +62 -0
- package/dist/styles/segmented-control.css +3 -7
- package/dist/styles/sunken-panel.css +18 -0
- package/dist/sunken-panel.d.ts +16 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/tab-bar.d.ts +4 -3
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +6 -6
- package/dist/tab-scaffold.js +43 -8
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/token-search-field.d.ts +25 -9
- package/dist/token-search-field.js +1 -1
- package/dist/toolbar-control-group.d.ts +10 -6
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +10 -11
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +1 -1
- package/dist/toolbar.js +1 -1
- package/dist/value-table.d.ts +2 -2
- package/dist/value-table.js +1 -1
- package/dist/wire-catalog.d.ts +31 -2
- package/dist/wire-catalog.js +203 -8
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-nav-stack.js +22 -7
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-resizable-regions.d.ts +1 -1
- package/dist/wire-resizable-regions.js +1 -1
- package/dist/wire-sidebar.js +52 -41
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-tab-bars.d.ts +5 -2
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-scaffold.js +9 -4
- package/dist/wire-tab-scaffold.js.map +1 -1
- package/dist/wire-token-search-fields.d.ts +12 -7
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +1 -1
- package/dist/workbench.js +56 -9
- package/dist/workbench.js.map +1 -1
- package/docs/app-layouts.md +7 -7
- package/docs/catalog.md +249 -46
- package/docs/collapsible-panel.md +38 -11
- package/docs/component-contract.md +132 -7
- package/docs/component-selection.md +79 -67
- package/docs/design/templates.md +1 -1
- package/docs/design-philosophy.md +7 -9
- package/docs/device-class.md +8 -8
- package/docs/examples/application-ui-profile.json +60 -0
- package/docs/examples/command-palette-adapter.tsx +67 -17
- package/docs/examples/component-catalog-extension-v2.json +81 -0
- package/docs/examples/component-catalog-extension.json +45 -0
- package/docs/layout.md +51 -32
- package/docs/nav-stack.md +15 -6
- package/docs/recipes.md +4 -4
- package/docs/split-view.md +3 -3
- package/docs/sunken-panel.md +43 -0
- package/docs/tab-scaffold.md +16 -7
- package/docs/type-contracts.md +99 -0
- package/docs/ui-analyzer.md +81 -0
- package/docs/ui-doctor.md +77 -0
- package/docs/ui-evaluator.md +122 -0
- package/docs/webawesome-theme.md +8 -8
- package/docs/workbench.md +18 -5
- package/doctor/cli.mjs +115 -0
- package/doctor/config.schema.json +68 -0
- package/doctor/index.d.mts +116 -0
- package/doctor/index.mjs +1256 -0
- package/doctor/report.schema.json +118 -0
- package/evaluator/cli.mjs +89 -0
- package/evaluator/index.d.mts +90 -0
- package/evaluator/index.mjs +1138 -0
- package/evaluator/report.schema.json +152 -0
- package/llms.txt +58 -15
- package/package.json +70 -10
- package/ux-demo/recipes/app-shell.tsx +206 -10
- package/ux-demo/recipes/collapsible-sidebar.tsx +167 -44
- package/ux-demo/recipes/compact-toolbar.tsx +114 -12
- package/ux-demo/recipes/composer-form.tsx +106 -18
- package/ux-demo/recipes/list-detail-dialog.tsx +144 -8
- package/ux-demo/recipes/list-workspace-states.tsx +165 -8
- package/ux-demo/recipes/loaders.ts +5 -2
- package/ux-demo/recipes/loading-inspector.tsx +124 -41
- package/ux-demo/recipes/mount-recipe.ts +27 -6
- package/ux-demo/recipes/navigation-sidebar.tsx +120 -9
- package/ux-demo/recipes/navigation-stack.tsx +61 -19
- package/ux-demo/recipes/types.ts +3 -1
- package/ux-demo/recipes/workspace-header.tsx +57 -2
- package/dist/chunk-2Z5TWHKQ.js +0 -34
- package/dist/chunk-2Z5TWHKQ.js.map +0 -1
- package/dist/chunk-37T3VNIZ.js +0 -19
- package/dist/chunk-37T3VNIZ.js.map +0 -1
- package/dist/chunk-55DATV3A.js +0 -10
- package/dist/chunk-55DATV3A.js.map +0 -1
- package/dist/chunk-5ATCDSQS.js +0 -42
- package/dist/chunk-5ATCDSQS.js.map +0 -1
- package/dist/chunk-5E2HVJ33.js +0 -10
- package/dist/chunk-5E2HVJ33.js.map +0 -1
- package/dist/chunk-6NLRBSVX.js.map +0 -1
- package/dist/chunk-7BR3DO2A.js.map +0 -1
- package/dist/chunk-7JB7VPRI.js +0 -34
- package/dist/chunk-7JB7VPRI.js.map +0 -1
- package/dist/chunk-7LDCTU7D.js +0 -134
- package/dist/chunk-7LDCTU7D.js.map +0 -1
- package/dist/chunk-AHQI52QO.js.map +0 -1
- package/dist/chunk-AQNKJRFH.js +0 -79
- package/dist/chunk-AQNKJRFH.js.map +0 -1
- package/dist/chunk-AVZHJN6C.js +0 -14
- package/dist/chunk-AVZHJN6C.js.map +0 -1
- package/dist/chunk-B24C4A6T.js +0 -22
- package/dist/chunk-B24C4A6T.js.map +0 -1
- package/dist/chunk-CH4SQ6H5.js +0 -39
- package/dist/chunk-CH4SQ6H5.js.map +0 -1
- package/dist/chunk-DAFFDO33.js +0 -14
- package/dist/chunk-DAFFDO33.js.map +0 -1
- package/dist/chunk-I7INRJO4.js +0 -17
- package/dist/chunk-I7INRJO4.js.map +0 -1
- package/dist/chunk-L4OKFDJY.js +0 -24
- package/dist/chunk-L4OKFDJY.js.map +0 -1
- package/dist/chunk-M5JRI6MN.js +0 -27
- package/dist/chunk-M5JRI6MN.js.map +0 -1
- package/dist/chunk-RNPGFQ33.js +0 -10
- package/dist/chunk-RNPGFQ33.js.map +0 -1
- package/dist/chunk-VPCTCUED.js +0 -10
- package/dist/chunk-VPCTCUED.js.map +0 -1
- package/dist/chunk-WRTAQ7BZ.js +0 -23
- package/dist/chunk-WRTAQ7BZ.js.map +0 -1
- package/dist/chunk-WVPYVDXY.js +0 -15
- package/dist/chunk-WVPYVDXY.js.map +0 -1
- package/dist/chunk-WXMGNX2Y.js.map +0 -1
- package/dist/chunk-XXMOARTH.js.map +0 -1
- package/dist/chunk-YGN7OMLT.js.map +0 -1
- package/dist/chunk-ZQQ6P4SV.js +0 -20
- package/dist/chunk-ZQQ6P4SV.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,6 +4,13 @@ Accessible, composable UI primitives for [kerf](https://github.com/brianwestphal
|
|
|
4
4
|
|
|
5
5
|
Start interface work with the [need-first component selection matrix](./docs/component-selection.md). It distinguishes direct reuse, composition, thin application adapters, and genuinely custom semantics, with imports, required wiring, application ownership, alternatives, and recipes for every public primitive.
|
|
6
6
|
|
|
7
|
+
When authoring a component gallery, follow the single
|
|
8
|
+
[Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract)
|
|
9
|
+
for focused-versus-composition modes, helper nesting, specimen selection,
|
|
10
|
+
geometry inspection, and metadata ownership. AI tools can discover that
|
|
11
|
+
contract and its public imports through the shipped
|
|
12
|
+
[`catalog-authoring.json`](./ai/catalog-authoring.json) artifact.
|
|
13
|
+
|
|
7
14
|
For connective application patterns, use the seven [production composition
|
|
8
15
|
recipes](./docs/recipes.md). Each has a stable catalog route, runnable state,
|
|
9
16
|
public-subpath source, semantic layout ownership, and explicit application
|
|
@@ -23,56 +30,71 @@ npm install kerfjs @kerfjs/ui
|
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
```tsx
|
|
26
|
-
import { ListItem } from
|
|
27
|
-
import { ListHeader } from
|
|
28
|
-
import { ListActionRow } from
|
|
29
|
-
import { Toolbar } from
|
|
30
|
-
import { ToolbarControlGroup } from
|
|
31
|
-
import { ToolbarText } from
|
|
32
|
-
|
|
33
|
-
mount(root, () =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
popoverTarget: 'workspace-actions',
|
|
43
|
-
popoverTargetAction: 'toggle',
|
|
44
|
-
'aria-controls': 'workspace-actions',
|
|
45
|
-
'aria-haspopup': 'dialog',
|
|
46
|
-
}}
|
|
47
|
-
/>
|
|
48
|
-
<ListItem
|
|
49
|
-
action="open-notes"
|
|
50
|
-
label="Notes"
|
|
51
|
-
selected
|
|
52
|
-
rootAttributes={{ 'data-command-color': 'blue', 'data-drop-status': 'ready' }}
|
|
53
|
-
/>
|
|
54
|
-
<ListActionRow
|
|
55
|
-
action="open-file"
|
|
56
|
-
itemId="src/main.ts"
|
|
57
|
-
label="src/main.ts"
|
|
58
|
-
trailingAction="open-file-actions"
|
|
59
|
-
trailingActionLabel="Actions for src/main.ts"
|
|
60
|
-
trailingActionIcon={moreIcon}
|
|
33
|
+
import { ListItem } from "@kerfjs/ui/list-item";
|
|
34
|
+
import { ListHeader } from "@kerfjs/ui/list-header";
|
|
35
|
+
import { ListActionRow } from "@kerfjs/ui/list-action-row";
|
|
36
|
+
import { Toolbar } from "@kerfjs/ui/toolbar";
|
|
37
|
+
import { ToolbarControlGroup } from "@kerfjs/ui/toolbar-control-group";
|
|
38
|
+
import { ToolbarText } from "@kerfjs/ui/toolbar-text";
|
|
39
|
+
|
|
40
|
+
mount(root, () => (
|
|
41
|
+
<>
|
|
42
|
+
<Toolbar
|
|
43
|
+
label="Document"
|
|
44
|
+
leading={
|
|
45
|
+
<ToolbarControlGroup appearance="borderless" single>
|
|
46
|
+
<ToolbarText text="Notes" />
|
|
47
|
+
</ToolbarControlGroup>
|
|
48
|
+
}
|
|
61
49
|
/>
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
50
|
+
<section>
|
|
51
|
+
<ListHeader
|
|
52
|
+
label="Workspace"
|
|
53
|
+
action="show-workspace-actions"
|
|
54
|
+
actionLabel="Workspace actions"
|
|
55
|
+
rootAttributes={{ "data-section-id": "workspace" }}
|
|
56
|
+
triggerAttributes={{
|
|
57
|
+
popoverTarget: "workspace-actions",
|
|
58
|
+
popoverTargetAction: "toggle",
|
|
59
|
+
"aria-controls": "workspace-actions",
|
|
60
|
+
"aria-haspopup": "dialog",
|
|
61
|
+
}}
|
|
62
|
+
/>
|
|
63
|
+
<ListItem
|
|
64
|
+
action="open-notes"
|
|
65
|
+
label="Notes"
|
|
66
|
+
selected
|
|
67
|
+
rootAttributes={{
|
|
68
|
+
"data-command-color": "blue",
|
|
69
|
+
"data-drop-status": "ready",
|
|
70
|
+
}}
|
|
71
|
+
/>
|
|
72
|
+
<ListActionRow
|
|
73
|
+
action="open-file"
|
|
74
|
+
itemId="src/main.ts"
|
|
75
|
+
label="src/main.ts"
|
|
76
|
+
trailingAction="open-file-actions"
|
|
77
|
+
trailingActionLabel="Actions for src/main.ts"
|
|
78
|
+
trailingActionIcon={moreIcon}
|
|
79
|
+
/>
|
|
80
|
+
<div id="workspace-actions" popover="auto">
|
|
81
|
+
Application-owned actions
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
</>
|
|
85
|
+
));
|
|
65
86
|
```
|
|
66
87
|
|
|
67
88
|
Components return Kerf `SafeHtml`. They do not own application state or attach transient listeners. Actions are stable `data-action` hooks; the application wires them once with `delegate()` or `delegateActions()` and retains the disposer.
|
|
68
89
|
|
|
69
90
|
`ListItem.rootAttributes`, `ListHeader.rootAttributes`,
|
|
70
|
-
`ListActionRow.rootAttributes`,
|
|
91
|
+
`ListActionRow.rootAttributes`, `AppTab.rootAttributes`,
|
|
92
|
+
`CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` carry typed
|
|
71
93
|
application `data-*` metadata without
|
|
72
94
|
teaching the package domain fields. `ListHeader.triggerAttributes` and
|
|
73
95
|
`ListActionRow.trailingActionAttributes` additionally support native popover
|
|
74
96
|
target and relationship attributes. Roles and component-owned action, selection,
|
|
75
|
-
disclosure, naming, disabled, and
|
|
97
|
+
disclosure, naming, disabled, icon, and catalog-structure semantics remain protected props; an
|
|
76
98
|
isolated `role="menuitem"` is not an extension shortcut.
|
|
77
99
|
The slots are also filtered at runtime, so structurally widened objects and
|
|
78
100
|
JavaScript callers cannot bypass those protections with case-variant names.
|
|
@@ -92,35 +114,37 @@ as a `New` marker.
|
|
|
92
114
|
|
|
93
115
|
## Component subpaths
|
|
94
116
|
|
|
95
|
-
| Component
|
|
96
|
-
|
|
|
97
|
-
| `LucideIcon`
|
|
98
|
-
| `DisclosureArrow`
|
|
99
|
-
| `Toolbar`
|
|
100
|
-
| `ToolbarControlGroup`
|
|
101
|
-
| `FloatingToolbar`
|
|
102
|
-
| `ToolbarText`
|
|
103
|
-
| `ListActionRow`
|
|
104
|
-
| `ListItem`
|
|
105
|
-
| `ListHeader`
|
|
106
|
-
| `ListInsetControl`
|
|
107
|
-
| `ListInsetText`
|
|
108
|
-
| Pane
|
|
109
|
-
|
|
|
110
|
-
| `
|
|
111
|
-
| `
|
|
112
|
-
| `
|
|
113
|
-
| `
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
117
|
+
| Component | Browser import (includes reachable CSS) | Manual CSS export |
|
|
118
|
+
| ------------------------------------------------------------------- | --------------------------------------- | -------------------------------------- |
|
|
119
|
+
| `LucideIcon` | `@kerfjs/ui/lucide-icon` | `@kerfjs/ui/lucide-icon.css` |
|
|
120
|
+
| `DisclosureArrow` | `@kerfjs/ui/disclosure-arrow` | `@kerfjs/ui/disclosure-arrow.css` |
|
|
121
|
+
| `Toolbar` | `@kerfjs/ui/toolbar` | `@kerfjs/ui/toolbar.css` |
|
|
122
|
+
| `ToolbarControlGroup` | `@kerfjs/ui/toolbar-control-group` | `@kerfjs/ui/toolbar-control-group.css` |
|
|
123
|
+
| `FloatingToolbar` | `@kerfjs/ui/floating-toolbar` | `@kerfjs/ui/floating-toolbar.css` |
|
|
124
|
+
| `ToolbarText` | `@kerfjs/ui/toolbar-text` | `@kerfjs/ui/toolbar-text.css` |
|
|
125
|
+
| `ListActionRow` | `@kerfjs/ui/list-action-row` | `@kerfjs/ui/list-action-row.css` |
|
|
126
|
+
| `ListItem` | `@kerfjs/ui/list-item` | `@kerfjs/ui/list-item.css` |
|
|
127
|
+
| `ListHeader` | `@kerfjs/ui/list-header` | `@kerfjs/ui/list-header.css` |
|
|
128
|
+
| `ListInsetControl` | `@kerfjs/ui/list-inset-control` | `@kerfjs/ui/list-inset-control.css` |
|
|
129
|
+
| `ListInsetText` | `@kerfjs/ui/list-inset-text` | `@kerfjs/ui/list-inset-text.css` |
|
|
130
|
+
| `Pane` | `@kerfjs/ui/pane` | `@kerfjs/ui/pane.css` |
|
|
131
|
+
| Content and navigation composition | — | `@kerfjs/ui/layout.css` |
|
|
132
|
+
| `ResizableRegion` | `@kerfjs/ui/resizable-region` | `@kerfjs/ui/resizable-region.css` |
|
|
133
|
+
| `wireResizableRegions` | `@kerfjs/ui/wire-resizable-regions` | — |
|
|
134
|
+
| `AppTab` | `@kerfjs/ui/app-tab` | `@kerfjs/ui/app-tab.css` |
|
|
135
|
+
| `TabBar` | `@kerfjs/ui/tab-bar` | `@kerfjs/ui/tab-bar.css` |
|
|
136
|
+
| `wireTabBars`, `reorderTabs` | `@kerfjs/ui/wire-tab-bars` | — |
|
|
137
|
+
| `LoadingSpinner` | `@kerfjs/ui/loading-spinner` | `@kerfjs/ui/loading-spinner.css` |
|
|
138
|
+
| `Skeleton` | `@kerfjs/ui/skeleton` | `@kerfjs/ui/skeleton.css` |
|
|
139
|
+
| `SunkenPanel` | `@kerfjs/ui/sunken-panel` | `@kerfjs/ui/sunken-panel.css` |
|
|
140
|
+
| `Select` | `@kerfjs/ui/select` | `@kerfjs/ui/select.css` |
|
|
141
|
+
| `SegmentedControl` | `@kerfjs/ui/segmented-control` | `@kerfjs/ui/segmented-control.css` |
|
|
142
|
+
| `TokenSearchField`, `readTokenSearchField`, `placeTokenSearchCaret` | `@kerfjs/ui/token-search-field` | `@kerfjs/ui/token-search-field.css` |
|
|
143
|
+
| `wireTokenSearchFields` | `@kerfjs/ui/wire-token-search-fields` | — |
|
|
144
|
+
| `StateBanner` | `@kerfjs/ui/state-banner` | `@kerfjs/ui/state-banner.css` |
|
|
145
|
+
| `EmptyState` | `@kerfjs/ui/empty-state` | `@kerfjs/ui/empty-state.css` |
|
|
146
|
+
| `PanelHeader` | `@kerfjs/ui/panel-header` | `@kerfjs/ui/panel-header.css` |
|
|
147
|
+
| `ValueTable`, `ValueTableRow` | `@kerfjs/ui/value-table` | `@kerfjs/ui/value-table.css` |
|
|
124
148
|
|
|
125
149
|
`PanelHeader` is a plain `Toolbar` used as a panel, dialog, or page heading: an
|
|
126
150
|
optional icon control group (given a brand fill with a matching border), the
|
|
@@ -156,7 +180,122 @@ delivery and side effects, companion wiring, application-owned policy,
|
|
|
156
180
|
variants, accessibility obligations, public CSS hooks, routes, and current
|
|
157
181
|
documentation/recipe links. The adjacent
|
|
158
182
|
[`component-catalog.schema.json`](./ai/component-catalog.schema.json) describes
|
|
159
|
-
the versioned format.
|
|
183
|
+
the versioned format. Every visual entry also declares who owns its margin,
|
|
184
|
+
border, and padding, so a generator can fit it into Kerf's alignment model
|
|
185
|
+
without guessing from a screenshot or private CSS.
|
|
186
|
+
|
|
187
|
+
Catalog demo authoring is deliberately separate from the entry inventory. Load
|
|
188
|
+
[`catalog-authoring.json`](./ai/catalog-authoring.json) to discover the
|
|
189
|
+
authoritative [Catalog demo authoring contract](./docs/catalog.md#catalog-demo-authoring-contract),
|
|
190
|
+
the exact API-signature context, public imports/helpers, and sanctioned metadata
|
|
191
|
+
slot. Keeping this as a companion artifact prevents per-entry selection facts
|
|
192
|
+
from duplicating presentation rules.
|
|
193
|
+
|
|
194
|
+
Tools that evaluate composition may additionally load
|
|
195
|
+
[`component-catalog-v2.json`](./ai/component-catalog-v2.json). It is a
|
|
196
|
+
deterministic, package-qualified projection of every v1 entry with formal
|
|
197
|
+
parent/context, zone/cardinality, child, state ownership, wiring, responsive,
|
|
198
|
+
layout, accessibility, public-boundary, and stable-diagnostic fields. V1
|
|
199
|
+
remains the selection and delivery compatibility surface. V2 defaults are
|
|
200
|
+
deliberately permissive; only documented objective rules receive an
|
|
201
|
+
authoritative override and enforceable diagnostic. The adjacent schema and
|
|
202
|
+
[`component-catalog-v2.d.ts`](./ai/component-catalog-v2.d.ts) types describe
|
|
203
|
+
the same contract.
|
|
204
|
+
|
|
205
|
+
Applications and downstream design systems should publish the same facts for
|
|
206
|
+
their own components. Start from the reusable
|
|
207
|
+
[`component-catalog-extension.schema.json`](./ai/component-catalog-extension.schema.json)
|
|
208
|
+
and the checked
|
|
209
|
+
[`component-catalog-extension.json`](./docs/examples/component-catalog-extension.json)
|
|
210
|
+
example. Give each app-owned component or composition a stable id, selection
|
|
211
|
+
guidance, public hooks, and explicit geometry ownership; then concatenate its
|
|
212
|
+
`entries` with Kerf's shipped `entries` in the AI context. Keep package/source
|
|
213
|
+
identity alongside each input when ids could collide. This makes a combined
|
|
214
|
+
tool reason about both sides of a composition using one vocabulary without
|
|
215
|
+
pretending app-local components are `@kerfjs/ui` exports.
|
|
216
|
+
|
|
217
|
+
Composition-aware consumers use
|
|
218
|
+
[`component-catalog-extension-v2.schema.json`](./ai/component-catalog-extension-v2.schema.json),
|
|
219
|
+
its shipped TypeScript types, and the checked
|
|
220
|
+
[`component-catalog-extension-v2.json`](./docs/examples/component-catalog-extension-v2.json)
|
|
221
|
+
example. Preserve each catalog's package and qualify every identity and
|
|
222
|
+
cross-catalog reference as `package:id`; never merge entries by bare id.
|
|
223
|
+
|
|
224
|
+
[`compile-time-contracts-v1.json`](./ai/compile-time-contracts-v1.json) is the
|
|
225
|
+
matching declaration contract: stable `KUI-T###` ids identify the invalid prop,
|
|
226
|
+
state, identity, accessibility, and protected-attribute combinations TypeScript
|
|
227
|
+
rejects. The package gate compiles one positive/negative consumer fixture against
|
|
228
|
+
both source and declarations extracted from the real packed tarball. The
|
|
229
|
+
[compile-time contract guide](./docs/type-contracts.md) documents migrations and
|
|
230
|
+
the dynamic DOM/children relationships that remain runtime or catalog checks.
|
|
231
|
+
Packages scaffolded by `create-kerf-component` maintain this v2 input from
|
|
232
|
+
`kerf.components.json`: `npm run catalog:generate` emits the catalog and
|
|
233
|
+
`npm run catalog:check` verifies source files, named public exports, explicit
|
|
234
|
+
author decisions, and byte-for-byte drift. Tools index the generated consumer
|
|
235
|
+
entries and this catalog by full key, reject duplicate full keys, search the
|
|
236
|
+
consumer package first, and retain package identity across every reference.
|
|
237
|
+
They must not infer missing semantics or geometry from rendered appearance.
|
|
238
|
+
|
|
239
|
+
### Application UI profile
|
|
240
|
+
|
|
241
|
+
Applications can check in `.kerf-ui-profile.json` so tools do not have to infer
|
|
242
|
+
project-wide UI policy. Start from the shipped
|
|
243
|
+
[`application-ui-profile.defaults.json`](./ai/application-ui-profile.defaults.json)
|
|
244
|
+
and the checked
|
|
245
|
+
[`application-ui-profile.json`](./docs/examples/application-ui-profile.json)
|
|
246
|
+
workspace example. The versioned
|
|
247
|
+
[`application-ui-profile.schema.json`](./ai/application-ui-profile.schema.json)
|
|
248
|
+
and [`application-ui-profile.d.ts`](./ai/application-ui-profile.d.ts) cover
|
|
249
|
+
catalog locations, concept preferences, allowed theme/density choices, semantic
|
|
250
|
+
token overrides, layout/responsive conventions, and narrow rule exceptions.
|
|
251
|
+
Profiles contain policy only—never product records, user data, or broad styling
|
|
252
|
+
waivers.
|
|
253
|
+
|
|
254
|
+
Catalog declarations always provide a v2 `composition` location. Consumer
|
|
255
|
+
packages generated with composition-only metadata omit `selection`;
|
|
256
|
+
`@kerfjs/ui` continues to require its v1 selection catalog.
|
|
257
|
+
|
|
258
|
+
Node-based AI and static-analysis tools may import the shipped discovery API
|
|
259
|
+
from `@kerfjs/ui/ai/application-ui-profile.mjs`. It discovers package defaults,
|
|
260
|
+
then the workspace profile, then directory profiles from parent to child;
|
|
261
|
+
`mergeApplicationUiProfiles()` applies later scalar/map values, replaces a
|
|
262
|
+
catalog by package and an exception by id, and preserves source provenance.
|
|
263
|
+
`loadApplicationUiProfile()` resolves catalogs and returns diagnostics with the
|
|
264
|
+
originating file plus JSON path. Unknown/stale components, tokens, rules, and
|
|
265
|
+
catalog locations are errors. Every layer is checked against its then-effective
|
|
266
|
+
catalogs, including parent references and catalog paths later overridden by a
|
|
267
|
+
child profile. Synchronous integrations can require the shipped
|
|
268
|
+
`application-ui-profile-sync.cjs` projection and call
|
|
269
|
+
`loadApplicationUiProfileSync()` with already-discovered layers. Consumers that define additional stable
|
|
270
|
+
diagnostics pass their ids through the additive `knownRules` option; those ids
|
|
271
|
+
are merged with catalog diagnostics before exception validation.
|
|
272
|
+
|
|
273
|
+
### Static CSS and layout ownership analysis
|
|
274
|
+
|
|
275
|
+
Run `kerf-ui-analyze --root . src` (or import
|
|
276
|
+
`@kerfjs/ui/analyzer`) to evaluate cross-file integration facts against the
|
|
277
|
+
composition catalogs and application profile. It catches provable private
|
|
278
|
+
selector reach-through, unknown tokens, competing geometry owners, and nested
|
|
279
|
+
scroll owners; it reports forced dimensions, repeated insets, off-scale literal
|
|
280
|
+
spacing, and dynamic classes separately as review findings. Text, versioned JSON,
|
|
281
|
+
and SARIF outputs carry stable `KUI-L###` ids, repository-relative locations,
|
|
282
|
+
evidence, and ownership chains. See the [analyzer guide](./docs/ui-analyzer.md).
|
|
283
|
+
|
|
284
|
+
### Browser-backed integration evaluation
|
|
285
|
+
|
|
286
|
+
Run `kerf-ui-evaluate --url <running-app>` (or import
|
|
287
|
+
`@kerfjs/ui/evaluator`) after the static analyzer. Its Playwright-backed
|
|
288
|
+
wide/intermediate/narrow/200%-zoom, light/dark, and reduced-motion matrix checks
|
|
289
|
+
rendered overflow, clipping, reachability, focus/keyboard behavior, accessible
|
|
290
|
+
names, contrast, hit targets, scrolling, alignment, and cataloged runtime
|
|
291
|
+
geometry. The versioned report carries stable `KUI-B###` diagnostics, focused
|
|
292
|
+
DOM/computed-style evidence, hashed screenshot artifacts, explicit timeout and
|
|
293
|
+
retention policy, and a separate unscored human-visual rubric. See the
|
|
294
|
+
[browser evaluator guide](./docs/ui-evaluator.md).
|
|
295
|
+
|
|
296
|
+
### Unified repair-loop doctor
|
|
297
|
+
|
|
298
|
+
Use `kerf-ui-doctor` for the supported application repair loop across profile/catalog validation, TypeScript, the Kerf UI ESLint preset, static layout analysis, and an optional explicitly authorized browser evaluation. It emits one portable versioned JSON report with deterministic exit codes, exact suppressions, monorepo package selection, changed/full modes, caching, and local-path redaction. See the [UI doctor guide](./docs/ui-doctor.md).
|
|
160
299
|
|
|
161
300
|
For code generation, pair catalog selection guidance with the checked-in
|
|
162
301
|
[`public-api-signatures-v1.md`](./ai/public-api-signatures-v1.md) declaration
|
|
@@ -240,10 +379,10 @@ Apps using Web Awesome's free components can opt into the same visual universe
|
|
|
240
379
|
with one CSS import:
|
|
241
380
|
|
|
242
381
|
```ts
|
|
243
|
-
import type {} from
|
|
244
|
-
import
|
|
245
|
-
import
|
|
246
|
-
import
|
|
382
|
+
import type {} from "@kerfjs/ui/webawesome";
|
|
383
|
+
import "@kerfjs/ui/webawesome.css";
|
|
384
|
+
import "@awesome.me/webawesome/dist/components/button/button.js";
|
|
385
|
+
import "@awesome.me/webawesome/dist/components/input/input.js";
|
|
247
386
|
```
|
|
248
387
|
|
|
249
388
|
The type-only `@kerfjs/ui/webawesome` import adds Kerf JSX intrinsic-element
|
|
@@ -269,7 +408,7 @@ classes for explicit appearance boundaries:
|
|
|
269
408
|
```css
|
|
270
409
|
:root {
|
|
271
410
|
--wa-color-brand-fill-loud: #7540a8;
|
|
272
|
-
--wa-form-control-border-radius: .5rem;
|
|
411
|
+
--wa-form-control-border-radius: 0.5rem;
|
|
273
412
|
}
|
|
274
413
|
```
|
|
275
414
|
|
|
@@ -309,8 +448,8 @@ standalone `filled`/`outlined` appearance with `shape="rounded"` or
|
|
|
309
448
|
appearance="toolbar"
|
|
310
449
|
shape="pill"
|
|
311
450
|
choices={[
|
|
312
|
-
{ value:
|
|
313
|
-
{ value:
|
|
451
|
+
{ value: "list", label: "List" },
|
|
452
|
+
{ value: "columns", label: "Columns" },
|
|
314
453
|
]}
|
|
315
454
|
/>
|
|
316
455
|
```
|
|
@@ -364,8 +503,8 @@ close button retains all close interaction.
|
|
|
364
503
|
`Select` uses Web Awesome but does not register anything by itself. Install the optional peer, import the shared theme if desired, and explicitly import the registration entry in the application:
|
|
365
504
|
|
|
366
505
|
```ts
|
|
367
|
-
import
|
|
368
|
-
import
|
|
506
|
+
import "@kerfjs/ui/webawesome.css";
|
|
507
|
+
import "@kerfjs/ui/select/register";
|
|
369
508
|
```
|
|
370
509
|
|
|
371
510
|
That boundary keeps Web Awesome and its custom-element side effects out of bundles that use unrelated components. Automated consumer-bundle tests enforce it.
|
|
@@ -400,8 +539,9 @@ than default patterns. The detailed rationale lives in the theme contract.
|
|
|
400
539
|
|
|
401
540
|
Run `npm run dev` from this directory for the category-grouped master/detail catalog. Every public visual component has a focused route; all 70 free Web Awesome 3.12 components have focused routes under the collapsible ecosystem section. Every detail visibly links its first-party demo source and existing guidance while showing the repository-relative paths; first-party components also link their implementation source, and Web Awesome entries label local guidance as Kerf integration guidance. One grouped `Related components` selector contains derived `Uses` / `Used by` navigation across both sets. Run `npm run check` for static/unit/bundle gates and `npm run test:e2e` for the real-browser suite.
|
|
402
541
|
|
|
403
|
-
Run `npm run format
|
|
404
|
-
|
|
542
|
+
Run `npm run format` after editing source or structured content. The narrower
|
|
543
|
+
`npm run format:css` command remains available for style-only work. The normal
|
|
544
|
+
`npm run lint` and `npm run check` gates use Prettier to reject formatting drift.
|
|
405
545
|
|
|
406
546
|
For dimensions that should scale with the root font size, author pixels with
|
|
407
547
|
`remify()`: `gap: remify(17px)` builds to `gap: 1.0625rem` using a fixed 16px
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"ids": [
|
|
4
|
+
"KUI-B001",
|
|
5
|
+
"KUI-B010",
|
|
6
|
+
"KUI-B011",
|
|
7
|
+
"KUI-B012",
|
|
8
|
+
"KUI-B020",
|
|
9
|
+
"KUI-B021",
|
|
10
|
+
"KUI-B022",
|
|
11
|
+
"KUI-B023",
|
|
12
|
+
"KUI-B030",
|
|
13
|
+
"KUI-B040",
|
|
14
|
+
"KUI-B050",
|
|
15
|
+
"KUI-B060",
|
|
16
|
+
"KUI-B070",
|
|
17
|
+
"KUI-B080",
|
|
18
|
+
"KUI-C101",
|
|
19
|
+
"KUI-C102",
|
|
20
|
+
"KUI-C103",
|
|
21
|
+
"KUI-C104",
|
|
22
|
+
"KUI-C105",
|
|
23
|
+
"KUI-C106",
|
|
24
|
+
"KUI-C107",
|
|
25
|
+
"KUI-C108",
|
|
26
|
+
"KUI-D001",
|
|
27
|
+
"KUI-D002",
|
|
28
|
+
"KUI-D003",
|
|
29
|
+
"KUI-D010",
|
|
30
|
+
"KUI-D011",
|
|
31
|
+
"KUI-D020",
|
|
32
|
+
"KUI-L001",
|
|
33
|
+
"KUI-L002",
|
|
34
|
+
"KUI-L003",
|
|
35
|
+
"KUI-L004",
|
|
36
|
+
"KUI-L005",
|
|
37
|
+
"KUI-L006",
|
|
38
|
+
"KUI-L007",
|
|
39
|
+
"KUI-L008",
|
|
40
|
+
"KUI-L009",
|
|
41
|
+
"KUI-L090",
|
|
42
|
+
"KUI-L101",
|
|
43
|
+
"KUI-L102",
|
|
44
|
+
"KUI-L201",
|
|
45
|
+
"KUI-L202",
|
|
46
|
+
"KUI-L203",
|
|
47
|
+
"KUI-L301",
|
|
48
|
+
"KUI-L401",
|
|
49
|
+
"KUI-L402",
|
|
50
|
+
"KUI-P001",
|
|
51
|
+
"KUI-P002",
|
|
52
|
+
"KUI-P003",
|
|
53
|
+
"KUI-P004",
|
|
54
|
+
"KUI-P005",
|
|
55
|
+
"KUI-P006",
|
|
56
|
+
"KUI-P007",
|
|
57
|
+
"KUI-P008",
|
|
58
|
+
"KUI-P009",
|
|
59
|
+
"KUI-P010",
|
|
60
|
+
"KUI-P011",
|
|
61
|
+
"KUI-P012",
|
|
62
|
+
"KUI-P013",
|
|
63
|
+
"KUI-P014",
|
|
64
|
+
"KUI-P015",
|
|
65
|
+
"KUI-P016",
|
|
66
|
+
"KUI-P017",
|
|
67
|
+
"KUI-P018",
|
|
68
|
+
"KUI-P019",
|
|
69
|
+
"KUI-P020",
|
|
70
|
+
"KUI-P021",
|
|
71
|
+
"KUI-P022",
|
|
72
|
+
"KUI-P023",
|
|
73
|
+
"KUI-P024",
|
|
74
|
+
"KUI-P025",
|
|
75
|
+
"KUI-P026",
|
|
76
|
+
"KUI-P027",
|
|
77
|
+
"KUI-P028",
|
|
78
|
+
"KUI-P029",
|
|
79
|
+
"KUI-P030",
|
|
80
|
+
"KUI-T001",
|
|
81
|
+
"KUI-T002",
|
|
82
|
+
"KUI-T003",
|
|
83
|
+
"KUI-T004",
|
|
84
|
+
"KUI-T005",
|
|
85
|
+
"KUI-T006",
|
|
86
|
+
"KUI-T007",
|
|
87
|
+
"KUI-T008",
|
|
88
|
+
"KUI-T009",
|
|
89
|
+
"KUI-T010",
|
|
90
|
+
"KUI-T011"
|
|
91
|
+
]
|
|
92
|
+
}
|