@kerfjs/ui 5.0.0-beta.8 → 5.0.0-beta.81
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 +520 -0
- package/ai/component-composition.d.ts +129 -0
- package/ai/component-composition.json +7401 -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 +619 -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
package/docs/nav-stack.md
CHANGED
|
@@ -5,14 +5,19 @@ and out over one another while the top chrome settles. A **single-pane layout is
|
|
|
5
5
|
a `NavStack` with one entry**. It is one of the opt-in app layouts (see
|
|
6
6
|
[`../../docs/23-app-layouts.md`](../../docs/23-app-layouts.md)).
|
|
7
7
|
|
|
8
|
-
Import the component and its
|
|
8
|
+
Import the component and its wiring helper:
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
|
-
import { NavStack, type NavStackView } from
|
|
12
|
-
import { wireNavStack } from
|
|
13
|
-
import '@kerfjs/ui/nav-stack.css';
|
|
11
|
+
import { NavStack, type NavStackView } from "@kerfjs/ui/nav-stack";
|
|
12
|
+
import { wireNavStack } from "@kerfjs/ui/wire-nav-stack";
|
|
14
13
|
```
|
|
15
14
|
|
|
15
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
16
|
+
webpack do by default), the import above also
|
|
17
|
+
loads NavStack's stylesheet and those of the components it renders internally
|
|
18
|
+
(`Toolbar`, `ToolbarControlGroup`, `ToolbarText`, `Pane`, `List`, `LucideIcon`). Without that condition, import the manual stylesheets instead:
|
|
19
|
+
`@kerfjs/ui/nav-stack.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
|
+
|
|
16
21
|
## State lives in the app
|
|
17
22
|
|
|
18
23
|
Like every `@kerfjs/ui` component, `NavStack` is declarative: the app owns the
|
|
@@ -20,28 +25,163 @@ stack as a `signal<NavStackView[]>`, `NavStack({ views })` renders it, and
|
|
|
20
25
|
`wireNavStack` animates the transitions.
|
|
21
26
|
|
|
22
27
|
```tsx
|
|
23
|
-
const views = signal<NavStackView[]>([
|
|
28
|
+
const views = signal<NavStackView[]>([
|
|
29
|
+
{
|
|
30
|
+
key: "inbox",
|
|
31
|
+
toolbar: { title: "Inbox" },
|
|
32
|
+
content: <InboxView />,
|
|
33
|
+
bottomToolbar: {
|
|
34
|
+
label: "Inbox status",
|
|
35
|
+
leading: <InboxStatus />,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
]);
|
|
24
39
|
|
|
25
40
|
// render inside mount():
|
|
26
41
|
<NavStack id="mail" label="Mail" views={views.value} />;
|
|
27
42
|
|
|
28
43
|
// once, after first render:
|
|
29
|
-
const dispose = wireNavStack(root, {
|
|
44
|
+
const dispose = wireNavStack(root, {
|
|
45
|
+
onBack: () => {
|
|
46
|
+
views.value = views.value.slice(0, -1);
|
|
47
|
+
},
|
|
48
|
+
});
|
|
30
49
|
|
|
31
50
|
// push / pop by editing the signal:
|
|
32
|
-
views.value = [
|
|
51
|
+
views.value = [
|
|
52
|
+
...views.value,
|
|
53
|
+
{ key: id, toolbar: { title: "Message" }, content: <MessageView id={id} /> },
|
|
54
|
+
];
|
|
33
55
|
```
|
|
34
56
|
|
|
35
57
|
`NavStack` renders every entry stacked, the last one active and the rest kept
|
|
36
|
-
mounted (so their DOM state
|
|
37
|
-
`key` (stable identity), `content`, an optional `
|
|
38
|
-
`
|
|
39
|
-
|
|
58
|
+
mounted (so their DOM state survives) but hidden. Each entry carries a
|
|
59
|
+
`key` (stable identity), `content`, an optional `toolbar` object with `title`,
|
|
60
|
+
`leading`, `center`, and `trailing` groups, and an optional structured
|
|
61
|
+
`bottomToolbar`. The component-level structured
|
|
62
|
+
`bottomToolbar` remains a persistent fallback for views that do not provide one.
|
|
63
|
+
Each view can also provide `header`, `footer`, `headerList`, `footerList`, and
|
|
64
|
+
`pane` configuration, as a `WorkbenchStaticPanel` does. With any of these,
|
|
65
|
+
the view renders a `Pane`: its header and footer stay pinned around the view's
|
|
66
|
+
scrolling content, and slide with that view during navigation. The header and
|
|
67
|
+
footer list configuration forwards to their `List`s; `pane` forwards
|
|
68
|
+
`contentElement`, `contentLabel`, `separators`, `safeAreaEdges`,
|
|
69
|
+
`chromeDividers`, and `appearance` to the Pane. Without those fields, the view
|
|
70
|
+
keeps its simple direct scroll area. Use `pane: { appearance: "sunken" }` for a
|
|
71
|
+
lowered scrolling work surface.
|
|
72
|
+
The back control appears automatically once the stack has more than one entry;
|
|
73
|
+
`wireNavStack`'s `onBack` is where the app pops its own signal.
|
|
74
|
+
|
|
75
|
+
See [Lowered work surfaces](layout.md#lowered-work-surfaces) for nested Pane
|
|
76
|
+
and layout content.
|
|
77
|
+
|
|
78
|
+
## The top toolbar
|
|
79
|
+
|
|
80
|
+
The top chrome is a real `Toolbar`, so it follows the same zone,
|
|
81
|
+
group, and responsive rules as every other toolbar. Its leading zone holds the
|
|
82
|
+
back control (a borderless `ToolbarControlGroup`, shown once the stack has
|
|
83
|
+
depth), then `toolbar.leading`, then `toolbar.title` as a `ToolbarText`.
|
|
84
|
+
`toolbar.center` fills the center zone and `toolbar.trailing` fills the
|
|
85
|
+
trailing zone. Give each zone `ToolbarControlGroup`s or `ToolbarText`,
|
|
86
|
+
as in any toolbar.
|
|
87
|
+
|
|
88
|
+
Configure the toolbar with `toolbarConfig` instead of styling it:
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
<NavStack
|
|
92
|
+
id="mail"
|
|
93
|
+
label="Mail"
|
|
94
|
+
views={views.value}
|
|
95
|
+
backText={previousTitle}
|
|
96
|
+
toolbarConfig={{
|
|
97
|
+
headingLevel: 1,
|
|
98
|
+
titleSize: "xlarge",
|
|
99
|
+
dividerSides: "b",
|
|
100
|
+
responsive: "wrap",
|
|
101
|
+
}}
|
|
102
|
+
/>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
- Each view's `toolbar` can forward the `Toolbar` configuration (`dividerSides`,
|
|
106
|
+
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`) and its `label`,
|
|
107
|
+
`titleSize`, and `headingLevel`. A view value overrides the corresponding
|
|
108
|
+
`toolbarConfig` default. Its `bottomToolbar` forwards the same `Toolbar`
|
|
109
|
+
configuration and has a required accessible `label`.
|
|
110
|
+
- `toolbarConfig` supplies stack-wide defaults (`dividerSides`,
|
|
111
|
+
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`) and adds
|
|
112
|
+
`label` (the toolbar's accessible name), `titleSize` (the title's
|
|
113
|
+
`ToolbarText` size, default `large`), and `headingLevel` (expose the title as
|
|
114
|
+
a heading; default a plain span). The defaults keep the stack's own chrome:
|
|
115
|
+
no divider, the standard Toolbar height (a 44px control band with 8px above and below), and the top and side safe-area edges
|
|
116
|
+
claimed.
|
|
117
|
+
- `backIcon` replaces the default chevron-left icon. `backText` adds visible
|
|
118
|
+
text beside it (for example, the previous view's title); visible text names
|
|
119
|
+
the control, so `backLabel` applies only to the icon-only control.
|
|
120
|
+
|
|
121
|
+
`panelToggle` supplies a persistent final group in the trailing zone of every
|
|
122
|
+
view's top toolbar. `Workbench` uses it for a navigation panel's standard
|
|
123
|
+
collapse toggle; the active view still owns the preceding toolbar groups.
|
|
124
|
+
|
|
125
|
+
The catalog's **Configured toolbar** example shows these together: a level-2
|
|
126
|
+
heading title over a bottom divider, leading and center groups on the root
|
|
127
|
+
view, a trailing group on the pushed view, and `backText` set to the previous
|
|
128
|
+
view's title.
|
|
129
|
+
|
|
130
|
+
Focus follows the controlled stack automatically. On push, `wireNavStack`
|
|
131
|
+
remembers the focused descendant of the departing view and moves focus into the
|
|
132
|
+
new top view. On pop it restores that exact descendant when it still exists. A
|
|
133
|
+
new view prefers a descendant marked `data-nav-focus`, then its first enabled
|
|
134
|
+
focusable descendant, and finally the view container itself. Use
|
|
135
|
+
`data-nav-focus` for a heading or primary control when DOM order is not the best
|
|
136
|
+
initial reading position; it may use `tabindex="-1"` for programmatic focus.
|
|
137
|
+
When a remembered control was removed during the controlled rerender, the same
|
|
138
|
+
fallback order applies. Disposing the helper stops future transitions and
|
|
139
|
+
cleans up any temporary fallback `tabindex` it added.
|
|
140
|
+
|
|
141
|
+
## Scroll dividers
|
|
142
|
+
|
|
143
|
+
The stack draws no permanent line between its chrome and the view. With
|
|
144
|
+
`wireScrollDividers(appRoot)` installed (see
|
|
145
|
+
[Layout › Scroll dividers](layout.md#scroll-dividers)), the top chrome shows a
|
|
146
|
+
line along its bottom edge only while the active view's content is scrolled
|
|
147
|
+
beneath it, and the bottom toolbar a line along its top edge only while more
|
|
148
|
+
content lies below it — neither when the content fits. The line follows the
|
|
149
|
+
active view across a push or pop. The chrome's line is overlaid on its bottom
|
|
150
|
+
edge and the bottom toolbar's is its always-present 1px top border, colored
|
|
151
|
+
only while shown, so neither ever moves the chrome or the content. When the view's only child is a `Pane`,
|
|
152
|
+
the line keys on whichever actually scrolls — the view, or the Pane's content —
|
|
153
|
+
and a Pane header or footer draws its own boundary instead. An explicit
|
|
154
|
+
`toolbarConfig.dividerSides` still draws a permanent Toolbar edge.
|
|
155
|
+
|
|
156
|
+
`chromeDividers` configures both lines, with the same values as a `Pane`'s:
|
|
157
|
+
`scroll` (the default) follows the scroll state above and draws nothing until
|
|
158
|
+
the wiring runs; `always` keeps both lines, with or without the wiring; `none`
|
|
159
|
+
drops them even when the wiring reports scroll state. It does not change the
|
|
160
|
+
top Toolbar's own `dividerSides`.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<NavStack id="settings" label="Settings" views={views.value} chromeDividers="always" />
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Safe areas
|
|
167
|
+
|
|
168
|
+
The stack paints through a device's unsafe areas. Its chrome pads for the top
|
|
169
|
+
and side insets, its bottom toolbar for the bottom and side insets, and each
|
|
170
|
+
view pads the remaining edges inside its scroller, so content scrolls under the
|
|
171
|
+
unsafe area but can always be scrolled clear. A view whose only child is a
|
|
172
|
+
`Pane` or layout lets that child own the insets. See [Choosing an app layout › Safe areas](app-layouts.md#safe-areas).
|
|
40
173
|
|
|
41
174
|
## Transitions
|
|
42
175
|
|
|
43
176
|
`wireNavStack(root, { onBack, duration? })` observes the rendered stack and
|
|
44
177
|
animates each change: a pushed view slides in from the trailing edge; a popped
|
|
45
|
-
view slides back off it over the revealed view
|
|
46
|
-
|
|
47
|
-
|
|
178
|
+
view slides back off it over the revealed view; and snapshots of the previous
|
|
179
|
+
top and bottom chrome cross-fade into the active view's chrome. The preserved
|
|
180
|
+
underlying view remains visible during a push, while remaining inaccessible.
|
|
181
|
+
Starting transforms and opacity apply instantly before the transition begins.
|
|
182
|
+
A new navigation settles the previous transition and cancels its pending frames
|
|
183
|
+
and cleanup timers; disposal removes temporary copies and exiting views. Focus moves to
|
|
184
|
+
the new top view independently of animation duration. It returns a disposer.
|
|
185
|
+
The animation honors `prefers-reduced-motion` (transitions collapse to instant)
|
|
186
|
+
and `duration: 0` disables it. Applicable at every device size and inside
|
|
187
|
+
dialogs.
|
package/docs/recipes.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# Production composition recipes
|
|
2
2
|
|
|
3
|
-
These
|
|
4
|
-
code. Open each stable UX-catalog route to run it, then copy the linked TSX
|
|
5
|
-
|
|
6
|
-
and keep state in a per-instance application adapter. They
|
|
7
|
-
monolithic components.
|
|
3
|
+
These ten reference compositions sit between individual primitives and product
|
|
4
|
+
code. Open each stable UX-catalog route to run it, then copy the linked TSX. The
|
|
5
|
+
examples import public package subpaths, compose components through their
|
|
6
|
+
props and tokens, and keep state in a per-instance application adapter. They
|
|
7
|
+
ship no stylesheet of their own and are not new monolithic components.
|
|
8
8
|
|
|
9
9
|
Copy the recipe source together with the catalog-independent
|
|
10
10
|
[`mount-recipe.ts`](../ux-demo/recipes/mount-recipe.ts) adapter. It mounts the
|
|
11
11
|
controller at one stable application root, uses `delegateActions()` for recipe
|
|
12
|
-
commands, forwards form and dialog lifecycle events,
|
|
13
|
-
|
|
14
|
-
idempotent disposer:
|
|
12
|
+
commands, forwards form and dialog lifecycle events, runs the recipe's own
|
|
13
|
+
`wire()` (for example `wireWorkbench` or `wireSidebar`), retains every
|
|
14
|
+
disposer, and returns one idempotent disposer:
|
|
15
15
|
|
|
16
16
|
```ts
|
|
17
|
-
import { createRecipe } from
|
|
18
|
-
import { mountRecipe } from
|
|
17
|
+
import { createRecipe } from "./navigation-sidebar.js";
|
|
18
|
+
import { mountRecipe } from "./mount-recipe.js";
|
|
19
19
|
|
|
20
|
-
const root = document.querySelector<HTMLElement>(
|
|
20
|
+
const root = document.querySelector<HTMLElement>("#navigation")!;
|
|
21
21
|
const stopRecipe = mountRecipe(root, createRecipe(announce));
|
|
22
|
-
window.addEventListener(
|
|
22
|
+
window.addEventListener("pagehide", stopRecipe, { once: true });
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The adapter is delivered as reference source, not a new package runtime export.
|
|
@@ -28,63 +28,90 @@ specific dispatch; either way, wire once at a stable root and retain disposal.
|
|
|
28
28
|
|
|
29
29
|
## Desktop application shell
|
|
30
30
|
|
|
31
|
-
[Open the recipe](../ux-demo/?component=recipe-app-shell) · [TSX source](../ux-demo/recipes/app-shell.tsx)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
[Open the recipe](../ux-demo/?component=recipe-app-shell) · [TSX source](../ux-demo/recipes/app-shell.tsx)
|
|
32
|
+
|
|
33
|
+
A filling `List` (`fill`, with the recipe's `data-*` markers through
|
|
34
|
+
`rootAttributes`) stacks the app-bar `Toolbar` above a `Workbench`
|
|
35
|
+
(`@kerfjs/ui/workbench`): resizable navigation and inspector rails around the
|
|
36
|
+
task list. Each rail composes its own panel toolbar — a default-size title and
|
|
37
|
+
the standard hide toggle — and the work area's `mainToolbar` carries the xl
|
|
38
|
+
view title. While a rail is hidden, `Workbench` relocates its show toggle into
|
|
39
|
+
the work-area toolbar on the same logical edge (leading for the navigation
|
|
40
|
+
rail, trailing for the inspector), and `wireWorkbench` hands focus between the
|
|
41
|
+
two positions. Collapse a rail completely rather than preserving an empty icon
|
|
42
|
+
rail. Only the three real panes own a `.kui-pane__content` scroll owner; no
|
|
43
|
+
frame `Pane` wraps the layout in a scroll owner that never scrolls, and the
|
|
44
|
+
app-bar `Toolbar` claims the top edge and both sides with its own
|
|
45
|
+
`safeAreaEdges`.
|
|
46
|
+
|
|
47
|
+
On a narrow container the rails overlay the task list one at a time instead of
|
|
48
|
+
squeezing it, leaving a 44px strip on the far side that dismisses the overlay
|
|
49
|
+
(`responsiveOverlayAt`, on by default; `compactOverlay: 'full'` covers the
|
|
50
|
+
whole width). The app owns each rail's collapsed and size signals — which
|
|
51
|
+
`wireWorkbench` keeps in sync with resizing and overlay dismissal — plus
|
|
52
|
+
routing, persistence, and data. Adapt only public `--kui-layout-*` and
|
|
53
|
+
component variables.
|
|
41
54
|
|
|
42
55
|
## Navigation sidebar
|
|
43
56
|
|
|
44
57
|
[Open the recipe](../ux-demo/?component=recipe-navigation-sidebar) · [TSX source](../ux-demo/recipes/navigation-sidebar.tsx)
|
|
45
58
|
|
|
46
59
|
One unpadded `.kui-pane` owns toolbar/content/footer structure. Its
|
|
47
|
-
`.kui-content` uses 24px major gaps; `
|
|
48
|
-
|
|
60
|
+
`.kui-content` uses 24px major gaps; `ListHeader`, `ListItem`, and
|
|
61
|
+
`ContentItem` children own their 8px margin, 1px border, and 8px padding.
|
|
49
62
|
Rows and footer toolbar groups remain 44px tall. The app owns routes,
|
|
50
63
|
permissions, labels, selection, valid section counts and their localized
|
|
51
64
|
`countLabel` phrases, non-count badge content, disclosure state, and revealed
|
|
52
|
-
content. A toggled `
|
|
65
|
+
content. A toggled `ListHeader` supplies the production `DisclosureArrow` when
|
|
53
66
|
no custom `actionIcon` is needed; ordinary navigation rows stay chevron-free.
|
|
54
67
|
|
|
55
68
|
## Workspace header
|
|
56
69
|
|
|
57
70
|
[Open the recipe](../ux-demo/?component=recipe-workspace-header) · [TSX source](../ux-demo/recipes/workspace-header.tsx)
|
|
58
71
|
|
|
59
|
-
|
|
72
|
+
The page heading is a direct `Toolbar`/`ToolbarText` composition while one control cluster holds secondary,
|
|
60
73
|
overflow, and primary actions. The app owns authorization and command policy;
|
|
61
74
|
controls relocate without changing focus order.
|
|
62
75
|
|
|
63
|
-
##
|
|
64
|
-
|
|
65
|
-
[Open the recipe](../ux-demo/?component=recipe-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
The
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
## List-detail dialog
|
|
77
|
+
|
|
78
|
+
[Open the recipe](../ux-demo/?component=recipe-list-detail-dialog) · [TSX source](../ux-demo/recipes/list-detail-dialog.tsx)
|
|
79
|
+
|
|
80
|
+
A list-detail dialog is laid out like a `Workbench` with a left sidebar: on
|
|
81
|
+
roomy devices the list is a full-height sidebar and the detail is a full-height
|
|
82
|
+
main column, each a `Pane` with its own top `Toolbar`. The sidebar's toolbar
|
|
83
|
+
carries its quiet default-size title (and it may add a bottom toolbar for
|
|
84
|
+
sidebar-only actions); the main column's toolbar carries the dialog's primary
|
|
85
|
+
extra-large title and the close control, and its footer carries the record
|
|
86
|
+
actions. The Web Awesome dialog therefore renders `without-header` there —
|
|
87
|
+
its label still names the modal — and the close button uses
|
|
88
|
+
`data-dialog="close"`. Web Awesome keeps modal focus and Escape, and the thin
|
|
89
|
+
recipe adapter restores the invoking control after the hide event.
|
|
90
|
+
`DialogSurface` chooses the large modal with no body inset, because the panes
|
|
91
|
+
own their geometry. Its explicit 16px `viewportGutter` and `maxHeight="viewport"`
|
|
92
|
+
bound the roomy modal to the dynamic viewport; the compact fullscreen
|
|
93
|
+
presentation retains its existing geometry. Application render state chooses
|
|
94
|
+
the presentation and can likewise choose gutter/cap values for a compact modal.
|
|
95
|
+
On compact devices the dialog becomes a full-screen sheet
|
|
96
|
+
with its own labeled header and footer actions, and `SplitView` becomes a
|
|
97
|
+
`NavStack` drill-down whose back control the application pops. The
|
|
98
|
+
application owns open state, selection, the pushed detail, dismissal policy,
|
|
99
|
+
and record actions. Do not put the primary title in a header spanning both
|
|
100
|
+
columns, rebuild the dialog, or reach into private shadow parts.
|
|
78
101
|
|
|
79
102
|
## Composer form
|
|
80
103
|
|
|
81
104
|
[Open the recipe](../ux-demo/?component=recipe-composer-form) · [TSX source](../ux-demo/recipes/composer-form.tsx)
|
|
82
105
|
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
106
|
+
A direct `ToolbarText` supplies the task title, with app-owned supporting copy
|
|
107
|
+
below; their ids are referenced by the form. `ListInsetText` gives that bare
|
|
108
|
+
supporting copy the same content-item text inset as the fields. The title and
|
|
109
|
+
supporting line share a nested heading `List` with `gap="none"`, so the heading
|
|
110
|
+
unit stays together instead of taking the form's 24px section gap. Production
|
|
111
|
+
fields own labels, help, and native focus. One `List` owns the 24px major
|
|
112
|
+
rhythm; the field `List` and the action `Row` use `controlInsets` to sit on the
|
|
113
|
+
shared 8px inline gutter with 8px gaps between related controls, rather than
|
|
114
|
+
acquiring a second content-item padding inset. The app owns
|
|
88
115
|
validation, drafts, permissions, and transport. Persistent error or success
|
|
89
116
|
feedback is the only nested semantic surface and uses `StateBanner`, not a toast.
|
|
90
117
|
Because upgraded Web Awesome fields retain live value properties, controlled
|
|
@@ -106,8 +133,12 @@ rows.
|
|
|
106
133
|
|
|
107
134
|
Use `ToolbarControlGroup` for related commands, `SegmentedControl` for a few
|
|
108
135
|
visible exclusive choices, `Select` for a longer value list, and an ordinary
|
|
109
|
-
button for an independent command.
|
|
110
|
-
|
|
136
|
+
button for an independent command. Even that independent button sits in a
|
|
137
|
+
single-control `ToolbarControlGroup`, which keeps its height, pill shape, focus,
|
|
138
|
+
and hover treatment aligned with the adjacent toolbar controls. At compact
|
|
139
|
+
widths the toolbar stacks its zones and wraps whole trailing groups onto another
|
|
140
|
+
row, so the last action is never clipped. The app owns values, actions,
|
|
141
|
+
persistence, and responsive priority.
|
|
111
142
|
|
|
112
143
|
## Navigation stack
|
|
113
144
|
|
|
@@ -116,10 +147,58 @@ and responsive priority.
|
|
|
116
147
|
Drill from a library list into a detail and back with `NavStack`
|
|
117
148
|
(`@kerfjs/ui/nav-stack`): the app owns the stack as a signal of views and
|
|
118
149
|
pushes/pops it, `NavStack` renders it, and `wireNavStack` slides the content and
|
|
119
|
-
settles the chrome (reduced motion collapses the slide to instant).
|
|
120
|
-
|
|
150
|
+
settles the chrome (reduced motion collapses the slide to instant). See the
|
|
151
|
+
layout guide
|
|
121
152
|
[`app-layouts.md`](app-layouts.md) for choosing among `NavStack`, `SplitView`,
|
|
122
|
-
`Workbench`, and `
|
|
153
|
+
`Workbench`, and `TabNavigator`.
|
|
154
|
+
|
|
155
|
+
## Loading inspector
|
|
156
|
+
|
|
157
|
+
[Open the recipe](../ux-demo/?component=recipe-loading-inspector) · [TSX source](../ux-demo/recipes/loading-inspector.tsx)
|
|
158
|
+
|
|
159
|
+
A record inspector whose per-record values load asynchronously. Every
|
|
160
|
+
value-bearing component (`ToolbarText`, `ValueTable`/`ValueTableRow`, `Select`,
|
|
161
|
+
`SegmentedControl`, `ListItem`, `StateBanner`) takes its `placeholder` from one
|
|
162
|
+
loading flag, so the same real chrome renders a faithful loading state and then
|
|
163
|
+
the populated record — no separate skeleton markup. The composition is the point;
|
|
164
|
+
`Skeleton` is the primitive it builds on. Its heading `Toolbar` uses
|
|
165
|
+
`responsive="wrap"`, so on a narrow inspector the toggle moves below a whole
|
|
166
|
+
record title instead of truncating it. The app owns the loading lifecycle and
|
|
167
|
+
which values are still unknown.
|
|
168
|
+
|
|
169
|
+
## Collapsible sidebar
|
|
170
|
+
|
|
171
|
+
[Open the recipe](../ux-demo/?component=recipe-collapsible-sidebar) · [TSX source](../ux-demo/recipes/collapsible-sidebar.tsx)
|
|
172
|
+
|
|
173
|
+
A mini app frame whose left navigation rail and bottom activity drawer are
|
|
174
|
+
standalone `CollapsiblePanel`s (`@kerfjs/ui/collapsible-panel`) driven by
|
|
175
|
+
`wireSidebar` (`@kerfjs/ui/wire-sidebar`). Each panel takes a `toolbar` — a
|
|
176
|
+
title plus the standard per-side toggle — so the hide control lives in the
|
|
177
|
+
panel's own header, and `CollapsiblePanelRelocated` renders the matching show
|
|
178
|
+
control only while the panel is collapsed, so exactly one control owns each
|
|
179
|
+
action and a collapsed panel is still reachable. The rail's relocated toggle
|
|
180
|
+
leads the always-visible main header; the drawer's sits in a
|
|
181
|
+
`FloatingToolbar` passed as the drawer's own `restoreControl`, which the panel
|
|
182
|
+
floats in its column's safe-area-aware bottom-end corner, next to where the
|
|
183
|
+
drawer opens — do not hand-roll a conditional floating control beside the
|
|
184
|
+
panel. `wireSidebar` owns the toggle delegation, moves focus into a
|
|
185
|
+
panel on open, restores it on close (to the trigger, or to the panel's expand toggle when
|
|
186
|
+
the trigger sits inside the collapsed panel), and — when a `deviceClass()` reports
|
|
187
|
+
`compact` — presents the panels as a dismissable **overlay** (backdrop, Escape
|
|
188
|
+
and backdrop-click collapse, and a trapped Tab ring, the ARIA dialog pattern).
|
|
189
|
+
The overlay starts closed and opens only from a toggle; the rail's signal is
|
|
190
|
+
seeded from the device class with `inlineCollapsed: false`, so the first compact
|
|
191
|
+
render has no overlay and a wide crossing restores the open inline rail. It
|
|
192
|
+
also persists each panel's inline collapsed state through a supplied storage hook. A
|
|
193
|
+
filling `Row` (`fill` plus `rootAttributes`) is the root: it takes the frame's
|
|
194
|
+
definite height and places the rail beside a `List` column, and a one-column
|
|
195
|
+
`Grid` grows the main pane above the drawer. Because the panels sit at the real
|
|
196
|
+
frame edges, each grows through its edge's safe area and hands that edge back to
|
|
197
|
+
its siblings when it collapses; the drawer's activity log is a `ValueTable`. The app owns each
|
|
198
|
+
`collapsed` signal, the panel sizes, and the content; the wire owns the
|
|
199
|
+
ephemeral interaction. For a full three-pane shell use `Workbench` instead — see
|
|
200
|
+
[`app-layouts.md`](app-layouts.md). This recipe is covered end-to-end across
|
|
201
|
+
Chromium, Firefox, and WebKit by `tests/browser/collapsible-sidebar-recipe.spec.ts`.
|
|
123
202
|
|
|
124
203
|
## Rules shared by every recipe
|
|
125
204
|
|
|
@@ -128,9 +207,17 @@ settles the chrome (reduced motion collapses the slide to instant). A live
|
|
|
128
207
|
- For direct `wa-*` JSX, import types from `@kerfjs/ui/webawesome`. Import only
|
|
129
208
|
individual Web Awesome registration modules and theme them with
|
|
130
209
|
`@kerfjs/ui/webawesome.css`.
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
210
|
+
- Compose, don't style. A recipe ships no stylesheet, sets no inline style, and
|
|
211
|
+
names no class outside the published layout vocabulary (`.kui-content`,
|
|
212
|
+
`.kui-control-cluster`, …) and themed Web Awesome classes — a content item is
|
|
213
|
+
a `ContentItem`, not a hand-written `.kui-content-item`; it configures
|
|
214
|
+
components through props, `rootAttributes`, and tokens. When a recipe needs a
|
|
215
|
+
capability no component offers, record it as a component gap rather than
|
|
216
|
+
papering over it with CSS. `npm run check:recipes` enforces these rules on
|
|
217
|
+
every file in `ux-demo/recipes/`.
|
|
218
|
+
- Each recipe also exports a catalog-only `presentation`: the `CatalogExample`
|
|
219
|
+
viewport that frames it in the UX catalog and its ownership note. An
|
|
220
|
+
application that copies the recipe ignores that export and mounts the
|
|
221
|
+
controller into its own container.
|
|
135
222
|
- Start from the copyable mount adapter, or reproduce its complete boundary:
|
|
136
223
|
wire stable `data-action` hooks once and retain every disposer.
|
package/docs/split-view.md
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
# Split view (list-detail)
|
|
2
2
|
|
|
3
|
-
`@kerfjs/ui/split-view` is a list-detail
|
|
3
|
+
`@kerfjs/ui/split-view` is a list-detail layout: a list and a
|
|
4
4
|
detail side by side on roomy screens, collapsing to a `NavStack` (list → detail)
|
|
5
5
|
on compact ones. One of the opt-in app layouts (see
|
|
6
6
|
[`../../docs/23-app-layouts.md`](../../docs/23-app-layouts.md)).
|
|
7
7
|
|
|
8
8
|
```ts
|
|
9
|
-
import { SplitView } from
|
|
10
|
-
import { deviceClass } from
|
|
11
|
-
|
|
12
|
-
// plus nav-stack.css when the compact path is reachable, and
|
|
13
|
-
// wireResizableRegions / wireNavStack for the interactive behavior.
|
|
9
|
+
import { SplitView } from "@kerfjs/ui/split-view";
|
|
10
|
+
import { deviceClass } from "@kerfjs/ui/device-class";
|
|
11
|
+
// plus wireResizableRegions / wireNavStack for the interactive behavior.
|
|
14
12
|
```
|
|
15
13
|
|
|
14
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
15
|
+
webpack do by default), the import above also
|
|
16
|
+
loads SplitView's stylesheet and those of the components it renders internally
|
|
17
|
+
(its compact `NavStack`, `ResizableRegion`, and the toolbar
|
|
18
|
+
components). Without that condition, import the manual stylesheets instead:
|
|
19
|
+
`@kerfjs/ui/split-view.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
|
+
|
|
21
|
+
## Safe areas
|
|
22
|
+
|
|
23
|
+
The list pane grows by the inline-start unsafe inset and pads for the edges it
|
|
24
|
+
touches; the detail pads for its own outer edges. Neither is inset on the
|
|
25
|
+
shared interior edge. A pane whose only child is a `Pane` lets that child own
|
|
26
|
+
the insets, and the compact form hands them to its `NavStack`. See
|
|
27
|
+
[Choosing an app layout › Safe areas](app-layouts.md#safe-areas).
|
|
28
|
+
|
|
29
|
+
For a lowered list or detail background, render a `Pane` in that region with
|
|
30
|
+
`appearance="sunken"`. SplitView arranges regions but does not own their
|
|
31
|
+
vertical scroll; its compact NavStack form can use the view's or nested Pane's
|
|
32
|
+
appearance. See [Lowered work surfaces](layout.md#lowered-work-surfaces).
|
|
33
|
+
|
|
16
34
|
## Responsive by device class
|
|
17
35
|
|
|
18
36
|
`SplitView` is declarative; the app derives `compact` from the device class and
|
|
@@ -45,5 +63,58 @@ const selected = signal<string | null>(null);
|
|
|
45
63
|
app's selection). This is the portrait-tablet / handset presentation; as a
|
|
46
64
|
dialog the compact form is a full-screen or large partial-cover modal.
|
|
47
65
|
|
|
66
|
+
## Configuring the list region and the compact stack
|
|
67
|
+
|
|
68
|
+
`resizable` forwards the list's `ResizableRegion` configuration alongside
|
|
69
|
+
`size`, `min`, and `max`: `separator` (`"hidden"` keeps the resize hit target
|
|
70
|
+
but paints no line), `handleIcon`, `contentOverflow`, and collapse —
|
|
71
|
+
`collapsed`, `transitioning`, `collapseMotion`, `restoreControl`, and
|
|
72
|
+
`restorePosition`. A collapsed list snaps to zero width, renders `inert` and
|
|
73
|
+
`aria-hidden`, and the detail fills the split; the app owns the `collapsed`
|
|
74
|
+
flag and renders the restore control (usually a `FloatingToolbar`). Omitted
|
|
75
|
+
options keep the region's defaults.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
resizable={{
|
|
79
|
+
size: listWidth.value,
|
|
80
|
+
min: 220,
|
|
81
|
+
max: 480,
|
|
82
|
+
collapsed: listCollapsed.value,
|
|
83
|
+
restoreControl: <ShowThreadsToolbar />,
|
|
84
|
+
}}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`compactStack` configures the compact `NavStack`: `toolbarConfig`, `backIcon`,
|
|
88
|
+
`backText`, `hideToolbar`, the persistent `bottomToolbar`, and `chromeDividers`
|
|
89
|
+
forward to the stack, and `list` / `detail` give each view its own structured
|
|
90
|
+
top `toolbar` (`leading`, `center`, `trailing`) and `bottomToolbar`:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
compactStack={{
|
|
94
|
+
backText: "Threads",
|
|
95
|
+
toolbarConfig: { headingLevel: 1 },
|
|
96
|
+
list: { toolbar: { trailing: <ComposeGroup /> } },
|
|
97
|
+
detail: {
|
|
98
|
+
toolbar: { trailing: <ReplyGroup /> },
|
|
99
|
+
bottomToolbar: { label: "Message actions", leading: <MessageActions /> },
|
|
100
|
+
},
|
|
101
|
+
}}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The catalog's **Interactive compact drill-down** example exercises this exact
|
|
105
|
+
controlled flow: a list action sets the selected message, `detailActive` pushes
|
|
106
|
+
its detail, and the wired Back action clears the selection to reveal the
|
|
107
|
+
preserved list. It also forwards `compactStack`: a level-2 heading title over
|
|
108
|
+
a bottom divider, a Compose group on the list view, and a Reply group plus a
|
|
109
|
+
bottom toolbar on the detail. Use the same structure in application demos so
|
|
110
|
+
compact examples show the interaction rather than rendering a disconnected
|
|
111
|
+
detail state.
|
|
112
|
+
|
|
113
|
+
The catalog's **Resizable, collapsible list** example forwards `resizable`: a
|
|
114
|
+
hidden separator that still resizes the list (its committed width comes back
|
|
115
|
+
through `wireResizableRegions`' `onCommit` into the app's size signal), a Hide
|
|
116
|
+
control in the list's own toolbar, and a `FloatingToolbar` restore control in
|
|
117
|
+
the split's bottom-start corner.
|
|
118
|
+
|
|
48
119
|
Compose the interactive wiring from the existing helpers — `SplitView` adds no
|
|
49
120
|
wire of its own.
|