@kerfjs/ui 5.0.0-beta.8 → 5.0.0-beta.80
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 +546 -139
- package/ai/application-ui-diagnostic-ids-v1.json +113 -0
- package/ai/application-ui-profile-sync.cjs +548 -0
- package/ai/application-ui-profile.d.mts +1 -0
- package/ai/application-ui-profile.d.ts +106 -0
- package/ai/application-ui-profile.defaults.json +96 -0
- package/ai/application-ui-profile.mjs +653 -0
- package/ai/application-ui-profile.schema.json +140 -0
- package/ai/catalog-authoring.json +36 -0
- package/ai/catalog-authoring.schema.json +109 -0
- package/ai/compile-time-contracts-v1.json +149 -0
- package/ai/compile-time-contracts-v1.schema.json +52 -0
- package/ai/component-catalog-extension.schema.json +104 -0
- package/ai/component-catalog.json +4280 -457
- package/ai/component-catalog.schema.json +94 -1
- 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-composition-rules.json +516 -0
- package/ai/component-composition.d.ts +129 -0
- package/ai/component-composition.json +7397 -0
- package/ai/component-composition.schema.json +408 -0
- package/ai/components/README.md +171 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/chip.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +96 -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 +82 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +100 -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 +91 -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 +94 -0
- package/ai/components/list.md +106 -0
- package/ai/components/loading-spinner.md +73 -0
- package/ai/components/lucide-icon.md +97 -0
- package/ai/components/nav-stack.md +105 -0
- package/ai/components/pane.md +104 -0
- package/ai/components/popup-menu.md +171 -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 +106 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +115 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +103 -0
- package/ai/components/state-banner.md +94 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +87 -0
- package/ai/components/tab-bar.md +113 -0
- package/ai/components/tab-navigator.md +95 -0
- package/ai/components/tabs.md +95 -0
- package/ai/components/text.md +87 -0
- package/ai/components/token-search-field.md +107 -0
- package/ai/components/toolbar-control-group.md +121 -0
- package/ai/components/toolbar-text.md +98 -0
- package/ai/components/toolbar.md +101 -0
- package/ai/components/value-table.md +73 -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 +119 -0
- package/ai/public-api-signatures-v1.md +2821 -250
- package/ai/skill.md +354 -66
- package/ai/webawesome-jsx-signatures-v1.md +9 -2
- package/analyzer/cli.mjs +49 -0
- package/analyzer/component-ownership.d.mts +72 -0
- package/analyzer/component-ownership.mjs +429 -0
- package/analyzer/index.d.mts +53 -0
- package/analyzer/index.mjs +2346 -0
- package/analyzer/loud-pairs.d.mts +49 -0
- package/analyzer/loud-pairs.mjs +357 -0
- package/analyzer/report.schema.json +66 -0
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/catalog-projection-cli.mjs +96 -0
- package/catalog-projection.d.mts +55 -0
- package/catalog-projection.mjs +62 -0
- package/dist/app-tab.d.ts +39 -4
- package/dist/app-tab.js +2 -1
- package/dist/badge.d.ts +54 -0
- package/dist/badge.js +3 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/catalog.js +26 -0
- package/dist/browser/chip.js +3 -0
- package/dist/browser/collapsible-panel.js +9 -0
- package/dist/browser/content-item.js +3 -0
- package/dist/browser/floating-toolbar.js +3 -0
- package/dist/browser/grid.js +3 -0
- package/dist/browser/list-action-row.js +5 -0
- package/dist/browser/{menu-header.js → list-header.js} +5 -3
- package/dist/browser/list-inset-control.js +3 -0
- package/dist/browser/list-inset-text.js +3 -0
- package/dist/browser/list-item.js +5 -0
- package/dist/browser/list.js +3 -0
- package/dist/browser/nav-stack.js +11 -0
- package/dist/browser/pane.js +3 -0
- package/dist/browser/popup-menu.js +3 -0
- package/dist/browser/row.js +3 -0
- package/dist/browser/segmented-control.js +0 -1
- package/dist/browser/select.js +2 -1
- package/dist/browser/spacer.js +3 -0
- package/dist/browser/split-view.js +13 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/browser/sunken-panel.js +3 -0
- package/dist/browser/surface-scaffold.js +3 -0
- package/dist/browser/tab-navigator.js +4 -0
- package/dist/browser/text.js +3 -0
- package/dist/browser/toolbar-control-group.js +1 -0
- package/dist/browser/workbench.js +14 -0
- package/dist/catalog-resources.d.ts +48 -0
- package/dist/catalog-resources.js +22 -0
- package/dist/catalog-resources.js.map +1 -0
- package/dist/catalog.d.ts +92 -0
- package/dist/catalog.js +541 -0
- package/dist/catalog.js.map +1 -0
- package/dist/chip.d.ts +36 -0
- package/dist/chip.js +3 -0
- package/dist/chip.js.map +1 -0
- package/dist/chunk-2GOCOLQL.js +270 -0
- package/dist/chunk-2GOCOLQL.js.map +1 -0
- package/dist/chunk-3CXRQAYT.js +288 -0
- package/dist/chunk-3CXRQAYT.js.map +1 -0
- package/dist/chunk-3RE2JMZU.js +48 -0
- package/dist/chunk-3RE2JMZU.js.map +1 -0
- package/dist/chunk-3SXWV2IR.js +295 -0
- package/dist/chunk-3SXWV2IR.js.map +1 -0
- package/dist/chunk-3XPGJUUQ.js +37 -0
- package/dist/chunk-3XPGJUUQ.js.map +1 -0
- package/dist/chunk-4Y4L5YEI.js +66 -0
- package/dist/chunk-4Y4L5YEI.js.map +1 -0
- package/dist/chunk-5BZBIRQG.js +452 -0
- package/dist/chunk-5BZBIRQG.js.map +1 -0
- package/dist/chunk-5D3WDMIK.js +71 -0
- package/dist/chunk-5D3WDMIK.js.map +1 -0
- package/dist/chunk-62VMNBV2.js +779 -0
- package/dist/chunk-62VMNBV2.js.map +1 -0
- package/dist/chunk-75I3SNUJ.js +44 -0
- package/dist/chunk-75I3SNUJ.js.map +1 -0
- package/dist/chunk-7QQ3HE47.js +17 -0
- package/dist/chunk-7QQ3HE47.js.map +1 -0
- package/dist/chunk-7TE6XDFI.js +91 -0
- package/dist/chunk-7TE6XDFI.js.map +1 -0
- package/dist/chunk-A7DYEERU.js +59 -0
- package/dist/chunk-A7DYEERU.js.map +1 -0
- package/dist/chunk-AN5IWMTM.js +24 -0
- package/dist/chunk-AN5IWMTM.js.map +1 -0
- package/dist/chunk-ARZ4RSQO.js +48 -0
- package/dist/chunk-ARZ4RSQO.js.map +1 -0
- package/dist/chunk-BJLXE56E.js +135 -0
- package/dist/chunk-BJLXE56E.js.map +1 -0
- package/dist/chunk-BYHGRKC3.js +44 -0
- package/dist/chunk-BYHGRKC3.js.map +1 -0
- package/dist/chunk-CEJ5FK6G.js +288 -0
- package/dist/chunk-CEJ5FK6G.js.map +1 -0
- package/dist/chunk-CVKIADIS.js +172 -0
- package/dist/chunk-CVKIADIS.js.map +1 -0
- package/dist/chunk-DQDTZE4W.js +70 -0
- package/dist/chunk-DQDTZE4W.js.map +1 -0
- package/dist/chunk-EFDCALR3.js +66 -0
- package/dist/chunk-EFDCALR3.js.map +1 -0
- package/dist/chunk-FL6J644M.js +116 -0
- package/dist/chunk-FL6J644M.js.map +1 -0
- package/dist/chunk-GS2QD3N7.js +14 -0
- package/dist/chunk-GS2QD3N7.js.map +1 -0
- package/dist/chunk-H45DAZBL.js +491 -0
- package/dist/chunk-H45DAZBL.js.map +1 -0
- package/dist/chunk-H7ZJEI3H.js +52 -0
- package/dist/chunk-H7ZJEI3H.js.map +1 -0
- package/dist/chunk-HFLGWMG3.js +138 -0
- package/dist/chunk-HFLGWMG3.js.map +1 -0
- package/dist/chunk-HFQDSSED.js +188 -0
- package/dist/chunk-HFQDSSED.js.map +1 -0
- package/dist/{chunk-56RJXPHG.js → chunk-I4SDIMFA.js} +7 -4
- package/dist/chunk-I4SDIMFA.js.map +1 -0
- package/dist/chunk-IM3GKYOG.js +202 -0
- package/dist/chunk-IM3GKYOG.js.map +1 -0
- package/dist/chunk-J3AWE5I4.js +50 -0
- package/dist/chunk-J3AWE5I4.js.map +1 -0
- package/dist/chunk-JOR5LGYE.js +55 -0
- package/dist/chunk-JOR5LGYE.js.map +1 -0
- package/dist/chunk-JZM3G6RT.js +149 -0
- package/dist/chunk-JZM3G6RT.js.map +1 -0
- package/dist/{chunk-7BR3DO2A.js → chunk-LAZLBC2Q.js} +14 -5
- package/dist/chunk-LAZLBC2Q.js.map +1 -0
- package/dist/chunk-LQKY5S4F.js +506 -0
- package/dist/chunk-LQKY5S4F.js.map +1 -0
- package/dist/chunk-LRAIS3YB.js +158 -0
- package/dist/chunk-LRAIS3YB.js.map +1 -0
- package/dist/chunk-MXNIVEVL.js +48 -0
- package/dist/chunk-MXNIVEVL.js.map +1 -0
- package/dist/chunk-NJZMR7HM.js +135 -0
- package/dist/chunk-NJZMR7HM.js.map +1 -0
- package/dist/chunk-NMWDHZVM.js +35 -0
- package/dist/chunk-NMWDHZVM.js.map +1 -0
- package/dist/{chunk-YGN7OMLT.js → chunk-NS2TBYM4.js} +8 -5
- package/dist/chunk-NS2TBYM4.js.map +1 -0
- package/dist/chunk-NVKRZ5DI.js +222 -0
- package/dist/chunk-NVKRZ5DI.js.map +1 -0
- package/dist/chunk-NVRJ7C3W.js +83 -0
- package/dist/chunk-NVRJ7C3W.js.map +1 -0
- package/dist/chunk-O27D24CA.js +250 -0
- package/dist/chunk-O27D24CA.js.map +1 -0
- package/dist/chunk-PQQQXJGV.js +58 -0
- package/dist/chunk-PQQQXJGV.js.map +1 -0
- package/dist/chunk-RRCD3A6G.js +139 -0
- package/dist/chunk-RRCD3A6G.js.map +1 -0
- package/dist/chunk-S3ECMF23.js +33 -0
- package/dist/chunk-S3ECMF23.js.map +1 -0
- package/dist/chunk-S4ZGTDSG.js +18 -0
- package/dist/chunk-S4ZGTDSG.js.map +1 -0
- package/dist/chunk-VHXHLZ6R.js +69 -0
- package/dist/chunk-VHXHLZ6R.js.map +1 -0
- package/dist/chunk-VIGVNDXZ.js +165 -0
- package/dist/chunk-VIGVNDXZ.js.map +1 -0
- package/dist/chunk-VR7MWD2X.js +91 -0
- package/dist/chunk-VR7MWD2X.js.map +1 -0
- package/dist/chunk-Y6KT7ZTR.js +109 -0
- package/dist/chunk-Y6KT7ZTR.js.map +1 -0
- package/dist/chunk-YLJ6X3AC.js +34 -0
- package/dist/chunk-YLJ6X3AC.js.map +1 -0
- package/dist/collapsible-panel.d.ts +137 -0
- package/dist/collapsible-panel.js +135 -0
- package/dist/collapsible-panel.js.map +1 -0
- package/dist/content-item.d.ts +99 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/css-values.d.ts +112 -0
- package/dist/css-values.js +3 -0
- package/dist/css-values.js.map +1 -0
- package/dist/device-class.js +34 -6
- package/dist/device-class.js.map +1 -1
- package/dist/disclosure-arrow.d.ts +6 -1
- package/dist/disclosure-arrow.js +2 -1
- package/dist/empty-state.d.ts +5 -2
- package/dist/empty-state.js +2 -1
- package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
- package/dist/floating-toolbar.d.ts +51 -0
- package/dist/floating-toolbar.js +3 -0
- package/dist/floating-toolbar.js.map +1 -0
- package/dist/grid.d.ts +57 -0
- package/dist/grid.js +5 -0
- package/dist/grid.js.map +1 -0
- package/dist/help-tags-register.d.ts +13 -0
- package/dist/help-tags-register.js +9 -0
- package/dist/help-tags-register.js.map +1 -0
- package/dist/index.d.ts +40 -18
- package/dist/index.js +44 -23
- package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +21 -9
- package/dist/list-action-row.js +8 -0
- package/dist/list-action-row.js.map +1 -0
- package/dist/list-header.d.ts +98 -0
- package/dist/list-header.js +10 -0
- package/dist/list-header.js.map +1 -0
- package/dist/list-inset-control.d.ts +22 -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 +30 -0
- package/dist/list-inset-text.js +4 -0
- package/dist/list-inset-text.js.map +1 -0
- package/dist/list-item.d.ts +62 -0
- package/dist/list-item.js +8 -0
- package/dist/list-item.js.map +1 -0
- package/dist/list.d.ts +63 -0
- package/dist/list.js +6 -0
- package/dist/list.js.map +1 -0
- package/dist/loading-spinner.d.ts +12 -2
- package/dist/loading-spinner.js +2 -1
- package/dist/lucide-icon.d.ts +14 -2
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack-B1Qc2e5q.d.ts +101 -0
- package/dist/nav-stack.d.ts +13 -38
- package/dist/nav-stack.js +10 -1
- package/dist/pane.d.ts +116 -0
- package/dist/pane.js +4 -0
- package/dist/pane.js.map +1 -0
- package/dist/panel-toolbar-CL9tYOkh.d.ts +72 -0
- package/dist/popup-menu-register.d.ts +9 -0
- package/dist/popup-menu-register.js +244 -0
- package/dist/popup-menu-register.js.map +1 -0
- package/dist/popup-menu.d.ts +100 -0
- package/dist/popup-menu.js +3 -0
- package/dist/popup-menu.js.map +1 -0
- package/dist/resizable-region.d.ts +32 -3
- package/dist/resizable-region.js +1 -1
- package/dist/row.d.ts +48 -0
- package/dist/row.js +6 -0
- package/dist/row.js.map +1 -0
- package/dist/segmented-control.d.ts +12 -9
- package/dist/segmented-control.js +1 -2
- package/dist/select-register.d.ts +5 -1
- package/dist/select-register.js +247 -3
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +103 -8
- package/dist/select.js +3 -1
- package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
- package/dist/semantic-tone-CdW013KF.d.ts +4 -0
- package/dist/sides-BPSWde0A.d.ts +4 -0
- package/dist/skeleton.d.ts +14 -7
- package/dist/skeleton.js +2 -1
- package/dist/spacer.d.ts +18 -0
- package/dist/spacer.js +4 -0
- package/dist/spacer.js.map +1 -0
- package/dist/split-view.d.ts +44 -7
- package/dist/split-view.js +124 -10
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +21 -7
- package/dist/state-banner.js +3 -1
- package/dist/styles/app-tab.css +224 -0
- package/dist/styles/badge.css +118 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
- package/dist/styles/catalog/components/catalog-example.css +168 -0
- package/dist/styles/catalog/components/catalog-stage.css +55 -0
- package/dist/styles/catalog/components/catalog.css +50 -0
- package/dist/styles/catalog.css +5 -0
- package/dist/styles/chip.css +138 -0
- package/dist/styles/collapsible-panel.css +580 -0
- package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +285 -0
- package/dist/styles/components/actions/toolbar/toolbar.css +417 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +891 -0
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +171 -0
- package/dist/styles/components/collections/list/list.css +133 -0
- package/dist/styles/components/collections/list-action-row/list-action-row.css +258 -0
- package/dist/styles/components/collections/list-header/list-header.css +229 -0
- package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
- package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
- package/dist/styles/components/collections/list-item/list-item.css +255 -0
- package/dist/styles/components/data-display/value-table/value-table.css +105 -0
- package/dist/styles/components/feedback/badge/badge.css +118 -0
- package/dist/styles/components/feedback/chip/chip.css +138 -0
- package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
- package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
- package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +248 -0
- package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
- package/dist/styles/components/forms/select/select.css +454 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +392 -0
- package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
- package/dist/styles/components/layout/grid/grid.css +85 -0
- package/dist/styles/components/layout/pane/pane.css +294 -0
- package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
- package/dist/styles/components/layout/row/row.css +111 -0
- package/dist/styles/components/layout/spacer/spacer.css +11 -0
- package/dist/styles/components/layout/split-view/split-view.css +146 -0
- package/dist/styles/components/layout/workbench/workbench.css +1075 -0
- package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
- package/dist/styles/components/navigation/app-tab/app-tab.css +376 -0
- package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +242 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +183 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +237 -0
- package/dist/styles/components/surfaces/content-item/content-item.css +120 -0
- package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +34 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +111 -0
- package/dist/styles/components/typography/text/text.css +158 -0
- package/dist/styles/content-item.css +120 -0
- package/dist/styles/document.css +33 -0
- package/dist/styles/floating-toolbar.css +119 -0
- package/dist/styles/foundation.css +187 -45
- package/dist/styles/grid.css +85 -0
- package/dist/styles/layout.css +3 -41
- package/dist/styles/list-action-row.css +258 -0
- package/dist/styles/list-header.css +229 -0
- package/dist/styles/list-inset-control.css +30 -0
- package/dist/styles/list-inset-text.css +29 -0
- package/dist/styles/list-item.css +255 -0
- package/dist/styles/list.css +133 -0
- package/dist/styles/loading-spinner.css +4 -0
- package/dist/styles/lucide-icon.css +9 -0
- package/dist/styles/nav-stack.css +180 -50
- package/dist/styles/pane.css +294 -0
- package/dist/styles/popup-menu.css +285 -0
- package/dist/styles/resizable-region.css +438 -4
- package/dist/styles/row.css +111 -0
- package/dist/styles/segmented-control.css +36 -9
- package/dist/styles/select.css +337 -21
- package/dist/styles/skeleton.css +64 -3
- package/dist/styles/spacer.css +11 -0
- package/dist/styles/split-view.css +114 -3
- package/dist/styles/state-banner.css +94 -19
- package/dist/styles/styles.css +13 -4
- package/dist/styles/sunken-panel.css +34 -0
- package/dist/styles/surface-scaffold.css +111 -0
- package/dist/styles/tab-bar.css +147 -9
- package/dist/styles/tab-navigator.css +237 -0
- package/dist/styles/text.css +158 -0
- package/dist/styles/token-search-field.css +167 -56
- package/dist/styles/toolbar-control-group.css +710 -30
- package/dist/styles/toolbar-text.css +139 -8
- package/dist/styles/toolbar.css +367 -11
- package/dist/styles/value-table.css +34 -4
- package/dist/styles/webawesome.css +388 -16
- package/dist/styles/workbench.css +988 -7
- package/dist/sunken-panel.d.ts +31 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/surface-scaffold-register.d.ts +4 -0
- package/dist/surface-scaffold-register.js +59 -0
- package/dist/surface-scaffold-register.js.map +1 -0
- package/dist/surface-scaffold.d.ts +38 -0
- package/dist/surface-scaffold.js +3 -0
- package/dist/surface-scaffold.js.map +1 -0
- package/dist/tab-bar.d.ts +39 -6
- package/dist/tab-bar.js +1 -1
- package/dist/tab-navigator.d.ts +86 -0
- package/dist/tab-navigator.js +95 -0
- package/dist/tab-navigator.js.map +1 -0
- package/dist/text.d.ts +63 -0
- package/dist/text.js +3 -0
- package/dist/text.js.map +1 -0
- package/dist/token-search-field.d.ts +3 -43
- package/dist/token-search-field.js +2 -1
- package/dist/token-search-model-DTcTXWMS.d.ts +154 -0
- package/dist/token-search-model.d.ts +3 -0
- package/dist/token-search-model.js +3 -0
- package/dist/token-search-model.js.map +1 -0
- package/dist/toolbar-control-group.d.ts +89 -7
- package/dist/toolbar-control-group.js +3 -1
- package/dist/toolbar-text.d.ts +45 -9
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +59 -7
- package/dist/toolbar.js +1 -1
- package/dist/types-C9BubXfz.d.ts +117 -0
- package/dist/value-table.d.ts +11 -3
- package/dist/value-table.js +2 -1
- package/dist/webawesome.d.ts +8 -1
- package/dist/wire-catalog.d.ts +82 -0
- package/dist/wire-catalog.js +407 -0
- package/dist/wire-catalog.js.map +1 -0
- package/dist/wire-content-items.d.ts +11 -0
- package/dist/wire-content-items.js +114 -0
- package/dist/wire-content-items.js.map +1 -0
- package/dist/wire-nav-stack.d.ts +4 -1
- package/dist/wire-nav-stack.js +191 -15
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-resizable-regions.d.ts +2 -1
- package/dist/wire-resizable-regions.js +2 -1
- package/dist/wire-scroll-dividers.d.ts +72 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/wire-sidebar.d.ts +63 -0
- package/dist/wire-sidebar.js +231 -0
- package/dist/wire-sidebar.js.map +1 -0
- package/dist/wire-tab-bars.d.ts +19 -2
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-navigator.d.ts +11 -0
- package/dist/wire-tab-navigator.js +21 -0
- package/dist/wire-tab-navigator.js.map +1 -0
- package/dist/wire-token-search-fields.d.ts +65 -3
- package/dist/wire-token-search-fields.js +2 -1
- package/dist/wire-toolbar-visibility.d.ts +13 -0
- package/dist/wire-toolbar-visibility.js +3 -0
- package/dist/wire-toolbar-visibility.js.map +1 -0
- package/dist/wire-workbench.d.ts +116 -0
- package/dist/wire-workbench.js +6 -0
- package/dist/wire-workbench.js.map +1 -0
- package/dist/workbench.d.ts +246 -9
- package/dist/workbench.js +17 -15
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +497 -26
- package/docs/app-layouts.md +141 -10
- package/docs/apple-hig.md +1 -0
- package/docs/catalog.md +493 -0
- package/docs/collapsible-panel.md +382 -0
- package/docs/component-contract.md +736 -61
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +617 -97
- 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/inline-action-dark.svg +1 -0
- package/docs/design/templates/list-header/inline-action.svg +1 -0
- package/docs/design/templates/list-header/size-l-dark.svg +1 -0
- package/docs/design/templates/list-header/size-l.svg +1 -0
- package/docs/design/templates/list-header/size-m-dark.svg +1 -0
- package/docs/design/templates/list-header/size-m.svg +1 -0
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xl.svg +1 -0
- package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xs.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/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/width-visibility-320-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600.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/icon-tile-brand-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning.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/dark-tone-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/dark-tone.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 +140 -0
- package/docs/design-philosophy.md +48 -20
- package/docs/device-class.md +10 -9
- package/docs/document-baseline.md +42 -0
- package/docs/examples/application-ui-profile.json +60 -0
- package/docs/examples/command-palette-adapter.tsx +69 -17
- package/docs/examples/component-catalog-extension.json +52 -0
- package/docs/examples/component-composition-extension.json +80 -0
- package/docs/layout.md +601 -59
- package/docs/nav-stack.md +154 -14
- package/docs/recipes.md +142 -55
- package/docs/split-view.md +77 -6
- package/docs/sunken-panel.md +93 -0
- package/docs/surface-scaffold.md +74 -0
- package/docs/tab-navigator.md +210 -0
- package/docs/type-contracts.md +135 -0
- package/docs/ui-analyzer.md +404 -0
- package/docs/ui-doctor.md +202 -0
- package/docs/ui-evaluator.md +139 -0
- package/docs/ux-demo.md +46 -16
- package/docs/webawesome-theme.md +188 -16
- package/docs/workbench.md +621 -12
- package/doctor/cli.mjs +120 -0
- package/doctor/component-style-checks.mjs +457 -0
- package/doctor/config.schema.json +94 -0
- package/doctor/eslint-diagnostics.d.mts +24 -0
- package/doctor/eslint-diagnostics.mjs +24 -0
- package/doctor/index.d.mts +122 -0
- package/doctor/index.mjs +1403 -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 +1203 -0
- package/evaluator/report.schema.json +152 -0
- package/llms.txt +510 -49
- package/package.json +266 -44
- package/scripts/component-catalog-extension-validation.mjs +28 -0
- package/traversal-exclusions.mjs +27 -0
- package/ux-demo/recipes/app-shell.tsx +205 -17
- package/ux-demo/recipes/collapsible-sidebar.tsx +260 -0
- package/ux-demo/recipes/compact-toolbar.tsx +135 -14
- package/ux-demo/recipes/composer-form.tsx +133 -21
- package/ux-demo/recipes/list-detail-dialog.tsx +286 -0
- package/ux-demo/recipes/list-workspace-states.tsx +183 -11
- package/ux-demo/recipes/loaders.ts +15 -5
- package/ux-demo/recipes/loading-inspector.tsx +204 -0
- package/ux-demo/recipes/mount-recipe.ts +28 -10
- package/ux-demo/recipes/navigation-sidebar.tsx +139 -13
- package/ux-demo/recipes/navigation-stack.tsx +81 -26
- package/ux-demo/recipes/types.ts +23 -2
- package/ux-demo/recipes/workspace-header.tsx +86 -5
- package/dist/browser/menu-action-row.js +0 -4
- package/dist/browser/menu-item.js +0 -4
- package/dist/browser/panel-header.js +0 -7
- package/dist/chunk-2RJBFNB6.js +0 -172
- package/dist/chunk-2RJBFNB6.js.map +0 -1
- package/dist/chunk-2Z5TWHKQ.js +0 -34
- package/dist/chunk-2Z5TWHKQ.js.map +0 -1
- package/dist/chunk-3YD6ZNRA.js +0 -34
- package/dist/chunk-3YD6ZNRA.js.map +0 -1
- package/dist/chunk-55DATV3A.js +0 -10
- package/dist/chunk-55DATV3A.js.map +0 -1
- package/dist/chunk-56RJXPHG.js.map +0 -1
- package/dist/chunk-7BR3DO2A.js.map +0 -1
- package/dist/chunk-7LDCTU7D.js +0 -134
- package/dist/chunk-7LDCTU7D.js.map +0 -1
- package/dist/chunk-AQNKJRFH.js +0 -79
- package/dist/chunk-AQNKJRFH.js.map +0 -1
- package/dist/chunk-B24C4A6T.js +0 -22
- package/dist/chunk-B24C4A6T.js.map +0 -1
- package/dist/chunk-BLK3UEEI.js +0 -23
- package/dist/chunk-BLK3UEEI.js.map +0 -1
- package/dist/chunk-BNQ2YDV4.js +0 -20
- package/dist/chunk-BNQ2YDV4.js.map +0 -1
- package/dist/chunk-DAFFDO33.js +0 -14
- package/dist/chunk-DAFFDO33.js.map +0 -1
- package/dist/chunk-H6URQGJI.js +0 -42
- package/dist/chunk-H6URQGJI.js.map +0 -1
- package/dist/chunk-I7INRJO4.js +0 -17
- package/dist/chunk-I7INRJO4.js.map +0 -1
- package/dist/chunk-LC3YSAZC.js +0 -39
- package/dist/chunk-LC3YSAZC.js.map +0 -1
- package/dist/chunk-M5JRI6MN.js +0 -27
- package/dist/chunk-M5JRI6MN.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 +0 -227
- package/dist/chunk-MQIZAD4A.js.map +0 -1
- package/dist/chunk-PONXLV5U.js +0 -19
- package/dist/chunk-PONXLV5U.js.map +0 -1
- package/dist/chunk-RUNWEPR4.js +0 -10
- package/dist/chunk-RUNWEPR4.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js +0 -26
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-WVPYVDXY.js +0 -15
- package/dist/chunk-WVPYVDXY.js.map +0 -1
- package/dist/chunk-YGN7OMLT.js.map +0 -1
- package/dist/chunk-YKUUZPED.js +0 -24
- package/dist/chunk-YKUUZPED.js.map +0 -1
- package/dist/menu-action-row.js +0 -5
- package/dist/menu-action-row.js.map +0 -1
- package/dist/menu-header.d.ts +0 -43
- package/dist/menu-header.js +0 -7
- package/dist/menu-header.js.map +0 -1
- package/dist/menu-item.d.ts +0 -33
- package/dist/menu-item.js +0 -5
- package/dist/menu-item.js.map +0 -1
- package/dist/panel-header.d.ts +0 -36
- package/dist/panel-header.js +0 -7
- package/dist/panel-header.js.map +0 -1
- package/dist/styles/menu-action-row.css +0 -160
- package/dist/styles/menu-header.css +0 -160
- package/dist/styles/menu-item.css +0 -123
- package/dist/styles/panel-header.css +0 -64
- package/dist/styles/tab-scaffold.css +0 -84
- package/dist/tab-scaffold.d.ts +0 -30
- package/dist/tab-scaffold.js +0 -16
- package/dist/tab-scaffold.js.map +0 -1
- package/dist/wire-tab-scaffold.d.ts +0 -11
- package/dist/wire-tab-scaffold.js +0 -16
- package/dist/wire-tab-scaffold.js.map +0 -1
- package/docs/tab-scaffold.md +0 -41
- package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
- package/ux-demo/recipes/recipes.css +0 -355
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# SunkenPanel
|
|
2
|
+
|
|
3
|
+
`SunkenPanel` is a visually lowered application surface with one compact inset
|
|
4
|
+
and a vertical content stack. Use it for a main work area or nested panel whose
|
|
5
|
+
background should sit behind ordinary content, such as the primary stage in an
|
|
6
|
+
issue tracker or component catalog.
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { SunkenPanel } from '@kerfjs/ui/sunken-panel';
|
|
10
|
+
|
|
11
|
+
<SunkenPanel ariaLabel="Release workspace">
|
|
12
|
+
<ReleaseSummary />
|
|
13
|
+
<ReleaseChecks />
|
|
14
|
+
</SunkenPanel>;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The default `shape="rounded"` uses the shared rounded-rectangle radius. Choose
|
|
18
|
+
`shape="square"` for a flush or edge-to-edge area that needs `border-radius: 0`:
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
<SunkenPanel shape="square">
|
|
22
|
+
<Workspace />
|
|
23
|
+
</SunkenPanel>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Filling a work area
|
|
27
|
+
|
|
28
|
+
Set `fill` when the panel is the direct layout root of a parent with a definite
|
|
29
|
+
height. Inside a flex column, use `flex` so it takes the remaining space and
|
|
30
|
+
can shrink with its parent. Like `Grid`, `flex` accepts `true` (equivalent to
|
|
31
|
+
`1 1 auto`), a CSS flex keyword, or a typed `CssFlex` value. The panel keeps
|
|
32
|
+
`min-height: 0`, allowing its parent to own scrolling.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<List fill>
|
|
36
|
+
<Toolbar label="Work area" />
|
|
37
|
+
<SunkenPanel flex>
|
|
38
|
+
<WorkArea />
|
|
39
|
+
</SunkenPanel>
|
|
40
|
+
</List>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Inside a `Pane`, the Pane's content remains the scroll owner. Place a
|
|
44
|
+
`SunkenPanel fill` in a definite-height Pane content region when the surface
|
|
45
|
+
itself needs to cover empty space, or use `flex` when a flex parent allocates
|
|
46
|
+
the remaining space. The panel does not add another scroller.
|
|
47
|
+
|
|
48
|
+
## Ownership
|
|
49
|
+
|
|
50
|
+
The root owns its lowered background, 8px padding, and 8px vertical gap.
|
|
51
|
+
Children own their borders and internal geometry. The application owns child
|
|
52
|
+
order, responsive placement, and scrolling; `SunkenPanel` deliberately does not
|
|
53
|
+
create another scroll container.
|
|
54
|
+
|
|
55
|
+
Use `ariaLabel` only when the surface is a distinct region people need to find
|
|
56
|
+
by name. With a label, the root receives `role="region"`; without one it remains
|
|
57
|
+
a non-landmark grouping.
|
|
58
|
+
|
|
59
|
+
Set `tabIndex={0}` to include the whole panel in the Tab order, or
|
|
60
|
+
`tabIndex={-1}` for a programmatic focus target. Keyboard focus draws the
|
|
61
|
+
standard focus ring. `outlined` keeps the same ring visible independently of
|
|
62
|
+
focus, for example while the panel is a drop target. Give a focusable work area
|
|
63
|
+
an `ariaLabel` when it is a distinct named region.
|
|
64
|
+
|
|
65
|
+
Do not use `SunkenPanel` merely to add padding, as a substitute for pane
|
|
66
|
+
header/content/footer anatomy, or around a child that already owns the same
|
|
67
|
+
outer surface.
|
|
68
|
+
|
|
69
|
+
For a lowered scrolling work area with Pane chrome, use
|
|
70
|
+
[`Pane appearance="sunken"`](layout.md#lowered-work-surfaces). It paints the
|
|
71
|
+
scroll viewport and empty space without adding a second scroller.
|
|
72
|
+
|
|
73
|
+
## Public styling boundary
|
|
74
|
+
|
|
75
|
+
Override the public properties at the composition boundary:
|
|
76
|
+
|
|
77
|
+
- `--kui-sunken-panel-background`
|
|
78
|
+
- `--kui-sunken-panel-foreground`
|
|
79
|
+
- `--kui-sunken-panel-padding`
|
|
80
|
+
- `--kui-sunken-panel-gap`
|
|
81
|
+
- `--kui-sunken-panel-radius`
|
|
82
|
+
|
|
83
|
+
The default background uses the shared translucent lowered-surface token.
|
|
84
|
+
Nested panels composite naturally at every depth: darker in light mode and
|
|
85
|
+
lighter in dark mode, without wrappers, depth classes, or per-instance token
|
|
86
|
+
assignments. Pane and Web Awesome sunken surfaces use the same palette.
|
|
87
|
+
See [Contextual transparency](./webawesome-theme.md#contextual-transparency).
|
|
88
|
+
Keep ordinary composition on these defaults; public properties are theming
|
|
89
|
+
escape hatches, not a reason to restyle each demo or nesting level.
|
|
90
|
+
|
|
91
|
+
The public root class is `.kui-sunken-panel`. Prefer the properties above over
|
|
92
|
+
styling descendants. The `square` shape deliberately overrides the radius
|
|
93
|
+
property with zero; use `rounded` when customizing the radius token.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Dialog and popup surface scaffolds
|
|
2
|
+
|
|
3
|
+
`DialogSurface` and `PopupSurface` configure recurring Web Awesome surface
|
|
4
|
+
geometry without application `::part()` overrides. They do not replace Web
|
|
5
|
+
Awesome behavior: the application still owns open state, dismissal policy, ids,
|
|
6
|
+
labels, and content. With `@kerfjs/ui/popup-menu/register` imported, a dropdown
|
|
7
|
+
inside `PopupSurface` also keeps keyboard item navigation made during its show
|
|
8
|
+
animation when Web Awesome completes its initial focus handoff.
|
|
9
|
+
|
|
10
|
+
Wrap one `wa-dialog` with `DialogSurface`. Choose `size` (`small`, `medium`, or
|
|
11
|
+
`large`), `presentation` (`modal`, `side-sheet`, or `fullscreen`), and independent
|
|
12
|
+
`bodyInset` / `footerInset` (`none`, `compact`, or `comfortable`). The defaults
|
|
13
|
+
match Kerf's medium modal, 8px body, and 16px footer rhythm.
|
|
14
|
+
|
|
15
|
+
The modal size presets have preferred widths of 400px, 560px, and 800px,
|
|
16
|
+
respectively, before the viewport width cap. Set `preferredWidth` to a branded
|
|
17
|
+
`CssLength` when the desktop shell needs another width. It takes precedence over
|
|
18
|
+
`size`, while the viewport cap still applies. For example, 832px and 480px
|
|
19
|
+
desktop preferences can share the same responsive dialog without changing its
|
|
20
|
+
resource tracks or preview aspect sizing.
|
|
21
|
+
|
|
22
|
+
### Modal viewport bounds
|
|
23
|
+
|
|
24
|
+
`viewportGutter` accepts a branded `CssLength` from `@kerfjs/ui/css-values`.
|
|
25
|
+
It sets the minimum horizontal clearance; `preferredWidth` overrides the `size`
|
|
26
|
+
preset when supplied. `maxHeight` accepts a branded length or `"viewport"`; explicit caps are
|
|
27
|
+
clamped to the dynamic viewport height minus twice the gutter (16px per edge
|
|
28
|
+
when the gutter is omitted). Negative gutters/caps clamp to zero. Omitting
|
|
29
|
+
both options preserves Web Awesome's existing width and phone height caps.
|
|
30
|
+
These options apply only to `presentation="modal"`; side sheets and fullscreen
|
|
31
|
+
surfaces keep their own geometry.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import '@kerfjs/ui/surface-scaffold/register';
|
|
35
|
+
import { remify } from '@kerfjs/ui/css-values';
|
|
36
|
+
import { DialogSurface } from '@kerfjs/ui/surface-scaffold';
|
|
37
|
+
|
|
38
|
+
<DialogSurface preferredWidth={remify(832)} viewportGutter={remify(8)} maxHeight="viewport" bodyInset="none">
|
|
39
|
+
<wa-dialog label="Close workspace">{/* Application-owned content and footer */}</wa-dialog>
|
|
40
|
+
</DialogSurface>;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This gives a desktop modal an 832px preferred width and a phone modal an 8px edge gutter with a `calc(100dvh - 16px)` height
|
|
44
|
+
cap without application selectors on Kerf roots or Web Awesome parts. A cap
|
|
45
|
+
is not a fixed height: short content stays naturally sized, and taller content
|
|
46
|
+
scrolls in Web Awesome's body while its header/footer remain outside that
|
|
47
|
+
scroll owner. Choosing a larger cap cannot guarantee that arbitrary content
|
|
48
|
+
fits without scrolling; preview tracks, canvas aspect ratios and content sizing
|
|
49
|
+
remain application-owned.
|
|
50
|
+
|
|
51
|
+
Responsive policy is explicit application state: read `deviceClass()` during
|
|
52
|
+
the render to choose the gutter, cap or presentation. For example use
|
|
53
|
+
`viewportGutter={remify(device.value.handset ? 8 : 16)}` with `maxHeight="viewport"`.
|
|
54
|
+
The scaffold introduces no hidden breakpoint or automatic fullscreen switch.
|
|
55
|
+
An application can configure device-class breakpoints when its phone policy
|
|
56
|
+
differs from the default. Prefer a typed cap such as `maxHeight={remify(640)}`
|
|
57
|
+
when the modal should stop growing before the viewport bound.
|
|
58
|
+
|
|
59
|
+
Treat a dialog body as a `List` by default. When its rows or sections own their
|
|
60
|
+
standard list geometry, set `bodyInset="none"` so the dialog does not add a
|
|
61
|
+
second inset. Bare prose is still a list child: wrap it in `ListInsetText` so its
|
|
62
|
+
text edge receives the standard 8px margin + 1px transparent border + 8px
|
|
63
|
+
padding and aligns with bordered siblings. Reserve `compact` or `comfortable`
|
|
64
|
+
body insets for exceptional content that does not already have list/content-item
|
|
65
|
+
geometry.
|
|
66
|
+
|
|
67
|
+
Wrap one `PopupMenu` (or another single `wa-dropdown`) with `PopupSurface`. `inset="list-zero"` removes menu
|
|
68
|
+
padding for a child that already owns row insets, `compact` uses 4px, and
|
|
69
|
+
`standard` uses the shared 8px surface inset. Keep the dropdown trigger named and
|
|
70
|
+
preserve `data-morph-skip-children` when its upgraded light-DOM items must retain
|
|
71
|
+
identity across Kerf rerenders. Import `@kerfjs/ui/popup-menu/register` once for
|
|
72
|
+
the focus handoff fix when wrapping a raw `wa-dropdown`.
|
|
73
|
+
|
|
74
|
+
Import `@kerfjs/ui/surface-scaffold/register` once when using `DialogSurface`: it registers `wa-dialog` and repairs Web Awesome 3.12 native dialog names before the first modal opening. Headed dialogs reference the rendered title, including live slotted labels; headerless dialogs use the public `label`. Explicit host `aria-label` and pre-existing native names are preserved. Geometry-only markup stays CSS-free and does not register Web Awesome implicitly.
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# Tab navigator
|
|
2
|
+
|
|
3
|
+
`@kerfjs/ui/tab-navigator` is a mobile-first, iOS-like bottom tab bar that switches
|
|
4
|
+
between major app sections, where **each tab keeps its own content mounted** —
|
|
5
|
+
usually a `NavStack`, so each tab's stack and scroll survive a switch. One of the
|
|
6
|
+
opt-in app layouts (see [`../../docs/23-app-layouts.md`](../../docs/23-app-layouts.md)).
|
|
7
|
+
It is distinct from `TabBar` (document-oriented, reorderable strips).
|
|
8
|
+
|
|
9
|
+
## Migration from TabScaffold
|
|
10
|
+
|
|
11
|
+
The deprecated `TabScaffold` API was removed during the 5.0 beta series. Replace names and import
|
|
12
|
+
paths when updating an app:
|
|
13
|
+
|
|
14
|
+
| Previous | Current |
|
|
15
|
+
| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
16
|
+
| `TabScaffold`, `TabScaffoldTab`, `TabScaffoldProps` from `@kerfjs/ui/tab-scaffold` | `TabNavigator`, `TabNavigatorTab`, `TabNavigatorProps` from `@kerfjs/ui/tab-navigator` |
|
|
17
|
+
| `wireTabScaffold`, `WireTabScaffoldOptions` from `@kerfjs/ui/wire-tab-scaffold` | `wireTabNavigator`, `WireTabNavigatorOptions` from `@kerfjs/ui/wire-tab-navigator` |
|
|
18
|
+
| `@kerfjs/ui/tab-scaffold.css` | `@kerfjs/ui/tab-navigator.css` |
|
|
19
|
+
|
|
20
|
+
Props, rendered DOM classes, data attributes, and wiring behavior are unchanged.
|
|
21
|
+
The old JS and CSS subpaths are no longer exported. Import the new CSS path
|
|
22
|
+
when your build does not use the package's `browser` condition.
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { TabNavigator } from "@kerfjs/ui/tab-navigator";
|
|
26
|
+
import { wireTabNavigator } from "@kerfjs/ui/wire-tab-navigator";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
30
|
+
webpack do by default), the import above also
|
|
31
|
+
loads TabNavigator's stylesheet and those of the components it renders internally
|
|
32
|
+
(the tab `Badge`). Without that condition, import the manual stylesheets instead:
|
|
33
|
+
`@kerfjs/ui/tab-navigator.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
34
|
+
|
|
35
|
+
## Controlled selection
|
|
36
|
+
|
|
37
|
+
The app owns the active tab (a signal); `TabNavigator` renders every tab's scene
|
|
38
|
+
(only the active one visible) plus the bottom bar, and `wireTabNavigator` reports
|
|
39
|
+
clicks.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
const active = signal("home");
|
|
43
|
+
|
|
44
|
+
<TabNavigator
|
|
45
|
+
id="app"
|
|
46
|
+
label="Sections"
|
|
47
|
+
active={active.value}
|
|
48
|
+
tabs={[
|
|
49
|
+
{ id: "home", label: "Home", icon: <HomeIcon />, content: <HomeStack /> },
|
|
50
|
+
{
|
|
51
|
+
id: "search",
|
|
52
|
+
label: "Search",
|
|
53
|
+
icon: <SearchIcon />,
|
|
54
|
+
content: <SearchStack />,
|
|
55
|
+
},
|
|
56
|
+
]}
|
|
57
|
+
/>;
|
|
58
|
+
|
|
59
|
+
// once, after first render:
|
|
60
|
+
const dispose = wireTabNavigator(root, {
|
|
61
|
+
onSelect: (id) => {
|
|
62
|
+
active.value = id;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Each `TabNavigatorTab` has an `id`, `label`, optional `icon`, optional `badge`
|
|
68
|
+
and `badgeLabel` (see [Tab badges](#tab-badges)), and `content`. The
|
|
69
|
+
bottom bar paints through the home-indicator safe area and pads for it and for
|
|
70
|
+
the side insets, while each scene pads for the top and side insets (a scene
|
|
71
|
+
whose only child is a `NavStack` or `Pane` lets that child own them; see
|
|
72
|
+
[Choosing an app layout › Safe areas](app-layouts.md#safe-areas)). The bar keeps 44px targets. Its single-line labels preserve their full line box and
|
|
73
|
+
truncate horizontally with an ellipsis when a destination name exceeds its
|
|
74
|
+
share of the bar. On larger device classes, promote the tab set to a
|
|
75
|
+
`Workbench` rail or a persistent sidebar instead of a bottom bar.
|
|
76
|
+
|
|
77
|
+
Set `deepInset: true` on a plain tab scene to add 8px of padding on every side
|
|
78
|
+
of its scrolling content, giving ordinary content items a 16px inline edge inset.
|
|
79
|
+
The default is `false`. A scene whose only child is a `Pane` or layout lets
|
|
80
|
+
that child own its content gutter: for a nested `NavStack`, set
|
|
81
|
+
`pane: { deepInset: true }` on its views instead. The navigator bar and a
|
|
82
|
+
stack's top toolbar remain full width.
|
|
83
|
+
|
|
84
|
+
A plain scene can opt into `tabIndex: 0` to become a Tab stop or `tabIndex: -1`
|
|
85
|
+
to accept programmatic focus. `outlined: true` keeps the standard focus ring
|
|
86
|
+
visible independently of focus, for example for a drop target. Keyboard focus
|
|
87
|
+
also draws that ring. Only the active scene receives the requested tab index or
|
|
88
|
+
outline; inactive scenes stay out of the Tab order and hide the outline. A
|
|
89
|
+
scene containing a `Pane` or another layout should put these options on its
|
|
90
|
+
inner focus owner instead. A focusable scene is a tabpanel named by its tab label.
|
|
91
|
+
|
|
92
|
+
## A NavStack with a top toolbar and Pane
|
|
93
|
+
|
|
94
|
+
Put the `NavStack` directly in a tab's `content`. Give each view a structured
|
|
95
|
+
`toolbar` and `pane` configuration. Leave `bottomToolbar` off both the views
|
|
96
|
+
and the stack: the navigator's tab bar is the only bottom chrome. The view's
|
|
97
|
+
Pane owns scrolling, while the stack keeps its toolbar above it and the
|
|
98
|
+
navigator keeps the tab bar below it.
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import { List } from "@kerfjs/ui/list";
|
|
102
|
+
import { ListItem } from "@kerfjs/ui/list-item";
|
|
103
|
+
import { NavStack, type NavStackView } from "@kerfjs/ui/nav-stack";
|
|
104
|
+
|
|
105
|
+
const projectViews: NavStackView[] = [
|
|
106
|
+
{
|
|
107
|
+
key: "projects",
|
|
108
|
+
toolbar: { title: "Projects" },
|
|
109
|
+
pane: { appearance: "sunken" },
|
|
110
|
+
content: <List><ListItem label="Project Atlas" /></List>,
|
|
111
|
+
},
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
<TabNavigator
|
|
115
|
+
id="app"
|
|
116
|
+
label="Sections"
|
|
117
|
+
active={active.value}
|
|
118
|
+
tabs={[
|
|
119
|
+
{
|
|
120
|
+
id: "projects",
|
|
121
|
+
label: "Projects",
|
|
122
|
+
content: (
|
|
123
|
+
<NavStack
|
|
124
|
+
id="projects-stack"
|
|
125
|
+
label="Projects navigation"
|
|
126
|
+
views={projectViews}
|
|
127
|
+
/>
|
|
128
|
+
),
|
|
129
|
+
},
|
|
130
|
+
{ id: "search", label: "Search", content: <SearchScene /> },
|
|
131
|
+
]}
|
|
132
|
+
/>;
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The app owns each stack's view array and the navigator's active tab. Call
|
|
136
|
+
`wireTabNavigator` for tab selection and `wireNavStack` for back navigation
|
|
137
|
+
and transitions, each on its own component root. Push a detail by appending
|
|
138
|
+
a view with its own `toolbar` and `pane`; switching tabs keeps that view
|
|
139
|
+
mounted. The catalog's **NavStack inside a tab** example demonstrates the
|
|
140
|
+
push, tab switch, and return flow.
|
|
141
|
+
|
|
142
|
+
Set a tab's `appearance: "sunken"` when its scene owns scrolling and should
|
|
143
|
+
paint the lowered surface behind short or long content. For a scene whose
|
|
144
|
+
only child is a `Pane` or `NavStack`, set appearance on that child's scroll
|
|
145
|
+
owner. See [Lowered work surfaces](layout.md#lowered-work-surfaces).
|
|
146
|
+
|
|
147
|
+
## Scroll divider
|
|
148
|
+
|
|
149
|
+
The bar has no permanent top border. With `wireScrollDividers(appRoot)`
|
|
150
|
+
installed (see [Layout › Scroll dividers](layout.md#scroll-dividers)), it shows
|
|
151
|
+
a line along its top edge only while the active scene's content continues below
|
|
152
|
+
it — not at the scroll end and not when the content fits. The line keys on
|
|
153
|
+
whatever actually scrolls in the scene: the scene itself or, through a sole
|
|
154
|
+
child, a `NavStack`'s active view or a `Pane`'s content. A `NavStack` with its
|
|
155
|
+
own bottom toolbar sits between them, so that toolbar's line applies instead.
|
|
156
|
+
The line is the bar's always-present 1px top border, colored only while shown,
|
|
157
|
+
so it never moves the bar or a tab.
|
|
158
|
+
|
|
159
|
+
`chromeDividers` configures it, with the same values as a `Pane`'s: `scroll`
|
|
160
|
+
(the default) follows the scroll state and draws nothing until the wiring runs;
|
|
161
|
+
`always` keeps the line, with or without the wiring; `none` drops it even when
|
|
162
|
+
the wiring reports content below.
|
|
163
|
+
|
|
164
|
+
## Tab badges
|
|
165
|
+
|
|
166
|
+
Give a tab a `badge` (a count or short string such as `3`, `"99+"`, or
|
|
167
|
+
`"New"`) to show the iOS tab-bar badge: a compact, solid `danger` `Badge` at the
|
|
168
|
+
top-trailing corner of the tab's icon, growing outward as the text lengthens
|
|
169
|
+
(without an icon it sits above the label). The badge is decorative
|
|
170
|
+
(`aria-hidden`); its meaning reaches assistive technology through `badgeLabel`,
|
|
171
|
+
which the tab folds into its accessible name as `"<label>, <badgeLabel>"`:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
{
|
|
175
|
+
id: "inbox",
|
|
176
|
+
label: "Inbox",
|
|
177
|
+
icon: <LucideIcon icon={Inbox} name="inbox" />,
|
|
178
|
+
badge: unread.value,
|
|
179
|
+
badgeLabel: `${unread.value} unread`,
|
|
180
|
+
content: <InboxStack />,
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`badgeLabel` defaults to the badge text itself, so supply a localized phrase
|
|
185
|
+
whenever the bare text would be ambiguous. Omitting `badge` (or passing an
|
|
186
|
+
empty string or a non-finite number) renders no badge and leaves the tab's name
|
|
187
|
+
as its label; `0` renders, so pass `undefined` when a count should disappear.
|
|
188
|
+
Keep the text short — clamp large counts (`"99+"`) in the app. The tone follows
|
|
189
|
+
the platform convention and is fixed; do not restyle the badge.
|
|
190
|
+
|
|
191
|
+
### Dot badges
|
|
192
|
+
|
|
193
|
+
For new content without a count, pass `badge: true`. The tab shows the iOS
|
|
194
|
+
tab-bar dot — an 8px solid `danger` `Badge` (`size="dot"`) centered on the
|
|
195
|
+
icon's top-trailing corner (above the label without an icon). A dot has no
|
|
196
|
+
text to fall back on, so `badgeLabel` is required by the types:
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
{
|
|
200
|
+
id: "feed",
|
|
201
|
+
label: "Feed",
|
|
202
|
+
icon: <LucideIcon icon={Rss} name="rss" />,
|
|
203
|
+
badge: hasNewPosts.value ? true : undefined,
|
|
204
|
+
badgeLabel: "New activity",
|
|
205
|
+
content: <FeedStack />,
|
|
206
|
+
}
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The tab's accessible name becomes `"Feed, New activity"`. Pass `undefined` to
|
|
210
|
+
clear the dot; `false` is not a badge value.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Compile-time contracts
|
|
2
|
+
|
|
3
|
+
Kerf UI rejects invalid integrations at compile time only when TypeScript can
|
|
4
|
+
prove the relationship from one call. The versioned
|
|
5
|
+
[`compile-time-contracts-v1.json`](../ai/compile-time-contracts-v1.json)
|
|
6
|
+
artifact names those guarantees with stable `KUI-T###` ids. Its source fixture
|
|
7
|
+
is compiled twice: against `src/` and against declarations extracted from the
|
|
8
|
+
actual `npm pack` tarball. `npm run check:catalog` also verifies that every
|
|
9
|
+
contract still points to a real catalog entry/import and a symbol in the emitted
|
|
10
|
+
public-signature artifact.
|
|
11
|
+
|
|
12
|
+
## Strengthened contracts
|
|
13
|
+
|
|
14
|
+
| ID | Compile-time guarantee |
|
|
15
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
16
|
+
| `KUI-T001` | `ListHeader` is a passive heading, a fully named/icon-bearing trailing action, or a controlled disclosure with `action` + `expanded`. Props ignored by the selected mode are rejected. |
|
|
17
|
+
| `KUI-T002` | `Select` has a visible `label` or an `ariaLabel`. |
|
|
18
|
+
| `KUI-T003` | A literal `Select.value` belongs to its literal `choices`. |
|
|
19
|
+
| `KUI-T004` | A literal `SegmentedControl.value` belongs to its literal `choices`. |
|
|
20
|
+
| `KUI-T005` | `expanded`, `expandAction`, and `expandLabel` exist only on `TokenSearchField({ collapsible: true })`. |
|
|
21
|
+
| `KUI-T006` | `TokenSearchEditorAttributes` accepts application `data-*` metadata but rejects component-owned identity, morph, count, and placeholder attributes. |
|
|
22
|
+
| `KUI-T007` | `ToolbarText.maxLines` requires `wrap: true`; it is never silently ignored in typed code. |
|
|
23
|
+
| `KUI-T008` | A literal `TabNavigator.active` id belongs to its literal `tabs`. |
|
|
24
|
+
| `KUI-T009` | Adjacent-token keyboard removal requires `onRemoveToken`; disabling removal rejects the now-meaningless callback. |
|
|
25
|
+
| `KUI-T010` | Finite public variants have named exported union types, including divider sides, tab activation, banner urgency, and all AppTab, TabBar, ToolbarControlGroup, and Select presentation axes; the convenience root barrel re-exports them. |
|
|
26
|
+
| `KUI-T011` | Semantic component zones use the recursive `KerfUiContent` type: `SafeHtml`, runtime-empty booleans/nullish values, and readonly nested arrays are valid; arbitrary strings, numbers, and signals are rejected. Explicit text positions such as `ListInsetText` retain their text exception. |
|
|
27
|
+
| `KUI-T012` | `List.gap` accepts finite `UiSpaceName` shorthands or a complete branded `CssLength`; raw strings and non-standalone `CssLengthExpression` arithmetic are rejected. `calc(plus(...))` promotes a typed expression to a complete value. |
|
|
28
|
+
| `KUI-T013` | CSS-valued props preserve property grammar: `List.flex` uses `CssFlex`, `Skeleton` dimensions use `CssSize`/`CssLength`, and choice icons and `LucideIcon.color` use `CssForegroundColor` (foreground tokens via `uiColor()`, `foregroundColorVar()`, or custom values via `foregroundColor()`; fill tokens such as `uiColor('success-fill-quiet')` are rejected); row declaration strings are absent. |
|
|
29
|
+
| `KUI-T014` | Stable single-root visual components accept the explicit native `slot` attribute. Multi-root `ResizableRegion` and `CollapsiblePanel` remain excluded because no single returned element can own the assignment, and other arbitrary native attributes remain rejected. |
|
|
30
|
+
|
|
31
|
+
`KerfUiContent` lets conditionals and mapped component collections be direct
|
|
32
|
+
siblings without an otherwise-unnecessary `Fragment`:
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<List>
|
|
36
|
+
{intro ? <ListInsetText>{intro}</ListInsetText> : null}
|
|
37
|
+
{rows.map((row) => (
|
|
38
|
+
<ListItem label={row.label} />
|
|
39
|
+
))}
|
|
40
|
+
</List>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The type is intentionally narrower than core JSX children. Wrap prose in a
|
|
44
|
+
semantic text component, and read signals into components or structural
|
|
45
|
+
conditionals rather than passing signal objects as content.
|
|
46
|
+
|
|
47
|
+
Literal identity inference is intentionally additive for dynamic applications.
|
|
48
|
+
When choices or ids arrive at runtime and the state signal is correctly typed as
|
|
49
|
+
`string`, widen the component explicitly:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<Select<string> value={loadedValue.value} choices={loadedChoices.value} ... />
|
|
53
|
+
<SegmentedControl<string> value={mode.value} choices={loadedModes.value} ... />
|
|
54
|
+
<TabNavigator<string> active={active.value} tabs={loadedTabs.value} ... />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The widening is an honest statement that TypeScript cannot know the runtime
|
|
58
|
+
dataset. Do not cast a known literal typo merely to bypass the relationship.
|
|
59
|
+
|
|
60
|
+
## Complete public-surface audit
|
|
61
|
+
|
|
62
|
+
The following existing contracts were already exact and remain covered by the
|
|
63
|
+
ordinary source/type gates:
|
|
64
|
+
|
|
65
|
+
- required identity or accessible-name inputs on `AppTab`, `FloatingToolbar`,
|
|
66
|
+
`NavStack`, `SplitView`, `Workbench`, `TabBar`, `ResizableRegion`,
|
|
67
|
+
`SegmentedControl`, `TokenSearchField`, and `ValueTable`;
|
|
68
|
+
- finite variants exported or represented as literal props on `DisclosureArrow`,
|
|
69
|
+
`FloatingToolbar`, `Pane`, `ResizableRegion`, `SegmentedControl`, `StateBanner`,
|
|
70
|
+
`SunkenPanel`, `ToolbarText`, `CollapsiblePanel`, `Catalog`, and the wire helpers;
|
|
71
|
+
- required controlled-state callbacks on `wireResizableRegions`, `wireTabBars`,
|
|
72
|
+
and `wireTabNavigator`, and the required app-owned size signals on
|
|
73
|
+
`wireWorkbench`;
|
|
74
|
+
- a `ListHeader` count requires `countLabel` and excludes badge/status, while
|
|
75
|
+
badge and status can appear together or be explicitly `undefined`; and
|
|
76
|
+
- protected application metadata boundaries on `AppTab`, `ListItem`,
|
|
77
|
+
`ListActionRow`, `ListHeader`, `Pane`, `CatalogExample`, and
|
|
78
|
+
`CatalogExampleStack`.
|
|
79
|
+
|
|
80
|
+
The remaining components (`LucideIcon`, `DisclosureArrow`, `Toolbar`,
|
|
81
|
+
`ToolbarControlGroup`, `ListInsetControl`, `ListInsetText`, `LoadingSpinner`,
|
|
82
|
+
`Skeleton`, `EmptyState`, `StateBanner`, `ValueTableRow`, and the
|
|
83
|
+
pure helpers) have independent props with no further conditional invalid state
|
|
84
|
+
that TypeScript can truthfully remove. Optional labels on decorative icons and
|
|
85
|
+
unnamed non-landmark surfaces are intentional variants, not missing contracts.
|
|
86
|
+
|
|
87
|
+
## Boundaries TypeScript cannot prove
|
|
88
|
+
|
|
89
|
+
Types do not claim to validate:
|
|
90
|
+
|
|
91
|
+
- the contents of `SafeHtml` slots (for example, “only AppTab children” or “no
|
|
92
|
+
interactive descendants”);
|
|
93
|
+
- nonempty arrays, unique ids, numeric min/max ordering, or a controlled value
|
|
94
|
+
loaded from dynamic data;
|
|
95
|
+
- equality between ids rendered in separate calls, elements discovered later in
|
|
96
|
+
the DOM, or an ARIA relationship's live target;
|
|
97
|
+
- that a caller retained and invoked a wiring disposer; or
|
|
98
|
+
- CSS class/token use inside arbitrary strings.
|
|
99
|
+
|
|
100
|
+
Those remain catalog `KUI-C###` diagnostics, runtime filtering/guards, lint or
|
|
101
|
+
browser assertions. Encoding them as permissive-looking TypeScript brands would
|
|
102
|
+
move errors into casts without making the integration safer.
|
|
103
|
+
|
|
104
|
+
## Migration from the earlier declarations
|
|
105
|
+
|
|
106
|
+
- Add `actionLabel` and `actionIcon` to a non-toggle `ListHeader` action. For a
|
|
107
|
+
disclosure, set literal `toggle: true`, provide `action` and controlled
|
|
108
|
+
`expanded`, and remove trailing-action-only props.
|
|
109
|
+
- Give every `Select` either `label` or `ariaLabel`. Use an explicit `<string>`
|
|
110
|
+
generic only for genuinely dynamic choice data.
|
|
111
|
+
- Put `expanded`/expand-action props behind `collapsible: true`.
|
|
112
|
+
- Replace `wireTokenSearchFields({ keyboard: true })` with either
|
|
113
|
+
`{ keyboard: { onRemoveToken } }` or
|
|
114
|
+
`{ keyboard: { removeAdjacentToken: false } }` when only caret navigation is
|
|
115
|
+
wanted.
|
|
116
|
+
- Add `wrap: true` anywhere `ToolbarText.maxLines` is used.
|
|
117
|
+
- Replace `Toolbar({ divider: false })` with `dividerSides: ''`, which is now
|
|
118
|
+
the default (a toolbar pinned over scrolling content gets its divider from
|
|
119
|
+
`wireScrollDividers` through its `Pane`); canonical combinations such as `b`,
|
|
120
|
+
`tr`, and `trbl` select permanent physical edges.
|
|
121
|
+
- Replace raw `List.gap` strings with a direct spacing shorthand (`"xs"`,
|
|
122
|
+
`"m"`) or a complete value from `@kerfjs/ui/css-values`. Replace
|
|
123
|
+
`gap="0.25rem"` with `gap={rem(0.25)}` and wrap sums with `calc(plus(...))`.
|
|
124
|
+
- Replace raw `List.flex` shorthands with `flex(grow, shrink, basis)` or a finite
|
|
125
|
+
keyword; replace raw Skeleton dimensions with `px`/`rem`/`em`/`pct` builders;
|
|
126
|
+
and replace raw choice colors with a foreground token such as
|
|
127
|
+
`uiColor('success-on-quiet')`, an app-owned `foregroundColorVar()`, or `foregroundColor('rebeccapurple')` for an application-chosen CSS color.
|
|
128
|
+
`SelectChoice.color` rejects fill tokens (`uiColor('success-fill-quiet')`) and
|
|
129
|
+
unqualified `colorVar()` values because a fill paints a nearly invisible
|
|
130
|
+
icon.
|
|
131
|
+
- Remove `style` from `ListItem` and `ListActionRow`; use `className`, public
|
|
132
|
+
tokens, and cataloged props. These breaking cleanups land before 5.0 stable.
|
|
133
|
+
|
|
134
|
+
JavaScript runtime behavior remains defensive for previously emitted calls, but
|
|
135
|
+
new TypeScript builds report these invalid or ignored combinations.
|