@kerfjs/ui 5.0.0-beta.7 → 5.0.0-beta.70
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 +501 -139
- package/ai/application-ui-diagnostic-ids-v1.json +109 -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 +3910 -464
- package/ai/component-catalog.schema.json +92 -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 +524 -0
- package/ai/component-composition.d.ts +127 -0
- package/ai/component-composition.json +7128 -0
- package/ai/component-composition.schema.json +399 -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 +93 -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 +98 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +89 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +94 -0
- package/ai/components/list.md +105 -0
- package/ai/components/loading-spinner.md +73 -0
- package/ai/components/lucide-icon.md +78 -0
- package/ai/components/nav-stack.md +104 -0
- package/ai/components/pane.md +101 -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 +113 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +102 -0
- package/ai/components/state-banner.md +94 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +78 -0
- package/ai/components/tab-bar.md +113 -0
- package/ai/components/tab-scaffold.md +94 -0
- package/ai/components/tabs.md +95 -0
- package/ai/components/text.md +85 -0
- package/ai/components/token-search-field.md +106 -0
- package/ai/components/toolbar-control-group.md +102 -0
- package/ai/components/toolbar-text.md +79 -0
- package/ai/components/toolbar.md +97 -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 +118 -0
- package/ai/public-api-signatures-v1.md +2748 -210
- package/ai/skill.md +286 -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 +286 -0
- package/analyzer/index.d.mts +52 -0
- package/analyzer/index.mjs +2038 -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 +52 -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} +4 -2
- 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/{panel-header.js → nav-stack.js} +5 -3
- 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 +1 -0
- package/dist/browser/spacer.js +3 -0
- package/dist/browser/split-view.js +11 -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-scaffold.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 +503 -0
- package/dist/catalog.js.map +1 -0
- package/dist/chip.d.ts +35 -0
- package/dist/chip.js +3 -0
- package/dist/chip.js.map +1 -0
- package/dist/chunk-2G2ZJQYK.js +152 -0
- package/dist/chunk-2G2ZJQYK.js.map +1 -0
- package/dist/chunk-3BYFWTP3.js +108 -0
- package/dist/chunk-3BYFWTP3.js.map +1 -0
- package/dist/chunk-47CKKLBE.js +34 -0
- package/dist/chunk-47CKKLBE.js.map +1 -0
- package/dist/chunk-4SQK27MR.js +202 -0
- package/dist/chunk-4SQK27MR.js.map +1 -0
- package/dist/chunk-5I7QGQVT.js +24 -0
- package/dist/chunk-5I7QGQVT.js.map +1 -0
- package/dist/chunk-6DFDTWGG.js +288 -0
- package/dist/chunk-6DFDTWGG.js.map +1 -0
- package/dist/chunk-7OKX3EF6.js +135 -0
- package/dist/chunk-7OKX3EF6.js.map +1 -0
- package/dist/chunk-AHEG27M7.js +66 -0
- package/dist/chunk-AHEG27M7.js.map +1 -0
- package/dist/chunk-AYUHMAI6.js +48 -0
- package/dist/chunk-AYUHMAI6.js.map +1 -0
- package/dist/chunk-B2ZMR7NY.js +85 -0
- package/dist/chunk-B2ZMR7NY.js.map +1 -0
- package/dist/chunk-BFPBS5Y4.js +250 -0
- package/dist/chunk-BFPBS5Y4.js.map +1 -0
- package/dist/chunk-DB5ADJKF.js +775 -0
- package/dist/chunk-DB5ADJKF.js.map +1 -0
- package/dist/chunk-DC6CN2DS.js +123 -0
- package/dist/chunk-DC6CN2DS.js.map +1 -0
- package/dist/chunk-DG6G5EPF.js +35 -0
- package/dist/chunk-DG6G5EPF.js.map +1 -0
- package/dist/{chunk-56RJXPHG.js → chunk-G4S2QU6V.js} +7 -4
- package/dist/chunk-G4S2QU6V.js.map +1 -0
- package/dist/chunk-GLDWRCAM.js +49 -0
- package/dist/chunk-GLDWRCAM.js.map +1 -0
- package/dist/chunk-I3Q7KKYM.js +33 -0
- package/dist/chunk-I3Q7KKYM.js.map +1 -0
- package/dist/chunk-IA7TMD4Y.js +288 -0
- package/dist/chunk-IA7TMD4Y.js.map +1 -0
- package/dist/chunk-J3KGJ6P6.js +135 -0
- package/dist/chunk-J3KGJ6P6.js.map +1 -0
- package/dist/chunk-K47P7QZC.js +17 -0
- package/dist/chunk-K47P7QZC.js.map +1 -0
- package/dist/chunk-K67Y2JNF.js +222 -0
- package/dist/chunk-K67Y2JNF.js.map +1 -0
- package/dist/chunk-KCCEH7RF.js +492 -0
- package/dist/chunk-KCCEH7RF.js.map +1 -0
- package/dist/chunk-KLJKU6ZL.js +109 -0
- package/dist/chunk-KLJKU6ZL.js.map +1 -0
- package/dist/chunk-KVBRMEPM.js +44 -0
- package/dist/chunk-KVBRMEPM.js.map +1 -0
- package/dist/chunk-M6DEEBEF.js +156 -0
- package/dist/chunk-M6DEEBEF.js.map +1 -0
- package/dist/chunk-MEY33VWB.js +44 -0
- package/dist/chunk-MEY33VWB.js.map +1 -0
- package/dist/chunk-MP2GDBQZ.js +50 -0
- package/dist/chunk-MP2GDBQZ.js.map +1 -0
- package/dist/chunk-NC4CFOID.js +188 -0
- package/dist/chunk-NC4CFOID.js.map +1 -0
- package/dist/chunk-NCSWXG7G.js +80 -0
- package/dist/chunk-NCSWXG7G.js.map +1 -0
- package/dist/chunk-NN6GYOA2.js +47 -0
- package/dist/chunk-NN6GYOA2.js.map +1 -0
- package/dist/chunk-OXO2QJWV.js +55 -0
- package/dist/chunk-OXO2QJWV.js.map +1 -0
- package/dist/chunk-P7D3EMXM.js +52 -0
- package/dist/chunk-P7D3EMXM.js.map +1 -0
- package/dist/chunk-PSHUSWQH.js +18 -0
- package/dist/chunk-PSHUSWQH.js.map +1 -0
- package/dist/chunk-Q6YU3BT7.js +138 -0
- package/dist/chunk-Q6YU3BT7.js.map +1 -0
- package/dist/chunk-QJ5VFCW3.js +131 -0
- package/dist/chunk-QJ5VFCW3.js.map +1 -0
- package/dist/chunk-RGS4WX2M.js +44 -0
- package/dist/chunk-RGS4WX2M.js.map +1 -0
- package/dist/chunk-RNQNEENY.js +146 -0
- package/dist/chunk-RNQNEENY.js.map +1 -0
- package/dist/chunk-RVERAFFY.js +291 -0
- package/dist/chunk-RVERAFFY.js.map +1 -0
- package/dist/chunk-SMZGAPCU.js +70 -0
- package/dist/chunk-SMZGAPCU.js.map +1 -0
- package/dist/{chunk-7BR3DO2A.js → chunk-SRSJO5QE.js} +13 -4
- package/dist/chunk-SRSJO5QE.js.map +1 -0
- package/dist/chunk-T2E5WBCZ.js +482 -0
- package/dist/chunk-T2E5WBCZ.js.map +1 -0
- package/dist/chunk-TJK44RQC.js +452 -0
- package/dist/chunk-TJK44RQC.js.map +1 -0
- package/dist/chunk-UIDKY4UB.js +14 -0
- package/dist/chunk-UIDKY4UB.js.map +1 -0
- package/dist/chunk-V3DX3K65.js +43 -0
- package/dist/chunk-V3DX3K65.js.map +1 -0
- package/dist/chunk-VZOFZPSO.js +71 -0
- package/dist/chunk-VZOFZPSO.js.map +1 -0
- package/dist/chunk-W2AC6Q2A.js +83 -0
- package/dist/chunk-W2AC6Q2A.js.map +1 -0
- package/dist/chunk-WF75U3V4.js +33 -0
- package/dist/chunk-WF75U3V4.js.map +1 -0
- package/dist/chunk-WTSNV5RG.js +52 -0
- package/dist/chunk-WTSNV5RG.js.map +1 -0
- package/dist/{chunk-YGN7OMLT.js → chunk-X5QSICJ3.js} +8 -5
- package/dist/chunk-X5QSICJ3.js.map +1 -0
- package/dist/chunk-YDGNU2OD.js +61 -0
- package/dist/chunk-YDGNU2OD.js.map +1 -0
- package/dist/collapsible-panel.d.ts +133 -0
- package/dist/collapsible-panel.js +131 -0
- package/dist/collapsible-panel.js.map +1 -0
- package/dist/content-item.d.ts +81 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/css-values.d.ts +107 -0
- package/dist/css-values.js +3 -0
- package/dist/css-values.js.map +1 -0
- package/dist/device-class.js +33 -5
- 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 +50 -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 +34 -14
- package/dist/index.js +43 -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 +99 -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 +9 -2
- package/dist/loading-spinner.js +2 -1
- package/dist/lucide-icon.d.ts +9 -2
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack.d.ts +66 -10
- package/dist/nav-stack.js +6 -1
- package/dist/pane.d.ts +108 -0
- package/dist/pane.js +4 -0
- package/dist/pane.js.map +1 -0
- package/dist/panel-toolbar-DDKh4uKd.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 +243 -2
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +102 -8
- package/dist/select.js +3 -1
- package/dist/semantic-content-BbzjvSu9.d.ts +14 -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 +39 -7
- package/dist/split-view.js +120 -10
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +18 -6
- package/dist/state-banner.js +3 -1
- package/dist/styles/app-tab.css +221 -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 +12 -0
- package/dist/styles/catalog.css +5 -0
- package/dist/styles/chip.css +132 -0
- package/dist/styles/collapsible-panel.css +575 -0
- package/dist/styles/content-item.css +75 -0
- package/dist/styles/document.css +23 -0
- package/dist/styles/floating-toolbar.css +119 -0
- package/dist/styles/foundation.css +178 -40
- package/dist/styles/grid.css +35 -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 +5 -0
- package/dist/styles/nav-stack.css +172 -47
- package/dist/styles/pane.css +263 -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 +29 -0
- package/dist/styles/surface-scaffold.css +56 -0
- package/dist/styles/tab-bar.css +147 -9
- package/dist/styles/tab-scaffold.css +126 -3
- package/dist/styles/text.css +112 -0
- package/dist/styles/token-search-field.css +155 -55
- package/dist/styles/toolbar-control-group.css +608 -29
- package/dist/styles/toolbar-text.css +101 -8
- package/dist/styles/toolbar.css +334 -12
- package/dist/styles/value-table.css +34 -4
- package/dist/styles/webawesome.css +365 -10
- package/dist/styles/workbench.css +980 -7
- package/dist/sunken-panel.d.ts +27 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/surface-scaffold.d.ts +30 -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-scaffold.d.ts +57 -7
- package/dist/tab-scaffold.js +83 -9
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/text.d.ts +56 -0
- package/dist/text.js +3 -0
- package/dist/text.js.map +1 -0
- package/dist/token-search-field-CVGwDn2y.d.ts +154 -0
- package/dist/token-search-field.d.ts +3 -43
- package/dist/token-search-field.js +2 -1
- 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 +77 -7
- package/dist/toolbar-control-group.js +3 -1
- package/dist/toolbar-text.d.ts +35 -4
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +59 -7
- package/dist/toolbar.js +1 -1
- package/dist/types-BuHELdXR.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 +327 -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 +147 -7
- 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-scaffold.js +9 -4
- package/dist/wire-tab-scaffold.js.map +1 -1
- package/dist/wire-token-search-fields.d.ts +65 -3
- package/dist/wire-token-search-fields.js +2 -1
- 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 +244 -9
- package/dist/workbench.js +17 -15
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +476 -24
- package/docs/app-layouts.md +106 -8
- package/docs/apple-hig.md +1 -0
- package/docs/catalog.md +483 -0
- package/docs/collapsible-panel.md +371 -0
- package/docs/component-contract.md +658 -56
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +529 -90
- 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/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-control-group/borderless-single-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group.svg +1 -0
- package/docs/design/templates/toolbar-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/default.svg +1 -0
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/large.svg +1 -0
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/small.svg +1 -0
- package/docs/design/templates/toolbar-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-text.svg +1 -0
- package/docs/design/templates/toolbar.svg +1 -0
- package/docs/design/templates/value-table/details-dark.svg +1 -0
- package/docs/design/templates/value-table/details.svg +1 -0
- package/docs/design/templates/value-table-dark.svg +1 -0
- package/docs/design/templates/value-table.svg +1 -0
- package/docs/design/templates.md +138 -0
- package/docs/design-philosophy.md +48 -20
- package/docs/device-class.md +10 -9
- package/docs/document-baseline.md +38 -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 +534 -59
- package/docs/nav-stack.md +138 -14
- package/docs/recipes.md +137 -54
- package/docs/split-view.md +74 -6
- package/docs/sunken-panel.md +87 -0
- package/docs/surface-scaffold.md +28 -0
- package/docs/tab-scaffold.md +99 -10
- package/docs/type-contracts.md +134 -0
- package/docs/ui-analyzer.md +347 -0
- package/docs/ui-doctor.md +128 -0
- package/docs/ui-evaluator.md +139 -0
- package/docs/ux-demo.md +41 -16
- package/docs/webawesome-theme.md +218 -16
- package/docs/workbench.md +608 -12
- package/doctor/cli.mjs +120 -0
- package/doctor/config.schema.json +72 -0
- package/doctor/eslint-diagnostics.d.mts +24 -0
- package/doctor/eslint-diagnostics.mjs +24 -0
- package/doctor/index.d.mts +121 -0
- package/doctor/index.mjs +1324 -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 +445 -48
- package/package.json +249 -37
- 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 +282 -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 +79 -24
- 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/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-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-KJYXOTG3.js +0 -10
- package/dist/chunk-KJYXOTG3.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-N3SUXLLS.js +0 -23
- package/dist/chunk-N3SUXLLS.js.map +0 -1
- package/dist/chunk-PONXLV5U.js +0 -19
- package/dist/chunk-PONXLV5U.js.map +0 -1
- package/dist/chunk-TZNCCM5H.js +0 -20
- package/dist/chunk-TZNCCM5H.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 -28
- 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/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`, `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,147 @@ 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
|
+
title: "Inbox",
|
|
32
|
+
content: <InboxView />,
|
|
33
|
+
bottomToolbar: <InboxStatus />,
|
|
34
|
+
},
|
|
35
|
+
]);
|
|
24
36
|
|
|
25
37
|
// render inside mount():
|
|
26
38
|
<NavStack id="mail" label="Mail" views={views.value} />;
|
|
27
39
|
|
|
28
40
|
// once, after first render:
|
|
29
|
-
const dispose = wireNavStack(root, {
|
|
41
|
+
const dispose = wireNavStack(root, {
|
|
42
|
+
onBack: () => {
|
|
43
|
+
views.value = views.value.slice(0, -1);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
30
46
|
|
|
31
47
|
// push / pop by editing the signal:
|
|
32
|
-
views.value = [
|
|
48
|
+
views.value = [
|
|
49
|
+
...views.value,
|
|
50
|
+
{ key: id, title: "Message", content: <MessageView id={id} /> },
|
|
51
|
+
];
|
|
33
52
|
```
|
|
34
53
|
|
|
35
54
|
`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 `title`,
|
|
38
|
-
`
|
|
39
|
-
|
|
55
|
+
mounted (so their DOM state survives) but hidden. Each entry carries a
|
|
56
|
+
`key` (stable identity), `content`, an optional `title`, optional per-view
|
|
57
|
+
`leading`, `center`, and trailing `toolbar` groups for the top toolbar, and an
|
|
58
|
+
optional per-view `bottomToolbar`. The component-level
|
|
59
|
+
`bottomToolbar` remains a persistent fallback for views that do not provide one.
|
|
60
|
+
Each view can also provide `header`, pinned below its top toolbar and above
|
|
61
|
+
that view's single scroll area. A fixed heading, notice, or section selector
|
|
62
|
+
can therefore change with the active screen without adding another scroller.
|
|
63
|
+
The back control appears automatically once the stack has more than one entry;
|
|
64
|
+
`wireNavStack`'s `onBack` is where the app pops its own signal.
|
|
65
|
+
|
|
66
|
+
Set a view's `appearance: "sunken"` to paint its scroll viewport with the
|
|
67
|
+
shared lowered-surface color, including space after short content. When the
|
|
68
|
+
view holds a `Pane` as its only child, set the appearance on the Pane instead
|
|
69
|
+
if its content owns scrolling. See [Lowered work surfaces](layout.md#lowered-work-surfaces).
|
|
70
|
+
|
|
71
|
+
## The top toolbar
|
|
72
|
+
|
|
73
|
+
The top chrome is a real `Toolbar`, so it follows the same zone,
|
|
74
|
+
group, and responsive rules as every other toolbar. Its leading zone holds the
|
|
75
|
+
back control (a borderless `ToolbarControlGroup`, shown once the stack has
|
|
76
|
+
depth), then the active view's `leading` groups, then the view's `title` as a
|
|
77
|
+
`ToolbarText`. The view's `center` fills the center zone and its `toolbar`
|
|
78
|
+
fills the trailing zone. Give each zone `ToolbarControlGroup`s or `ToolbarText`,
|
|
79
|
+
as in any toolbar.
|
|
80
|
+
|
|
81
|
+
Configure the toolbar with `toolbarConfig` instead of styling it:
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<NavStack
|
|
85
|
+
id="mail"
|
|
86
|
+
label="Mail"
|
|
87
|
+
views={views.value}
|
|
88
|
+
backText={previousTitle}
|
|
89
|
+
toolbarConfig={{
|
|
90
|
+
headingLevel: 1,
|
|
91
|
+
titleSize: "xlarge",
|
|
92
|
+
dividerSides: "b",
|
|
93
|
+
responsive: "wrap",
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- `toolbarConfig` forwards the `Toolbar` configuration (`dividerSides`,
|
|
99
|
+
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`) and adds
|
|
100
|
+
`label` (the toolbar's accessible name), `titleSize` (the title's
|
|
101
|
+
`ToolbarText` size, default `large`), and `headingLevel` (expose the title as
|
|
102
|
+
a heading; default a plain span). The defaults keep the stack's own chrome:
|
|
103
|
+
no divider, the standard Toolbar height (a 44px control band with 8px above and below), and the top and side safe-area edges
|
|
104
|
+
claimed.
|
|
105
|
+
- `backIcon` replaces the default chevron-left icon. `backText` adds visible
|
|
106
|
+
text beside it (for example, the previous view's title); visible text names
|
|
107
|
+
the control, so `backLabel` applies only to the icon-only control.
|
|
108
|
+
|
|
109
|
+
`panelToggle` supplies a persistent final group in the trailing zone of every
|
|
110
|
+
view's top toolbar. `Workbench` uses it for a navigation panel's standard
|
|
111
|
+
collapse toggle; the active view still owns the preceding toolbar groups.
|
|
112
|
+
|
|
113
|
+
The catalog's **Configured toolbar** example shows these together: a level-2
|
|
114
|
+
heading title over a bottom divider, leading and center groups on the root
|
|
115
|
+
view, a trailing group on the pushed view, and `backText` set to the previous
|
|
116
|
+
view's title.
|
|
117
|
+
|
|
118
|
+
Focus follows the controlled stack automatically. On push, `wireNavStack`
|
|
119
|
+
remembers the focused descendant of the departing view and moves focus into the
|
|
120
|
+
new top view. On pop it restores that exact descendant when it still exists. A
|
|
121
|
+
new view prefers a descendant marked `data-nav-focus`, then its first enabled
|
|
122
|
+
focusable descendant, and finally the view container itself. Use
|
|
123
|
+
`data-nav-focus` for a heading or primary control when DOM order is not the best
|
|
124
|
+
initial reading position; it may use `tabindex="-1"` for programmatic focus.
|
|
125
|
+
When a remembered control was removed during the controlled rerender, the same
|
|
126
|
+
fallback order applies. Disposing the helper stops future transitions and
|
|
127
|
+
cleans up any temporary fallback `tabindex` it added.
|
|
128
|
+
|
|
129
|
+
## Scroll dividers
|
|
130
|
+
|
|
131
|
+
The stack draws no permanent line between its chrome and the view. With
|
|
132
|
+
`wireScrollDividers(appRoot)` installed (see
|
|
133
|
+
[Layout › Scroll dividers](layout.md#scroll-dividers)), the top chrome shows a
|
|
134
|
+
line along its bottom edge only while the active view's content is scrolled
|
|
135
|
+
beneath it, and the bottom toolbar a line along its top edge only while more
|
|
136
|
+
content lies below it — neither when the content fits. The line follows the
|
|
137
|
+
active view across a push or pop. The chrome's line is overlaid on its bottom
|
|
138
|
+
edge and the bottom toolbar's is its always-present 1px top border, colored
|
|
139
|
+
only while shown, so neither ever moves the chrome or the content. When the view's only child is a `Pane`,
|
|
140
|
+
the line keys on whichever actually scrolls — the view, or the Pane's content —
|
|
141
|
+
and a Pane header or footer draws its own boundary instead. An explicit
|
|
142
|
+
`toolbarConfig.dividerSides` still draws a permanent Toolbar edge.
|
|
143
|
+
|
|
144
|
+
`chromeDividers` configures both lines, with the same values as a `Pane`'s:
|
|
145
|
+
`scroll` (the default) follows the scroll state above and draws nothing until
|
|
146
|
+
the wiring runs; `always` keeps both lines, with or without the wiring; `none`
|
|
147
|
+
drops them even when the wiring reports scroll state. It does not change the
|
|
148
|
+
top Toolbar's own `dividerSides`.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<NavStack id="settings" label="Settings" views={views.value} chromeDividers="always" />
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Safe areas
|
|
155
|
+
|
|
156
|
+
The stack paints through a device's unsafe areas. Its chrome pads for the top
|
|
157
|
+
and side insets, its bottom toolbar for the bottom and side insets, and each
|
|
158
|
+
view pads the remaining edges inside its scroller, so content scrolls under the
|
|
159
|
+
unsafe area but can always be scrolled clear. A view whose only child is a
|
|
160
|
+
`Pane` or layout lets that child own the insets. See [Choosing an app layout › Safe areas](app-layouts.md#safe-areas).
|
|
40
161
|
|
|
41
162
|
## Transitions
|
|
42
163
|
|
|
43
164
|
`wireNavStack(root, { onBack, duration? })` observes the rendered stack and
|
|
44
165
|
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
|
-
|
|
166
|
+
view slides back off it over the revealed view; and snapshots of the previous
|
|
167
|
+
top and bottom chrome cross-fade into the active view's chrome. Focus moves to
|
|
168
|
+
the new top view independently of animation duration. It returns a disposer.
|
|
169
|
+
The animation honors `prefers-reduced-motion` (transitions collapse to instant)
|
|
170
|
+
and `duration: 0` disables it. Applicable at every device size and inside
|
|
171
|
+
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,86 @@ 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. On compact devices the dialog becomes a full-screen sheet
|
|
92
|
+
with its own labeled header and footer actions, and `SplitView` becomes a
|
|
93
|
+
`NavStack` drill-down whose back control the application pops. The
|
|
94
|
+
application owns open state, selection, the pushed detail, dismissal policy,
|
|
95
|
+
and record actions. Do not put the primary title in a header spanning both
|
|
96
|
+
columns, rebuild the dialog, or reach into private shadow parts.
|
|
78
97
|
|
|
79
98
|
## Composer form
|
|
80
99
|
|
|
81
100
|
[Open the recipe](../ux-demo/?component=recipe-composer-form) · [TSX source](../ux-demo/recipes/composer-form.tsx)
|
|
82
101
|
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
102
|
+
A direct `ToolbarText` supplies the task title, with app-owned supporting copy
|
|
103
|
+
below; their ids are referenced by the form. `ListInsetText` gives that bare
|
|
104
|
+
supporting copy the same content-item text inset as the fields. The title and
|
|
105
|
+
supporting line share a nested heading `List` with `gap="none"`, so the heading
|
|
106
|
+
unit stays together instead of taking the form's 24px section gap. Production
|
|
107
|
+
fields own labels, help, and native focus. One `List` owns the 24px major
|
|
108
|
+
rhythm; the field `List` and the action `Row` use `controlInsets` to sit on the
|
|
109
|
+
shared 8px inline gutter with 8px gaps between related controls, rather than
|
|
110
|
+
acquiring a second content-item padding inset. The app owns
|
|
88
111
|
validation, drafts, permissions, and transport. Persistent error or success
|
|
89
112
|
feedback is the only nested semantic surface and uses `StateBanner`, not a toast.
|
|
90
113
|
Because upgraded Web Awesome fields retain live value properties, controlled
|
|
@@ -106,8 +129,12 @@ rows.
|
|
|
106
129
|
|
|
107
130
|
Use `ToolbarControlGroup` for related commands, `SegmentedControl` for a few
|
|
108
131
|
visible exclusive choices, `Select` for a longer value list, and an ordinary
|
|
109
|
-
button for an independent command.
|
|
110
|
-
|
|
132
|
+
button for an independent command. Even that independent button sits in a
|
|
133
|
+
single-control `ToolbarControlGroup`, which keeps its height, pill shape, focus,
|
|
134
|
+
and hover treatment aligned with the adjacent toolbar controls. At compact
|
|
135
|
+
widths the toolbar stacks its zones and wraps whole trailing groups onto another
|
|
136
|
+
row, so the last action is never clipped. The app owns values, actions,
|
|
137
|
+
persistence, and responsive priority.
|
|
111
138
|
|
|
112
139
|
## Navigation stack
|
|
113
140
|
|
|
@@ -116,11 +143,59 @@ and responsive priority.
|
|
|
116
143
|
Drill from a library list into a detail and back with `NavStack`
|
|
117
144
|
(`@kerfjs/ui/nav-stack`): the app owns the stack as a signal of views and
|
|
118
145
|
pushes/pops it, `NavStack` renders it, and `wireNavStack` slides the content and
|
|
119
|
-
settles the chrome (reduced motion collapses the slide to instant).
|
|
120
|
-
|
|
146
|
+
settles the chrome (reduced motion collapses the slide to instant). See the
|
|
147
|
+
layout guide
|
|
121
148
|
[`app-layouts.md`](app-layouts.md) for choosing among `NavStack`, `SplitView`,
|
|
122
149
|
`Workbench`, and `TabScaffold`.
|
|
123
150
|
|
|
151
|
+
## Loading inspector
|
|
152
|
+
|
|
153
|
+
[Open the recipe](../ux-demo/?component=recipe-loading-inspector) · [TSX source](../ux-demo/recipes/loading-inspector.tsx)
|
|
154
|
+
|
|
155
|
+
A record inspector whose per-record values load asynchronously. Every
|
|
156
|
+
value-bearing component (`ToolbarText`, `ValueTable`/`ValueTableRow`, `Select`,
|
|
157
|
+
`SegmentedControl`, `ListItem`, `StateBanner`) takes its `placeholder` from one
|
|
158
|
+
loading flag, so the same real chrome renders a faithful loading state and then
|
|
159
|
+
the populated record — no separate skeleton markup. The composition is the point;
|
|
160
|
+
`Skeleton` is the primitive it builds on. Its heading `Toolbar` uses
|
|
161
|
+
`responsive="wrap"`, so on a narrow inspector the toggle moves below a whole
|
|
162
|
+
record title instead of truncating it. The app owns the loading lifecycle and
|
|
163
|
+
which values are still unknown.
|
|
164
|
+
|
|
165
|
+
## Collapsible sidebar
|
|
166
|
+
|
|
167
|
+
[Open the recipe](../ux-demo/?component=recipe-collapsible-sidebar) · [TSX source](../ux-demo/recipes/collapsible-sidebar.tsx)
|
|
168
|
+
|
|
169
|
+
A mini app frame whose left navigation rail and bottom activity drawer are
|
|
170
|
+
standalone `CollapsiblePanel`s (`@kerfjs/ui/collapsible-panel`) driven by
|
|
171
|
+
`wireSidebar` (`@kerfjs/ui/wire-sidebar`). Each panel takes a `toolbar` — a
|
|
172
|
+
title plus the standard per-side toggle — so the hide control lives in the
|
|
173
|
+
panel's own header, and `CollapsiblePanelRelocated` renders the matching show
|
|
174
|
+
control only while the panel is collapsed, so exactly one control owns each
|
|
175
|
+
action and a collapsed panel is still reachable. The rail's relocated toggle
|
|
176
|
+
leads the always-visible main header; the drawer's sits in a
|
|
177
|
+
`FloatingToolbar` passed as the drawer's own `restoreControl`, which the panel
|
|
178
|
+
floats in its column's safe-area-aware bottom-end corner, next to where the
|
|
179
|
+
drawer opens — do not hand-roll a conditional floating control beside the
|
|
180
|
+
panel. `wireSidebar` owns the toggle delegation, moves focus into a
|
|
181
|
+
panel on open, restores it on close (to the trigger, or to the panel's expand toggle when
|
|
182
|
+
the trigger sits inside the collapsed panel), and — when a `deviceClass()` reports
|
|
183
|
+
`compact` — presents the panels as a dismissable **overlay** (backdrop, Escape
|
|
184
|
+
and backdrop-click collapse, and a trapped Tab ring, the ARIA dialog pattern).
|
|
185
|
+
The overlay starts closed and opens only from a toggle; the rail's signal is
|
|
186
|
+
seeded from the device class with `inlineCollapsed: false`, so the first compact
|
|
187
|
+
render has no overlay and a wide crossing restores the open inline rail. It
|
|
188
|
+
also persists each panel's inline collapsed state through a supplied storage hook. A
|
|
189
|
+
filling `Row` (`fill` plus `rootAttributes`) is the root: it takes the frame's
|
|
190
|
+
definite height and places the rail beside a `List` column, and a one-column
|
|
191
|
+
`Grid` grows the main pane above the drawer. Because the panels sit at the real
|
|
192
|
+
frame edges, each grows through its edge's safe area and hands that edge back to
|
|
193
|
+
its siblings when it collapses; the drawer's activity log is a `ValueTable`. The app owns each
|
|
194
|
+
`collapsed` signal, the panel sizes, and the content; the wire owns the
|
|
195
|
+
ephemeral interaction. For a full three-pane shell use `Workbench` instead — see
|
|
196
|
+
[`app-layouts.md`](app-layouts.md). This recipe is covered end-to-end across
|
|
197
|
+
Chromium, Firefox, and WebKit by `tests/browser/collapsible-sidebar-recipe.spec.ts`.
|
|
198
|
+
|
|
124
199
|
## Rules shared by every recipe
|
|
125
200
|
|
|
126
201
|
- Import `@kerfjs/ui/layout.css`; keep every pane unpadded and use exactly one
|
|
@@ -128,9 +203,17 @@ settles the chrome (reduced motion collapses the slide to instant). A live
|
|
|
128
203
|
- For direct `wa-*` JSX, import types from `@kerfjs/ui/webawesome`. Import only
|
|
129
204
|
individual Web Awesome registration modules and theme them with
|
|
130
205
|
`@kerfjs/ui/webawesome.css`.
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
206
|
+
- Compose, don't style. A recipe ships no stylesheet, sets no inline style, and
|
|
207
|
+
names no class outside the published layout vocabulary (`.kui-content`,
|
|
208
|
+
`.kui-control-cluster`, …) and themed Web Awesome classes — a content item is
|
|
209
|
+
a `ContentItem`, not a hand-written `.kui-content-item`; it configures
|
|
210
|
+
components through props, `rootAttributes`, and tokens. When a recipe needs a
|
|
211
|
+
capability no component offers, record it as a component gap rather than
|
|
212
|
+
papering over it with CSS. `npm run check:recipes` enforces these rules on
|
|
213
|
+
every file in `ux-demo/recipes/`.
|
|
214
|
+
- Each recipe also exports a catalog-only `presentation`: the `CatalogExample`
|
|
215
|
+
viewport that frames it in the UX catalog and its ownership note. An
|
|
216
|
+
application that copies the recipe ignores that export and mounts the
|
|
217
|
+
controller into its own container.
|
|
135
218
|
- Start from the copyable mount adapter, or reproduce its complete boundary:
|
|
136
219
|
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,55 @@ 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 top-toolbar groups
|
|
90
|
+
(`leading`, `center`, trailing `toolbar`) and `bottomToolbar`:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
compactStack={{
|
|
94
|
+
backText: "Threads",
|
|
95
|
+
toolbarConfig: { headingLevel: 1 },
|
|
96
|
+
list: { toolbar: <ComposeGroup /> },
|
|
97
|
+
detail: { toolbar: <ReplyGroup />, bottomToolbar: <MessageActions /> },
|
|
98
|
+
}}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The catalog's **Interactive compact drill-down** example exercises this exact
|
|
102
|
+
controlled flow: a list action sets the selected message, `detailActive` pushes
|
|
103
|
+
its detail, and the wired Back action clears the selection to reveal the
|
|
104
|
+
preserved list. It also forwards `compactStack`: a level-2 heading title over
|
|
105
|
+
a bottom divider, a Compose group on the list view, and a Reply group plus a
|
|
106
|
+
bottom toolbar on the detail. Use the same structure in application demos so
|
|
107
|
+
compact examples show the interaction rather than rendering a disconnected
|
|
108
|
+
detail state.
|
|
109
|
+
|
|
110
|
+
The catalog's **Resizable, collapsible list** example forwards `resizable`: a
|
|
111
|
+
hidden separator that still resizes the list (its committed width comes back
|
|
112
|
+
through `wireResizableRegions`' `onCommit` into the app's size signal), a Hide
|
|
113
|
+
control in the list's own toolbar, and a `FloatingToolbar` restore control in
|
|
114
|
+
the split's bottom-start corner.
|
|
115
|
+
|
|
48
116
|
Compose the interactive wiring from the existing helpers — `SplitView` adds no
|
|
49
117
|
wire of its own.
|
|
@@ -0,0 +1,87 @@
|
|
|
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
|
+
Do not use `SunkenPanel` merely to add padding, as a substitute for pane
|
|
60
|
+
header/content/footer anatomy, or around a child that already owns the same
|
|
61
|
+
outer surface.
|
|
62
|
+
|
|
63
|
+
For a lowered scrolling work area with Pane chrome, use
|
|
64
|
+
[`Pane appearance="sunken"`](layout.md#lowered-work-surfaces). It paints the
|
|
65
|
+
scroll viewport and empty space without adding a second scroller.
|
|
66
|
+
|
|
67
|
+
## Public styling boundary
|
|
68
|
+
|
|
69
|
+
Override the public properties at the composition boundary:
|
|
70
|
+
|
|
71
|
+
- `--kui-sunken-panel-background`
|
|
72
|
+
- `--kui-sunken-panel-foreground`
|
|
73
|
+
- `--kui-sunken-panel-padding`
|
|
74
|
+
- `--kui-sunken-panel-gap`
|
|
75
|
+
- `--kui-sunken-panel-radius`
|
|
76
|
+
|
|
77
|
+
`--kui-sunken-panel-background` can be overridden for a known backdrop. Keep
|
|
78
|
+
the default lowered surface opaque; a translucent override compounds when
|
|
79
|
+
sunken panels nest. See [Contextual transparency](./webawesome-theme.md#contextual-transparency)
|
|
80
|
+
for the color and contrast evaluation and its opt-in bounded prototype. The
|
|
81
|
+
prototype also compares Pane and Web Awesome sunken surfaces. Assign its
|
|
82
|
+
first, second, and transparent deeper tints on application-owned wrappers;
|
|
83
|
+
a single translucent override on every nested surface has no depth cap.
|
|
84
|
+
|
|
85
|
+
The public root class is `.kui-sunken-panel`. Prefer the properties above over
|
|
86
|
+
styling descendants. The `square` shape deliberately overrides the radius
|
|
87
|
+
property with zero; use `rounded` when customizing the radius token.
|