@kerfjs/ui 4.4.1 → 4.5.0-beta.1
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 +425 -42
- 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 +102 -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 +319 -0
- package/ai/component-catalog-v2.d.ts +67 -0
- package/ai/component-catalog-v2.json +4675 -0
- package/ai/component-catalog-v2.schema.json +246 -0
- package/ai/component-catalog.json +5826 -0
- package/ai/component-catalog.schema.json +95 -0
- package/ai/public-api-signatures-v1.md +1719 -0
- package/ai/skill.md +129 -21
- package/ai/webawesome-jsx-signatures-v1.md +106 -0
- package/analyzer/cli.mjs +46 -0
- package/analyzer/index.d.mts +45 -0
- package/analyzer/index.mjs +737 -0
- package/analyzer/report.schema.json +66 -0
- package/dist/app-tab.d.ts +14 -2
- package/dist/app-tab.js +3 -1
- package/dist/browser/app-tab.js +3 -2
- package/dist/browser/disclosure-arrow.js +4 -0
- package/dist/browser/empty-state.js +3 -3
- package/dist/browser/floating-toolbar.js +3 -0
- package/dist/browser/list-action-row.js +4 -0
- package/dist/browser/list-header.js +6 -0
- package/dist/browser/list-inset-control.js +3 -0
- package/dist/browser/list-inset-text.js +3 -0
- package/dist/browser/list-item.js +4 -0
- package/dist/browser/list.js +3 -0
- package/dist/browser/loading-spinner.js +2 -2
- package/dist/browser/lucide-icon.js +2 -2
- package/dist/browser/pane.js +3 -0
- package/dist/browser/panel-header.js +7 -0
- package/dist/browser/resizable-region.js +2 -2
- package/dist/browser/segmented-control.js +3 -2
- package/dist/browser/select.js +4 -3
- package/dist/browser/skeleton.js +3 -0
- package/dist/browser/state-banner.js +3 -2
- package/dist/browser/sunken-panel.js +3 -0
- package/dist/browser/tab-bar.js +2 -2
- package/dist/browser/token-search-field.js +4 -0
- package/dist/browser/toolbar-control-group.js +2 -2
- package/dist/browser/toolbar-text.js +3 -2
- package/dist/browser/toolbar.js +2 -2
- package/dist/browser/value-table.js +3 -2
- 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 +150 -0
- package/dist/catalog.js +377 -0
- package/dist/catalog.js.map +1 -0
- 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-7XRDUG4Y.js +58 -0
- package/dist/chunk-7XRDUG4Y.js.map +1 -0
- package/dist/chunk-B3A3IVO5.js +83 -0
- package/dist/chunk-B3A3IVO5.js.map +1 -0
- package/dist/chunk-DPDBVKNA.js +113 -0
- package/dist/chunk-DPDBVKNA.js.map +1 -0
- package/dist/chunk-FEAMR7S4.js +68 -0
- package/dist/chunk-FEAMR7S4.js.map +1 -0
- package/dist/chunk-FEY65TBV.js +15 -0
- package/dist/chunk-FEY65TBV.js.map +1 -0
- package/dist/{chunk-TRNBHPNW.js → chunk-IJBSZ4NX.js} +11 -8
- package/dist/chunk-IJBSZ4NX.js.map +1 -0
- package/dist/chunk-J5BFYY7Q.js +35 -0
- package/dist/chunk-J5BFYY7Q.js.map +1 -0
- package/dist/chunk-JRKSK2HX.js +79 -0
- package/dist/chunk-JRKSK2HX.js.map +1 -0
- package/dist/chunk-KWWR5VMS.js +45 -0
- package/dist/chunk-KWWR5VMS.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-NWSEP5RT.js +117 -0
- package/dist/chunk-NWSEP5RT.js.map +1 -0
- package/dist/chunk-OJWWHFH3.js +426 -0
- package/dist/chunk-OJWWHFH3.js.map +1 -0
- package/dist/chunk-PSKN344N.js +114 -0
- package/dist/chunk-PSKN344N.js.map +1 -0
- package/dist/chunk-PX3YSS5C.js +32 -0
- package/dist/chunk-PX3YSS5C.js.map +1 -0
- package/dist/chunk-QO55FN2Y.js +20 -0
- package/dist/chunk-QO55FN2Y.js.map +1 -0
- package/dist/chunk-R7ZWUN64.js +38 -0
- package/dist/chunk-R7ZWUN64.js.map +1 -0
- package/dist/chunk-RKVQEH4J.js +61 -0
- package/dist/chunk-RKVQEH4J.js.map +1 -0
- package/dist/chunk-SRSJO5QE.js +40 -0
- package/dist/chunk-SRSJO5QE.js.map +1 -0
- package/dist/chunk-SYDMYBPG.js +31 -0
- package/dist/chunk-SYDMYBPG.js.map +1 -0
- package/dist/chunk-TB6DY7H5.js +25 -0
- package/dist/chunk-TB6DY7H5.js.map +1 -0
- package/dist/chunk-UFZKLBCF.js +108 -0
- package/dist/chunk-UFZKLBCF.js.map +1 -0
- package/dist/{chunk-MQIZAD4A.js → chunk-UKKSMZYT.js} +76 -22
- package/dist/chunk-UKKSMZYT.js.map +1 -0
- package/dist/chunk-W5L2JSBY.js +40 -0
- package/dist/chunk-W5L2JSBY.js.map +1 -0
- package/dist/chunk-Y45PPBDV.js +105 -0
- package/dist/chunk-Y45PPBDV.js.map +1 -0
- package/dist/chunk-Y6LYKFXY.js +43 -0
- package/dist/chunk-Y6LYKFXY.js.map +1 -0
- package/dist/collapsible-panel.d.ts +66 -0
- package/dist/collapsible-panel.js +63 -0
- package/dist/collapsible-panel.js.map +1 -0
- package/dist/device-class.d.ts +62 -0
- package/dist/device-class.js +103 -0
- package/dist/device-class.js.map +1 -0
- package/dist/disclosure-arrow.d.ts +14 -0
- package/dist/disclosure-arrow.js +4 -0
- package/dist/disclosure-arrow.js.map +1 -0
- package/dist/divider-sides-267FA7sY.d.ts +4 -0
- package/dist/empty-state.d.ts +1 -1
- package/dist/empty-state.js +1 -1
- package/dist/floating-toolbar.d.ts +28 -0
- package/dist/floating-toolbar.js +3 -0
- package/dist/floating-toolbar.js.map +1 -0
- package/dist/index.d.ts +20 -9
- package/dist/index.js +29 -18
- package/dist/list-action-row.d.ts +52 -0
- package/dist/list-action-row.js +5 -0
- package/dist/list-action-row.js.map +1 -0
- package/dist/list-header.d.ts +64 -0
- package/dist/list-header.js +7 -0
- package/dist/list-header.js.map +1 -0
- package/dist/list-inset-control.d.ts +16 -0
- package/dist/list-inset-control.js +3 -0
- package/dist/list-inset-control.js.map +1 -0
- package/dist/list-inset-text.d.ts +25 -0
- package/dist/list-inset-text.js +3 -0
- package/dist/list-inset-text.js.map +1 -0
- package/dist/list-item.d.ts +33 -0
- package/dist/list-item.js +5 -0
- package/dist/list-item.js.map +1 -0
- package/dist/list.d.ts +19 -0
- package/dist/list.js +3 -0
- package/dist/list.js.map +1 -0
- package/dist/loading-spinner.js +1 -1
- package/dist/nav-stack.d.ts +38 -0
- package/dist/nav-stack.js +5 -0
- package/dist/nav-stack.js.map +1 -0
- 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 +42 -0
- package/dist/panel-header.js +7 -0
- package/dist/panel-header.js.map +1 -0
- package/dist/resizable-region.d.ts +3 -1
- package/dist/resizable-region.js +1 -1
- package/dist/segmented-control.d.ts +8 -6
- package/dist/segmented-control.js +2 -1
- package/dist/select-register.d.ts +5 -1
- package/dist/select-register.js +3 -0
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +15 -6
- package/dist/select.js +2 -1
- package/dist/skeleton.d.ts +24 -0
- package/dist/skeleton.js +3 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/split-view.d.ts +42 -0
- package/dist/split-view.js +81 -0
- package/dist/split-view.js.map +1 -0
- package/dist/state-banner.d.ts +8 -3
- package/dist/state-banner.js +2 -1
- package/dist/styles/app-tab.css +152 -0
- package/dist/styles/catalog.css +575 -0
- package/dist/styles/collapsible-panel.css +146 -0
- package/dist/styles/disclosure-arrow.css +23 -0
- package/dist/styles/empty-state.css +47 -0
- package/dist/styles/floating-toolbar.css +38 -0
- package/dist/styles/foundation.css +362 -0
- package/dist/styles/layout.css +55 -0
- package/dist/styles/list-action-row.css +160 -0
- package/dist/styles/list-header.css +160 -0
- package/dist/styles/list-inset-control.css +7 -0
- package/dist/styles/list-inset-text.css +14 -0
- package/dist/styles/list-item.css +123 -0
- package/dist/styles/list.css +43 -0
- package/dist/styles/loading-spinner.css +21 -0
- package/dist/styles/lucide-icon.css +6 -0
- package/dist/styles/nav-stack.css +111 -0
- package/dist/styles/pane.css +62 -0
- package/dist/styles/panel-header.css +64 -0
- package/dist/styles/resizable-region.css +111 -0
- package/{src → dist/styles}/segmented-control.css +58 -31
- package/dist/styles/select.css +140 -0
- package/dist/styles/skeleton.css +31 -0
- package/dist/styles/split-view.css +35 -0
- package/dist/styles/state-banner.css +198 -0
- package/dist/styles/styles.css +24 -0
- package/dist/styles/sunken-panel.css +22 -0
- package/dist/styles/tab-bar.css +45 -0
- package/dist/styles/tab-scaffold.css +84 -0
- package/dist/styles/token-search-field.css +289 -0
- package/dist/styles/toolbar-control-group.css +225 -0
- package/dist/styles/toolbar-text.css +92 -0
- package/dist/styles/toolbar.css +97 -0
- package/dist/styles/value-table.css +75 -0
- package/dist/styles/webawesome.css +399 -0
- package/dist/styles/workbench.css +94 -0
- package/dist/sunken-panel.d.ts +19 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/tab-bar.d.ts +10 -2
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +30 -0
- package/dist/tab-scaffold.js +51 -0
- package/dist/tab-scaffold.js.map +1 -0
- package/dist/token-search-field.d.ts +59 -0
- package/dist/token-search-field.js +4 -0
- package/dist/token-search-field.js.map +1 -0
- package/dist/toolbar-control-group.d.ts +11 -5
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +31 -4
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +5 -3
- package/dist/toolbar.js +1 -1
- package/dist/value-table.d.ts +13 -3
- package/dist/value-table.js +2 -1
- package/dist/webawesome.d.ts +100 -0
- package/dist/webawesome.js +3 -0
- package/dist/webawesome.js.map +1 -0
- package/dist/wire-catalog.d.ts +57 -0
- package/dist/wire-catalog.js +302 -0
- package/dist/wire-catalog.js.map +1 -0
- package/dist/wire-nav-stack.d.ts +15 -0
- package/dist/wire-nav-stack.js +103 -0
- package/dist/wire-nav-stack.js.map +1 -0
- package/dist/wire-resizable-regions.d.ts +1 -1
- package/dist/wire-resizable-regions.js +1 -1
- package/dist/wire-sidebar.d.ts +43 -0
- package/dist/wire-sidebar.js +128 -0
- package/dist/wire-sidebar.js.map +1 -0
- package/dist/wire-tab-bars.d.ts +18 -2
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-scaffold.d.ts +11 -0
- package/dist/wire-tab-scaffold.js +21 -0
- package/dist/wire-tab-scaffold.js.map +1 -0
- package/dist/wire-token-search-fields.d.ts +111 -0
- package/dist/wire-token-search-fields.js +5 -0
- package/dist/wire-token-search-fields.js.map +1 -0
- package/dist/workbench.d.ts +33 -0
- package/dist/workbench.js +64 -0
- package/dist/workbench.js.map +1 -0
- package/docs/accessibility.md +124 -4
- package/docs/app-layouts.md +61 -0
- package/docs/catalog.md +364 -0
- package/docs/collapsible-panel.md +129 -0
- package/docs/component-contract.md +312 -5
- package/docs/component-selection.md +219 -0
- package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
- package/docs/design/templates/empty-state/filtered.svg +1 -0
- package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
- package/docs/design/templates/empty-state/with-action.svg +1 -0
- package/docs/design/templates/empty-state-dark.svg +1 -0
- package/docs/design/templates/empty-state.svg +1 -0
- package/docs/design/templates/list/compact-dark.svg +1 -0
- package/docs/design/templates/list/compact.svg +1 -0
- package/docs/design/templates/list/stack-dark.svg +1 -0
- package/docs/design/templates/list/stack.svg +1 -0
- package/docs/design/templates/list-action-row/default-dark.svg +1 -0
- package/docs/design/templates/list-action-row/default.svg +1 -0
- package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
- package/docs/design/templates/list-action-row/selected.svg +1 -0
- package/docs/design/templates/list-action-row-dark.svg +1 -0
- package/docs/design/templates/list-action-row.svg +1 -0
- package/docs/design/templates/list-dark.svg +1 -0
- package/docs/design/templates/list-header/action-dark.svg +1 -0
- package/docs/design/templates/list-header/action.svg +1 -0
- package/docs/design/templates/list-header/count-dark.svg +1 -0
- package/docs/design/templates/list-header/count.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
- package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
- package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
- package/docs/design/templates/list-header-dark.svg +1 -0
- package/docs/design/templates/list-header.svg +1 -0
- package/docs/design/templates/list-item/default-dark.svg +1 -0
- package/docs/design/templates/list-item/default.svg +1 -0
- package/docs/design/templates/list-item/multiline-dark.svg +1 -0
- package/docs/design/templates/list-item/multiline.svg +1 -0
- package/docs/design/templates/list-item/selected-dark.svg +1 -0
- package/docs/design/templates/list-item/selected.svg +1 -0
- package/docs/design/templates/list-item/trailing-dark.svg +1 -0
- package/docs/design/templates/list-item/trailing.svg +1 -0
- package/docs/design/templates/list-item-dark.svg +1 -0
- package/docs/design/templates/list-item.svg +1 -0
- package/docs/design/templates/list.svg +1 -0
- package/docs/design/templates/panel-header/icon-actions-dark.svg +1 -0
- package/docs/design/templates/panel-header/icon-actions.svg +1 -0
- package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +1 -0
- package/docs/design/templates/panel-header/icon-summary-actions.svg +1 -0
- package/docs/design/templates/panel-header/no-icon-dark.svg +1 -0
- package/docs/design/templates/panel-header/no-icon.svg +1 -0
- package/docs/design/templates/panel-header/page-heading-dark.svg +1 -0
- package/docs/design/templates/panel-header/page-heading.svg +1 -0
- package/docs/design/templates/panel-header/title-only-dark.svg +1 -0
- package/docs/design/templates/panel-header/title-only.svg +1 -0
- package/docs/design/templates/panel-header-dark.svg +1 -0
- package/docs/design/templates/panel-header.svg +1 -0
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
- package/docs/design/templates/segmented-control/equal.svg +1 -0
- package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
- package/docs/design/templates/segmented-control/pill-small.svg +1 -0
- package/docs/design/templates/segmented-control-dark.svg +1 -0
- package/docs/design/templates/segmented-control.svg +1 -0
- package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
- package/docs/design/templates/skeleton/avatar.svg +1 -0
- package/docs/design/templates/skeleton/block-dark.svg +1 -0
- package/docs/design/templates/skeleton/block.svg +1 -0
- package/docs/design/templates/skeleton/lines-dark.svg +1 -0
- package/docs/design/templates/skeleton/lines.svg +1 -0
- package/docs/design/templates/skeleton-dark.svg +1 -0
- package/docs/design/templates/skeleton.svg +1 -0
- package/docs/design/templates/state-banner/danger-dark.svg +1 -0
- package/docs/design/templates/state-banner/danger.svg +1 -0
- package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
- package/docs/design/templates/state-banner/info-badge.svg +1 -0
- package/docs/design/templates/state-banner/info-dark.svg +1 -0
- package/docs/design/templates/state-banner/info.svg +1 -0
- package/docs/design/templates/state-banner/success-dark.svg +1 -0
- package/docs/design/templates/state-banner/success.svg +1 -0
- package/docs/design/templates/state-banner/warning-dark.svg +1 -0
- package/docs/design/templates/state-banner/warning.svg +1 -0
- package/docs/design/templates/state-banner-dark.svg +1 -0
- package/docs/design/templates/state-banner.svg +1 -0
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
- package/docs/design/templates/tab-bar-dark.svg +1 -0
- package/docs/design/templates/tab-bar.svg +1 -0
- package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
- package/docs/design/templates/token-search-field/empty.svg +1 -0
- package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
- package/docs/design/templates/token-search-field/tokens.svg +1 -0
- package/docs/design/templates/token-search-field-dark.svg +1 -0
- package/docs/design/templates/token-search-field.svg +1 -0
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group.svg +1 -0
- package/docs/design/templates/toolbar-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/default.svg +1 -0
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/large.svg +1 -0
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/small.svg +1 -0
- package/docs/design/templates/toolbar-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-text.svg +1 -0
- package/docs/design/templates/toolbar.svg +1 -0
- package/docs/design/templates/value-table/details-dark.svg +1 -0
- package/docs/design/templates/value-table/details.svg +1 -0
- package/docs/design/templates/value-table-dark.svg +1 -0
- package/docs/design/templates/value-table.svg +1 -0
- package/docs/design/templates.md +130 -0
- package/docs/design-philosophy.md +59 -1
- package/docs/device-class.md +54 -0
- package/docs/examples/application-ui-profile.json +60 -0
- package/docs/examples/command-palette-adapter.tsx +120 -0
- package/docs/examples/component-catalog-extension-v2.json +81 -0
- package/docs/examples/component-catalog-extension.json +45 -0
- package/docs/layout.md +150 -0
- package/docs/nav-stack.md +56 -0
- package/docs/recipes.md +167 -0
- package/docs/split-view.md +49 -0
- package/docs/sunken-panel.md +53 -0
- package/docs/tab-scaffold.md +50 -0
- package/docs/type-contracts.md +102 -0
- package/docs/ui-analyzer.md +86 -0
- package/docs/ui-doctor.md +84 -0
- package/docs/ui-evaluator.md +122 -0
- package/docs/ux-demo.md +23 -9
- package/docs/webawesome-theme.md +87 -7
- package/docs/workbench.md +73 -0
- package/doctor/cli.mjs +115 -0
- package/doctor/config.schema.json +68 -0
- package/doctor/eslint-diagnostics.d.mts +8 -0
- package/doctor/eslint-diagnostics.mjs +7 -0
- package/doctor/index.d.mts +116 -0
- package/doctor/index.mjs +1257 -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 +197 -14
- package/package.json +228 -46
- package/traversal-exclusions.mjs +27 -0
- package/ux-demo/recipes/app-shell.tsx +228 -0
- package/ux-demo/recipes/collapsible-sidebar.tsx +223 -0
- package/ux-demo/recipes/compact-toolbar.tsx +145 -0
- package/ux-demo/recipes/composer-form.tsx +151 -0
- package/ux-demo/recipes/list-detail-dialog.tsx +181 -0
- package/ux-demo/recipes/list-workspace-states.tsx +183 -0
- package/ux-demo/recipes/loaders.ts +36 -0
- package/ux-demo/recipes/loading-inspector.tsx +164 -0
- package/ux-demo/recipes/mount-recipe.ts +64 -0
- package/ux-demo/recipes/navigation-sidebar.tsx +137 -0
- package/ux-demo/recipes/navigation-stack.tsx +118 -0
- package/ux-demo/recipes/recipes.css +448 -0
- package/ux-demo/recipes/types.ts +19 -0
- package/ux-demo/recipes/workspace-header.tsx +67 -0
- package/dist/browser/dialog-header.js +0 -3
- package/dist/browser/menu-header.js +0 -3
- package/dist/browser/menu-item.js +0 -3
- package/dist/browser/page-header.js +0 -3
- package/dist/chunk-2PES33HS.js +0 -13
- package/dist/chunk-2PES33HS.js.map +0 -1
- package/dist/chunk-3O7ZEUW2.js +0 -27
- package/dist/chunk-3O7ZEUW2.js.map +0 -1
- package/dist/chunk-4HHCYSGT.js +0 -79
- package/dist/chunk-4HHCYSGT.js.map +0 -1
- package/dist/chunk-55DATV3A.js +0 -10
- package/dist/chunk-55DATV3A.js.map +0 -1
- package/dist/chunk-723YNJBH.js +0 -17
- package/dist/chunk-723YNJBH.js.map +0 -1
- package/dist/chunk-DAFFDO33.js +0 -14
- package/dist/chunk-DAFFDO33.js.map +0 -1
- package/dist/chunk-GY5WH7TO.js +0 -10
- package/dist/chunk-GY5WH7TO.js.map +0 -1
- package/dist/chunk-MBR3TYNL.js +0 -14
- package/dist/chunk-MBR3TYNL.js.map +0 -1
- package/dist/chunk-MFKMHK5W.js +0 -10
- package/dist/chunk-MFKMHK5W.js.map +0 -1
- package/dist/chunk-MQIZAD4A.js.map +0 -1
- package/dist/chunk-NHXX4JI5.js +0 -28
- package/dist/chunk-NHXX4JI5.js.map +0 -1
- package/dist/chunk-OPCJRCYO.js +0 -19
- package/dist/chunk-OPCJRCYO.js.map +0 -1
- package/dist/chunk-T5XNMVOI.js +0 -24
- package/dist/chunk-T5XNMVOI.js.map +0 -1
- package/dist/chunk-TRNBHPNW.js.map +0 -1
- package/dist/chunk-VHW5YNIB.js +0 -17
- package/dist/chunk-VHW5YNIB.js.map +0 -1
- package/dist/chunk-VKH2JLDZ.js +0 -10
- package/dist/chunk-VKH2JLDZ.js.map +0 -1
- package/dist/chunk-WVPYVDXY.js +0 -15
- package/dist/chunk-WVPYVDXY.js.map +0 -1
- package/dist/chunk-WY4CAEPG.js +0 -14
- package/dist/chunk-WY4CAEPG.js.map +0 -1
- package/dist/dialog-header.d.ts +0 -14
- package/dist/dialog-header.js +0 -3
- package/dist/dialog-header.js.map +0 -1
- package/dist/menu-header.d.ts +0 -15
- package/dist/menu-header.js +0 -3
- package/dist/menu-header.js.map +0 -1
- package/dist/menu-item.d.ts +0 -22
- package/dist/menu-item.js +0 -3
- package/dist/menu-item.js.map +0 -1
- package/dist/page-header.d.ts +0 -9
- package/dist/page-header.js +0 -3
- package/dist/page-header.js.map +0 -1
- package/src/app-tab.css +0 -20
- package/src/dialog-header.css +0 -9
- package/src/empty-state.css +0 -6
- package/src/foundation.css +0 -106
- package/src/loading-spinner.css +0 -4
- package/src/lucide-icon.css +0 -1
- package/src/menu-header.css +0 -13
- package/src/menu-item.css +0 -12
- package/src/page-header.css +0 -3
- package/src/resizable-region.css +0 -19
- package/src/select.css +0 -18
- package/src/state-banner.css +0 -31
- package/src/styles.css +0 -18
- package/src/tab-bar.css +0 -4
- package/src/toolbar-control-group.css +0 -25
- package/src/toolbar-text.css +0 -4
- package/src/toolbar.css +0 -9
- package/src/value-table.css +0 -5
- package/src/webawesome.css +0 -178
|
@@ -2,17 +2,221 @@
|
|
|
2
2
|
|
|
3
3
|
`@kerfjs/ui` components are plain functions that return Kerf `SafeHtml`. They have no component instance or lifecycle.
|
|
4
4
|
|
|
5
|
+
## Selection boundary
|
|
6
|
+
|
|
7
|
+
Begin with the [need-first component matrix](./component-selection.md). Reuse a
|
|
8
|
+
primitive only when purpose, anatomy, state, and interaction match. Compose
|
|
9
|
+
public primitives for recurring layout; add a thin application adapter for
|
|
10
|
+
product state and policy; use custom markup when the semantic contract differs.
|
|
11
|
+
Recurring cross-product custom patterns belong in an upstream component or
|
|
12
|
+
recipe request, not in duplicated markup or selectors for undocumented anatomy.
|
|
13
|
+
|
|
14
|
+
The shipped [`component-catalog.json`](../ai/component-catalog.json) is the
|
|
15
|
+
canonical machine-readable inventory. Its facts are projected into the UX
|
|
16
|
+
catalog deterministically; package checks compare them with runtime exports,
|
|
17
|
+
package delivery paths, Web Awesome's installed manifest, AI guidance, and
|
|
18
|
+
documentation links. Nuanced prose in this contract and the selection guide
|
|
19
|
+
remains authored rather than generated.
|
|
20
|
+
|
|
21
|
+
### Composition catalog v2
|
|
22
|
+
|
|
23
|
+
[`component-catalog-v2.json`](../ai/component-catalog-v2.json) adds a formal,
|
|
24
|
+
machine-evaluable composition layer without changing the v1 selection and
|
|
25
|
+
delivery contract. Every v1 entry projects once, in order, under the stable
|
|
26
|
+
qualified key `package:id`. Each v2 entry explicitly covers parents/contexts,
|
|
27
|
+
named zones and cardinality, child concepts, state ownership, required wiring,
|
|
28
|
+
responsive ownership, layout and geometry, accessibility obligations, public
|
|
29
|
+
CSS boundaries, diagnostics, and provenance.
|
|
30
|
+
|
|
31
|
+
The generator starts with permissive defaults. An `any` mode records that the
|
|
32
|
+
catalog has no defensible prohibition; it does not claim every composition is
|
|
33
|
+
recommended. Objective rules live in
|
|
34
|
+
`component-catalog-v2-overrides.json` and may carry stable `KUI-C###`
|
|
35
|
+
diagnostics. A tool reports a diagnostic only after proving its exact `when`
|
|
36
|
+
condition. Subjective choice, product policy, and visual taste remain prose.
|
|
37
|
+
|
|
38
|
+
V1 consumers continue unchanged. V2 consumers read v1 for selection/delivery
|
|
39
|
+
and v2 for composition. `npm run catalog:sync` projects every new component,
|
|
40
|
+
recipe, and supported Web Awesome entry, and the completeness gate prevents
|
|
41
|
+
silent omissions. Downstream catalogs use the v2 extension schema and types,
|
|
42
|
+
retain their own package identity, and qualify cross-catalog references. See
|
|
43
|
+
the checked
|
|
44
|
+
[`component-catalog-extension-v2.json`](./examples/component-catalog-extension-v2.json)
|
|
45
|
+
application-owned example.
|
|
46
|
+
|
|
47
|
+
### Compile-time contract boundary
|
|
48
|
+
|
|
49
|
+
The versioned
|
|
50
|
+
[`compile-time-contracts-v1.json`](../ai/compile-time-contracts-v1.json)
|
|
51
|
+
artifact maps stable `KUI-T###` ids to public imports, emitted symbols, and
|
|
52
|
+
catalog identities. Its positive/negative fixture compiles against both source
|
|
53
|
+
and a freshly packed package, so source declarations and shipped declarations
|
|
54
|
+
cannot silently diverge. See [Compile-time contracts](./type-contracts.md) for
|
|
55
|
+
the full audit, migration guidance, and the relationships deliberately left to
|
|
56
|
+
runtime/catalog checks because TypeScript cannot prove them.
|
|
57
|
+
|
|
58
|
+
### Application UI profile
|
|
59
|
+
|
|
60
|
+
The component catalogs describe what packages provide; an application profile
|
|
61
|
+
describes which supported choices a project has approved. A workspace may
|
|
62
|
+
check in `.kerf-ui-profile.json` conforming to
|
|
63
|
+
[`application-ui-profile.schema.json`](../ai/application-ui-profile.schema.json).
|
|
64
|
+
Keep package-qualified catalog locations and recurring-concept preferences,
|
|
65
|
+
allowed color schemes and density, public semantic-token overrides,
|
|
66
|
+
layout/responsive conventions, and narrow rule exceptions there. Product
|
|
67
|
+
records, copy, permissions, user preferences, and transport state do not belong
|
|
68
|
+
in this policy file.
|
|
69
|
+
|
|
70
|
+
Every catalog location names a v2 composition artifact. `selection` is optional
|
|
71
|
+
for consumer packages whose generated metadata declares v1 selection guidance
|
|
72
|
+
not applicable; `@kerfjs/ui` retains its required v1 selection artifact. This
|
|
73
|
+
lets a generated `component-catalog-v2.json` participate directly without a
|
|
74
|
+
fabricated compatibility file.
|
|
75
|
+
|
|
76
|
+
Discovery and precedence are deterministic:
|
|
77
|
+
|
|
78
|
+
1. Load `application-ui-profile.defaults.json` from `@kerfjs/ui`.
|
|
79
|
+
2. Load `.kerf-ui-profile.json` at the workspace root when present.
|
|
80
|
+
3. Walk from the workspace root toward the target directory and load each
|
|
81
|
+
directory-local profile in parent-to-child order.
|
|
82
|
+
|
|
83
|
+
Later scalar and object-map values win. Catalogs merge by package; preferences
|
|
84
|
+
and token overrides merge by key; exceptions merge by stable id. Lists such as
|
|
85
|
+
allowed themes/densities replace the earlier list rather than accumulating.
|
|
86
|
+
Every resolved field retains its source file. The shipped
|
|
87
|
+
`application-ui-profile.mjs` API implements discovery, merge, loading, and
|
|
88
|
+
validation and reports actionable originating file + JSON-path diagnostics for stale
|
|
89
|
+
catalogs, unknown component/rule/token references, preference conflicts, and
|
|
90
|
+
broad exceptions. Each raw layer is validated against the catalogs effective at
|
|
91
|
+
that exact precedence point before merge, so a broken parent catalog, stale
|
|
92
|
+
parent reference, invalid value, or unknown field cannot disappear merely
|
|
93
|
+
because a child profile replaces it. The shipped
|
|
94
|
+
`application-ui-profile-sync.cjs` projects the same merge and validation contract
|
|
95
|
+
for synchronous hosts such as ESLint rules; it deliberately performs no async
|
|
96
|
+
I/O.
|
|
97
|
+
See the
|
|
98
|
+
[`application-ui-profile.json`](./examples/application-ui-profile.json) example.
|
|
99
|
+
|
|
100
|
+
Catalog detail footers use one standard resource vocabulary and order. Build
|
|
101
|
+
them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo source`
|
|
102
|
+
first, optional `Component source` and `Design template`, then `Guidance`.
|
|
103
|
+
Third-party entries use the typed `integrationGuidance` kind, which renders
|
|
104
|
+
`Integration guidance`, and omit `Component source` when the implementation is
|
|
105
|
+
not owned by the catalog's project. Prefer these semantic kinds over local labels
|
|
106
|
+
such as “View source” or “Read UI guidance”; the helper makes that convention a
|
|
107
|
+
compile-time choice while still returning ordinary `CatalogResource[]` values.
|
|
108
|
+
|
|
5
109
|
## Ownership boundaries
|
|
6
110
|
|
|
111
|
+
### Geometry ownership metadata
|
|
112
|
+
|
|
113
|
+
The canonical [`component-catalog.json`](../ai/component-catalog.json) records
|
|
114
|
+
the margin, border, and padding owner for every component and composition under
|
|
115
|
+
`geometry`. Read it before adding a wrapper or local spacing rule:
|
|
116
|
+
|
|
117
|
+
- `self` means the entry's public visual contract supplies that geometry.
|
|
118
|
+
- `parent` means the embedding layout must supply it.
|
|
119
|
+
- `child` means composed descendants supply it; the entry's outer shell does not.
|
|
120
|
+
- `none` means that dimension is intentionally absent from the standard contract.
|
|
121
|
+
- `conditional` means a variant, part, or configuration changes ownership; the
|
|
122
|
+
accompanying `notes` explain the boundary.
|
|
123
|
+
|
|
124
|
+
The values describe public ownership, including themed shadow parts, rather
|
|
125
|
+
than merely asking whether a CSS declaration appears on the host element.
|
|
126
|
+
Recipes are exempt because they arrange entries whose individual ownership is
|
|
127
|
+
already cataloged.
|
|
128
|
+
|
|
129
|
+
Downstream packages and applications should publish the same contract for their
|
|
130
|
+
reusable visual components. Use
|
|
131
|
+
[`component-catalog-extension.schema.json`](../ai/component-catalog-extension.schema.json)
|
|
132
|
+
and copy the structure of the checked
|
|
133
|
+
[`component-catalog-extension.json`](./examples/component-catalog-extension.json)
|
|
134
|
+
example. Keep app and Kerf entries as package-qualified inputs, then let people
|
|
135
|
+
or AI tools search their combined entries and compare `geometry` before adding
|
|
136
|
+
wrappers or insets. Do not add app-owned entries to Kerf's canonical catalog or
|
|
137
|
+
claim Kerf delivery paths for them.
|
|
138
|
+
|
|
7
139
|
- Components own semantic markup, stable anatomy, documented variants, ARIA projection, and package CSS hooks.
|
|
8
140
|
- Applications own signals/stores, product copy, domain-state mapping, persistence, routing, permissions, and transport.
|
|
9
141
|
- Actions are `data-action` strings. Wire them at a stable root with `delegate()` or `delegateActions()` and retain the disposer.
|
|
10
142
|
- A reusable component never owns per-instance mutable module state.
|
|
11
|
-
- Consumers style through `--kui-*` semantic tokens and public component classes. Foundation tokens provide opinionated neutral, brand/info, success, warning, and danger fill/border/foreground roles. Stateful components expose local override variables;
|
|
143
|
+
- Consumers style through `--kui-*` semantic tokens and public component classes. Foundation tokens provide opinionated neutral, brand/info, success, warning, and danger fill/border/foreground roles. Stateful components expose local override variables; prefer an equivalent prop or token before writing a selector.
|
|
144
|
+
|
|
145
|
+
`ListItem.rootAttributes`, `ListActionRow.rootAttributes`,
|
|
146
|
+
`ListHeader.rootAttributes`, `AppTab.rootAttributes`,
|
|
147
|
+
`CatalogExample.rootAttributes`, and `CatalogExampleStack.rootAttributes` accept
|
|
148
|
+
application-owned `data-*` metadata without
|
|
149
|
+
adding product fields to the shared API. A `ListActionRow` trailing action uses
|
|
150
|
+
`trailingActionAttributes`, and a `ListHeader` action/disclosure uses
|
|
151
|
+
`triggerAttributes`, for `data-*`, native popover target/action attributes, and
|
|
152
|
+
the corresponding `aria-controls`/`aria-haspopup` relationship. These slots do
|
|
153
|
+
not accept roles or component-owned action, selection, disclosure, accessible
|
|
154
|
+
name, disabled, or icon fields. Extension objects are filtered at runtime,
|
|
155
|
+
including case-insensitive rejection of protected `data-*` names, and the
|
|
156
|
+
component or helper writes its protected attributes after the accepted metadata. Typed,
|
|
157
|
+
structurally widened, and JavaScript callers therefore cannot replace its
|
|
158
|
+
contract.
|
|
159
|
+
|
|
160
|
+
`AppTab.closeIcon` and `ResizableRegion.handleIcon` replace dormant decorative
|
|
161
|
+
glyph content only. They must not contain controls or interactive roles. The
|
|
162
|
+
component continues to own the named close button or focusable separator, and
|
|
163
|
+
`wireTabBars()` / `wireResizableRegions()` continue to own transient behavior
|
|
164
|
+
and disposal.
|
|
165
|
+
|
|
166
|
+
`ListItem.trailing`, `ListActionRow.label`, `ListActionRow.icon`, and
|
|
167
|
+
`ListActionRow.trailingActionIcon` are dormant SafeHtml slots. They must not
|
|
168
|
+
contain controls. When a row needs an independently interactive trailing
|
|
169
|
+
region, `ListActionRow` owns the noninteractive root and the two sibling native
|
|
170
|
+
buttons; the application owns their delegated behavior and controlled state.
|
|
171
|
+
Both row components align a leading icon with the first label line when
|
|
172
|
+
`multiline` allows the label to wrap; additional lines extend below that fixed
|
|
173
|
+
visual anchor.
|
|
174
|
+
|
|
175
|
+
### Public CSS anatomy
|
|
176
|
+
|
|
177
|
+
The `publicClasses` array on each entry in
|
|
178
|
+
[`component-catalog.json`](../ai/component-catalog.json) is the exact supported
|
|
179
|
+
anatomy boundary. A scoped selector may join documented public classes, such as
|
|
180
|
+
`.workspace .kui-toolbar .kui-toolbar__trailing`, when composition-specific
|
|
181
|
+
layout cannot be expressed by a prop or token. A class being public does not
|
|
182
|
+
make copied component markup an invocation or transfer state and accessibility
|
|
183
|
+
ownership to the application.
|
|
184
|
+
|
|
185
|
+
The v2 composition catalog additionally requires `boundaries.rootClass` to be
|
|
186
|
+
either one exact member of `publicClasses` or `null` when the entry has no
|
|
187
|
+
rendered class root. Runtime geometry tooling uses this explicit field; array
|
|
188
|
+
order never implies root ownership.
|
|
189
|
+
|
|
190
|
+
Do not select a component's descendant by element name, id, attribute alone, or
|
|
191
|
+
an unlisted implementation class. Selectors such as `.kui-state-banner span`,
|
|
192
|
+
`.kui-list-item [data-state]`, and `.kui-list-item .local-label` depend on
|
|
193
|
+
private structure. If no prop, token, or cataloged class expresses a recurring
|
|
194
|
+
need, request a supported hook instead of inferring one from rendered markup.
|
|
195
|
+
|
|
196
|
+
`ListItem` renders its leading icon and nested SVG at a root-scaled 18px by
|
|
197
|
+
default while retaining the row's 44px minimum interactive target. Multiline
|
|
198
|
+
rows align that 18px visual with the first inherited text line.
|
|
199
|
+
|
|
200
|
+
`DisclosureArrow` uses an 18px root-scaled visual by default. Override
|
|
201
|
+
`--kui-disclosure-arrow-size` on the component or its containing scope when a
|
|
202
|
+
consumer needs another size. Kerf `Select` uses a separate Web Awesome expand
|
|
203
|
+
glyph contract, `--kui-disclosure-icon-scale: .5`; changing one contract does
|
|
204
|
+
not implicitly change the other. Direction changes take the shortest rotation
|
|
205
|
+
path; a 180-degree closed-to-open tie uses counterclockwise rotation.
|
|
206
|
+
|
|
207
|
+
In `ListHeader` toggle mode, omitting `actionIcon` composes the production
|
|
208
|
+
`DisclosureArrow` and derives its visual direction from `expanded`. The app
|
|
209
|
+
must update that controlled state and reveal or hide real content. Passing a
|
|
210
|
+
custom `actionIcon` replaces the default rather than layering or rotating both.
|
|
211
|
+
The root fills the available inline width after its standard margins. A
|
|
212
|
+
separate action stays at the logical end in its 44px target while the visible
|
|
213
|
+
glyph defaults to 18px through `--kui-list-header-action-icon-size`.
|
|
12
214
|
|
|
13
215
|
`StateBanner` exposes instance-level `--kui-state-banner-background`,
|
|
14
216
|
`--kui-state-banner-border`, `--kui-state-banner-foreground`,
|
|
15
|
-
`--kui-state-banner-detail`,
|
|
217
|
+
`--kui-state-banner-detail`, `--kui-state-banner-badge-background`,
|
|
218
|
+
`--kui-state-banner-badge-foreground`, and action background variables. Its optional
|
|
219
|
+
badge is a compact pill beside the title and follows the banner tone by default. Its five built-in
|
|
16
220
|
tones can be rethemed globally with
|
|
17
221
|
`--kui-state-banner-{tone}-{background|border|foreground}`. Toolbar control,
|
|
18
222
|
segmented-control, app-tab, and tab-bar colors likewise use their public
|
|
@@ -27,11 +231,61 @@ separator with a compact grip that appears on hover or keyboard focus. Override
|
|
|
27
231
|
`--kui-resizable-region-handle-active-color` on a region when its containing
|
|
28
232
|
surface needs a different contrast level.
|
|
29
233
|
|
|
234
|
+
`Pane` defines one structural model for sidebars, main areas, inspectors, and
|
|
235
|
+
dialogs. Its `.kui-pane` root is unpadded and contains an optional vertical
|
|
236
|
+
header, one scrolling vertical `.kui-pane__content`, and an optional footer.
|
|
237
|
+
Logical-edge separator lines are independently opt-in and default off.
|
|
238
|
+
`@kerfjs/ui/layout.css` retains the pane roles and supplies the related content
|
|
239
|
+
geometry classes.
|
|
240
|
+
`List` is the corresponding layout-only vertical stack: its children stretch by
|
|
241
|
+
default, while `gap`, `flex`, and `scrollable` opt into standard/custom spacing,
|
|
242
|
+
flex growth, and vertical scroll ownership. `dividerSides` accepts canonical
|
|
243
|
+
physical top/right/bottom/left combinations such as `tr` and `trbl`; the stack
|
|
244
|
+
adds no list semantics, margin, or padding of its own. String props receive
|
|
245
|
+
browser CSS, so use `gap="var(--kui-space-2xs)"` for the root-scaled 4px token or
|
|
246
|
+
`gap="0.25rem"`; source-only `remify(4px)` is not valid at runtime.
|
|
247
|
+
`.kui-content` gives major children 24px vertical separation.
|
|
248
|
+
`.kui-content-item` gives one child 8px inline margin, a real 1px border,
|
|
249
|
+
8px padding, and 12px corners; border and background may be transparent without
|
|
250
|
+
changing geometry. `.kui-content-item--pill` selects the 22px radius.
|
|
251
|
+
|
|
252
|
+
`ToolbarControlGroup` is the unit of toolbar organization, even for dormant
|
|
253
|
+
text. Each group reserves `calc(2px + remify(42px))`, or 44px, with 8px between
|
|
254
|
+
groups and inside items. For an ordinary icon/action control inside a group, use
|
|
255
|
+
a plain `<button>` — the group styles `> button` fully, and it keeps the group
|
|
256
|
+
free of a Web Awesome dependency and shadow DOM. Reach for `wa-button` only when
|
|
257
|
+
you need a Web Awesome feature, chiefly the `slot="trigger"` button of a
|
|
258
|
+
`wa-dropdown` popup menu. `ListHeader` similarly separates its dormant title and
|
|
259
|
+
optional count or badge from its optional 44px action. Use the mutually
|
|
260
|
+
exclusive `count`/`countLabel` pair for non-negative safe-integer section
|
|
261
|
+
quantities; reserve `badge` for non-count `SafeHtml`. Do not concatenate counts
|
|
262
|
+
into the section label. Do not add padding to pane shells,
|
|
263
|
+
double child-owned geometry with wrapper insets, or create competing scroll
|
|
264
|
+
owners. The [layout contract](./layout.md) lists the public roles and tokens.
|
|
265
|
+
|
|
266
|
+
`PanelHeader` is a plain top `Toolbar` used as a panel, dialog, or page heading;
|
|
267
|
+
it overrides no Toolbar styles. The leading zone holds an optional icon (a normal
|
|
268
|
+
bordered `ToolbarControlGroup` given a brand fill with a matching border) and the
|
|
269
|
+
title as extra-large `ToolbarText`, and the app's `actions` go straight into the
|
|
270
|
+
trailing zone (typically as a `ToolbarControlGroup`). The icon group is omitted
|
|
271
|
+
when no icon is passed. The optional summary is a separate row aligned below the
|
|
272
|
+
title, so it cannot pull the icon group out of vertical alignment with the
|
|
273
|
+
title and action row.
|
|
274
|
+
|
|
275
|
+
`ValueTable` composes typed `ValueTableRow` entries. A row owns its `dt`/`dd`
|
|
276
|
+
semantics and may receive a leading `SafeHtml` icon. Every row keeps 8px of
|
|
277
|
+
root-scaled padding above and below its content; the shared item-padding token
|
|
278
|
+
continues to own its inline inset. Separators follow the content they introduce:
|
|
279
|
+
8px from either edge for an iconless row, or 40px from the left edge (8px
|
|
280
|
+
padding + 24px icon + 8px gap) and 8px from the right edge for an icon-bearing
|
|
281
|
+
row. Applications own the values, formatting, and whether an icon is decorative
|
|
282
|
+
or meaningfully labeled.
|
|
283
|
+
|
|
30
284
|
## Imports and side effects
|
|
31
285
|
|
|
32
286
|
Every component has an explicit JS and CSS subpath. In CSS-aware browser builds,
|
|
33
287
|
the JS component subpath resolves to a generated wrapper that imports the
|
|
34
|
-
foundation, the component stylesheet
|
|
288
|
+
foundation, the compiled component stylesheet from `dist/styles`, and styles for its reachable UI
|
|
35
289
|
subcomponents. The source graph derives those transitive styles at build time;
|
|
36
290
|
an application root never maintains that list. Unused component subpaths and
|
|
37
291
|
their CSS remain unreachable. The root barrel and `@kerfjs/ui/unstyled` stay
|
|
@@ -41,23 +295,76 @@ overrides load later in the cascade or set scoped `--kui-*` variables. JavaScrip
|
|
|
41
295
|
modules are pure except the browser style wrappers and `@kerfjs/ui/select/register`,
|
|
42
296
|
which registers exactly the Web Awesome elements used by `Select`. Eventful
|
|
43
297
|
helpers such as `wireResizableRegions` and `wireTabBars` attach listeners only
|
|
44
|
-
when called and return disposers.
|
|
298
|
+
when called and return disposers. `wireTokenSearchFields` goes one step further:
|
|
299
|
+
by default it also owns the collapsible field's transient expand/collapse/focus
|
|
300
|
+
(activate to reveal and focus, Escape or empty blur to collapse), holding that
|
|
301
|
+
state in a signal it exposes on the returned handle. An app reads that signal in
|
|
302
|
+
render, hands in its own via `collapsible.signals`, drives it through
|
|
303
|
+
`handle.open`/`handle.close`, or disables any individual behavior — so transient
|
|
304
|
+
UI is consistent by default without every app reinventing it.
|
|
305
|
+
|
|
306
|
+
`wireTokenSearchFields` is a deliberate exception, not the rule for `wire…`
|
|
307
|
+
helpers. Its collapse behavior was _rich and error-prone_ — reveal, focus
|
|
308
|
+
transfer, Escape, empty-blur collapse, focus return — the kind of transient chrome
|
|
309
|
+
apps kept reimplementing inconsistently, so the helper owns it. Everywhere else the
|
|
310
|
+
app's state is **domain or persisted, not transient chrome, and stays app-owned**: a
|
|
311
|
+
`NavStack`'s view stack is navigation history, a `TabBar`/`TabScaffold`'s selection
|
|
312
|
+
and tab order are data, a `ResizableRegion`'s committed size and a
|
|
313
|
+
`Workbench`/`SplitView` rail's `collapsed` flag are persisted layout preferences.
|
|
314
|
+
Each helper already owns only the _ephemeral mechanics_ around that state —
|
|
315
|
+
`wireNavStack` the push/pop animation, `wireTabBars` the overflow autoscroll and
|
|
316
|
+
drag preview, `wireResizableRegions` the live drag preview — and reports committed
|
|
317
|
+
changes through callbacks. A `ListHeader` `toggle` disclosure's `expanded` is
|
|
318
|
+
likewise app-owned: it is a one-line boolean the app already tracks and must read to
|
|
319
|
+
render the section body, so a managed helper would remove no real complexity. Reach
|
|
320
|
+
for a managed default only when the transient behavior is substantial enough that
|
|
321
|
+
hand-rolling it produces genuine, inconsistent variation.
|
|
322
|
+
|
|
323
|
+
CSS, the generated wrappers that make it
|
|
45
324
|
reachable, and the registration module are the package's only declared side
|
|
46
325
|
effects.
|
|
47
326
|
|
|
327
|
+
A value-bearing component's `placeholder` prop is a first-class loading mode: the
|
|
328
|
+
component renders its own real chrome (labels, icon and action affordances,
|
|
329
|
+
container geometry) while replacing each **value** slot with a subtle, deliberately
|
|
330
|
+
unanimated `Skeleton` block and disabling its own interactive controls
|
|
331
|
+
(`aria-busy`, dropped `data-action`, disabled buttons). Sizes and shapes stay
|
|
332
|
+
identical to the populated component, so a parent composes a faithful loading view —
|
|
333
|
+
an inspector, a detail pane — from placeholder children without hand-rebuilding
|
|
334
|
+
markup. The application still owns the loading lifecycle (when to pass `placeholder`)
|
|
335
|
+
and which slots are unknown; the standalone `Skeleton` covers custom slots. It is a
|
|
336
|
+
placeholder, not progress: use `LoadingSpinner` for known busy activity, and never
|
|
337
|
+
animate the skeleton.
|
|
338
|
+
|
|
339
|
+
Package source styles express root-scaled geometry with `remify(<px>)`; the
|
|
340
|
+
build converts it against the 16px authoring baseline and exposes only ordinary
|
|
341
|
+
`rem` CSS. Literal pixels remain for intentional hairlines, and `em` remains
|
|
342
|
+
explicit when a value is relative to its component's current font size. The UX
|
|
343
|
+
catalog applies the same transform to source CSS under Vite so `npm run dev`
|
|
344
|
+
retains hot module replacement.
|
|
345
|
+
|
|
48
346
|
`@kerfjs/ui/webawesome.css` is a separate, optional CSS boundary. It imports
|
|
49
347
|
Web Awesome's public base stylesheet and overrides its semantic theme layer to
|
|
50
348
|
match the Kerf/Hot Sheet 2 system. It never imports component JavaScript.
|
|
349
|
+
`import type {} from '@kerfjs/ui/webawesome'` is the matching side-effect-free
|
|
350
|
+
Kerf JSX declaration boundary for every catalog-supported `wa-*` tag.
|
|
51
351
|
Consumers register only the individual Web Awesome modules they render and can
|
|
52
352
|
override `--wa-*` values after the theme import. The shared `--wa-*` values feed
|
|
53
353
|
both Web Awesome controls and Kerf's `--kui-*` foundation aliases, preventing a
|
|
54
354
|
second application palette.
|
|
55
355
|
|
|
356
|
+
`Select` owns its custom-element reconciliation seam. It gives each slotted
|
|
357
|
+
option icon a stable key and leaves the upgraded Web Awesome-owned slot subtree
|
|
358
|
+
untouched on later Kerf renders. Its custom selected slot is keyed by the
|
|
359
|
+
controlled value so changed selections replace that content. Applications
|
|
360
|
+
should pass ordinary `choices` and `renderSelected` output rather than adding
|
|
361
|
+
their own morph-control attributes.
|
|
362
|
+
|
|
56
363
|
`kerfjs` is a peer dependency and remains external in every build. Importing a toolbar must not bundle a second Kerf runtime, another UI component, Web Awesome registration, the UX catalog, or development tooling.
|
|
57
364
|
|
|
58
365
|
## Extracted versus application-specific
|
|
59
366
|
|
|
60
|
-
The package set is intentionally domain-neutral: icon rendering, toolbar primitives, controlled segmented choices, menu rows/headers, resizable regions and wiring, controlled reorderable tab bars, headers, loading, select, banners, empty states, dialog headers, and value
|
|
367
|
+
The package set is intentionally domain-neutral: icon rendering, toolbar primitives, controlled segmented choices, a controlled token-chip search field with DOM read/caret helpers, menu rows/headers, resizable regions and wiring, controlled reorderable tab bars, headers, loading, select, banners, empty states, dialog headers, and typed value-table rows.
|
|
61
368
|
|
|
62
369
|
Keep product adapters outside the package: connection-state maps, ticket empty-state copy, project/terminal/chat tab actions, saved pane sizes, provider or repository models, and application-specific palettes. An adapter may compose these primitives, map product state into their props, and override semantic CSS variables.
|
|
63
370
|
|