@kerfjs/ui 5.0.0-beta.7 → 5.0.0-beta.71
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 +3905 -446
- 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 +524 -0
- package/ai/component-composition.d.ts +129 -0
- package/ai/component-composition.json +7140 -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 +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 +401 -0
- package/analyzer/index.d.mts +53 -0
- package/analyzer/index.mjs +2307 -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-SLWCCHNP.js +491 -0
- package/dist/chunk-SLWCCHNP.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-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 +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 +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 +343 -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 +667 -56
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +540 -95
- 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 +384 -0
- package/docs/ui-doctor.md +153 -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 +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 +1364 -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
|
@@ -1,11 +1,124 @@
|
|
|
1
1
|
# Public API signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.71` and `kerfjs@5.0.0-beta.71`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
|
|
4
|
+
|
|
5
|
+
## `@kerfjs/ui/css-values`
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
declare const cssValueBrand: unique symbol;
|
|
9
|
+
declare const cssLengthBrand: unique symbol;
|
|
10
|
+
declare const cssLengthExpressionBrand: unique symbol;
|
|
11
|
+
declare const cssFlexBrand: unique symbol;
|
|
12
|
+
declare const cssColorBrand: unique symbol;
|
|
13
|
+
declare const cssForegroundColorBrand: unique symbol;
|
|
14
|
+
/**
|
|
15
|
+
* A complete typed CSS value minted by a property-specific Kerf UI builder.
|
|
16
|
+
*
|
|
17
|
+
* This brand is an authoring correctness aid, not a sanitizer or security
|
|
18
|
+
* boundary. Prefer the narrower property grammar, such as {@link CssLength},
|
|
19
|
+
* whenever one is available.
|
|
20
|
+
*/
|
|
21
|
+
type CssValue = string & {
|
|
22
|
+
readonly [cssValueBrand]: 'CssValue';
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A complete CSS length-percentage value suitable for dimension-valued UI
|
|
26
|
+
* props. Despite the concise name, percentages are intentionally included.
|
|
27
|
+
*/
|
|
28
|
+
type CssLength = CssValue & {
|
|
29
|
+
readonly [cssLengthBrand]: 'CssLength';
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* An incomplete arithmetic expression. Wrap it with {@link calc} before
|
|
33
|
+
* passing it to a prop that accepts {@link CssLength}.
|
|
34
|
+
*/
|
|
35
|
+
type CssLengthExpression = string & {
|
|
36
|
+
readonly [cssLengthExpressionBrand]: 'CssLengthExpression';
|
|
37
|
+
};
|
|
38
|
+
/** A complete CSS `flex` shorthand. It is not interchangeable with a length. */
|
|
39
|
+
type CssFlex = CssValue & {
|
|
40
|
+
readonly [cssFlexBrand]: 'CssFlex';
|
|
41
|
+
};
|
|
42
|
+
/** A complete CSS color value. It is not interchangeable with a length. */
|
|
43
|
+
type CssColor = CssValue & {
|
|
44
|
+
readonly [cssColorBrand]: 'CssColor';
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A complete CSS color meant to paint a foreground: text or an icon drawn over
|
|
48
|
+
* a surface. Mint it with {@link uiColor} and a foreground token name
|
|
49
|
+
* ({@link UiForegroundColorName}) or with {@link foregroundColorVar}. It is a
|
|
50
|
+
* {@link CssColor}, but a plain `CssColor` is not a foreground color: fill,
|
|
51
|
+
* border, and surface tokens are pale backgrounds that leave a foreground
|
|
52
|
+
* nearly invisible.
|
|
53
|
+
*/
|
|
54
|
+
type CssForegroundColor = CssColor & {
|
|
55
|
+
readonly [cssForegroundColorBrand]: 'CssForegroundColor';
|
|
56
|
+
};
|
|
57
|
+
type CssFlexKeyword = 'none' | 'auto' | 'initial';
|
|
58
|
+
type CssFlexBasis = CssLength | 'auto' | 'content' | 'min-content' | 'max-content' | 'fit-content';
|
|
59
|
+
type CssSizeKeyword = 'auto' | 'min-content' | 'max-content' | 'fit-content';
|
|
60
|
+
/** A complete width/height value accepted by dimension-valued UI props. */
|
|
61
|
+
type CssSize = CssLength | CssSizeKeyword;
|
|
62
|
+
declare const uiColorNames: readonly ["brand-border-loud", "brand-border-normal", "brand-border-quiet", "brand-fill-loud", "brand-fill-normal", "brand-fill-quiet", "brand-on-fill", "brand-on-loud", "brand-on-normal", "brand-on-quiet", "danger-border-loud", "danger-border-normal", "danger-border-quiet", "danger-fill-loud", "danger-fill-normal", "danger-fill-quiet", "danger-on-fill", "danger-on-loud", "danger-on-normal", "danger-on-quiet", "neutral-border-loud", "neutral-border-normal", "neutral-border-quiet", "neutral-fill-loud", "neutral-fill-normal", "neutral-fill-quiet", "neutral-on-loud", "neutral-on-normal", "neutral-on-quiet", "pop-border-loud", "pop-border-normal", "pop-border-quiet", "pop-fill-loud", "pop-fill-normal", "pop-fill-quiet", "pop-on-fill", "pop-on-loud", "pop-on-normal", "pop-on-quiet", "success-border-loud", "success-border-normal", "success-border-quiet", "success-fill-loud", "success-fill-normal", "success-fill-quiet", "success-on-fill", "success-on-loud", "success-on-normal", "success-on-quiet", "surface", "surface-lowered", "surface-raised", "text", "text-link", "text-quiet", "warning-border-loud", "warning-border-normal", "warning-border-quiet", "warning-fill-loud", "warning-fill-normal", "warning-fill-quiet", "warning-on-fill", "warning-on-loud", "warning-on-normal", "warning-on-quiet"];
|
|
63
|
+
/** Names of the public `--kui-color-*` semantic tokens. */
|
|
64
|
+
type UiColorName = (typeof uiColorNames)[number];
|
|
65
|
+
/** The semantic tokens that paint a foreground: the `*-on-*` and text roles. */
|
|
66
|
+
type UiForegroundColorName = Extract<UiColorName, `${string}-on-${string}` | 'text' | 'text-quiet' | 'text-link'>;
|
|
67
|
+
/** Kerf UI's complete spacing-token vocabulary. `s` and `xl` are exceptions. */
|
|
68
|
+
type UiSpaceName = 'none' | '2xs' | 'xs' | 's' | 'm' | 'l' | 'xl';
|
|
69
|
+
/** Create a complete pixel length. */
|
|
70
|
+
declare function px(value: number): CssLength;
|
|
71
|
+
/** Create a complete root-font-relative length. */
|
|
72
|
+
declare function rem(value: number): CssLength;
|
|
73
|
+
/** Converts a pixel value into rem units by dividing by 16. */
|
|
74
|
+
declare function remify(value: number): CssLength;
|
|
75
|
+
/** Create a complete current-font-relative length. */
|
|
76
|
+
declare function em(value: number): CssLength;
|
|
77
|
+
/** Create a complete percentage length. */
|
|
78
|
+
declare function pct(value: number): CssLength;
|
|
79
|
+
/** Resolve a Kerf UI spacing step to its public custom property. */
|
|
80
|
+
declare function space(name: UiSpaceName): CssLength;
|
|
81
|
+
/**
|
|
82
|
+
* Reference an application-owned custom property whose contract is a CSS
|
|
83
|
+
* length-percentage. The deliberately narrow name grammar keeps this helper
|
|
84
|
+
* from becoming an arbitrary CSS-string constructor.
|
|
85
|
+
*/
|
|
86
|
+
declare function lengthVar(name: `--${string}`, fallback?: CssLength): CssLength;
|
|
87
|
+
/** Combine two or more complete lengths into a non-standalone sum. */
|
|
88
|
+
declare function plus(first: CssLength, second: CssLength, ...rest: readonly CssLength[]): CssLengthExpression;
|
|
89
|
+
/** Turn a typed length expression into a complete CSS `calc()` value. */
|
|
90
|
+
declare function calc(expression: CssLengthExpression): CssLength;
|
|
91
|
+
/** Build a complete, structured CSS flex shorthand. */
|
|
92
|
+
declare function flex(grow: number, shrink?: number, basis?: CssFlexBasis): CssFlex;
|
|
93
|
+
/**
|
|
94
|
+
* The brand {@link uiColor} returns for a token name: a
|
|
95
|
+
* {@link CssForegroundColor} for a foreground token, otherwise a plain
|
|
96
|
+
* {@link CssColor}.
|
|
97
|
+
*/
|
|
98
|
+
type UiColor<Name extends UiColorName> = Name extends UiForegroundColorName ? CssForegroundColor : CssColor;
|
|
99
|
+
/**
|
|
100
|
+
* Resolve a public Kerf UI semantic color token. A foreground token name
|
|
101
|
+
* (`success-on-quiet`, `text-quiet`, …) returns a {@link CssForegroundColor};
|
|
102
|
+
* any other token returns a plain {@link CssColor}.
|
|
103
|
+
*/
|
|
104
|
+
declare function uiColor<Name extends UiColorName>(name: Name): UiColor<Name>;
|
|
105
|
+
/** Reference an application-owned custom property whose contract is a color. */
|
|
106
|
+
declare function colorVar(name: `--${string}`, fallback?: CssColor): CssColor;
|
|
107
|
+
/**
|
|
108
|
+
* Reference an application-owned custom property whose contract is a
|
|
109
|
+
* foreground color (text or an icon over a surface). Use it where a prop
|
|
110
|
+
* accepts only {@link CssForegroundColor}, such as `SelectChoice.color`.
|
|
111
|
+
*/
|
|
112
|
+
declare function foregroundColorVar(name: `--${string}`, fallback?: CssForegroundColor): CssForegroundColor;
|
|
113
|
+
|
|
114
|
+
export { type CssColor, type CssFlex, type CssFlexBasis, type CssFlexKeyword, type CssForegroundColor, type CssLength, type CssLengthExpression, type CssSize, type CssSizeKeyword, type CssValue, type UiColor, type UiColorName, type UiForegroundColorName, type UiSpaceName, calc, colorVar, em, flex, foregroundColorVar, lengthVar, pct, plus, px, rem, remify, space, uiColor };
|
|
115
|
+
```
|
|
4
116
|
|
|
5
117
|
## `@kerfjs/ui/disclosure-arrow`
|
|
6
118
|
|
|
7
119
|
```ts
|
|
8
120
|
import { SafeHtml } from 'kerfjs';
|
|
121
|
+
import { CssLength } from './css-values.js';
|
|
9
122
|
|
|
10
123
|
type DisclosureDirection = 'up' | 'down' | 'left' | 'right';
|
|
11
124
|
interface DisclosureArrowProps {
|
|
@@ -14,9 +127,13 @@ interface DisclosureArrowProps {
|
|
|
14
127
|
closedDirection?: DisclosureDirection;
|
|
15
128
|
/** Replacement icons should use right as their unrotated orientation. */
|
|
16
129
|
icon?: SafeHtml;
|
|
130
|
+
/** Typed box size for the square visual. Default: `remify(18px)`. */
|
|
131
|
+
size?: CssLength;
|
|
17
132
|
className?: string;
|
|
133
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
134
|
+
slot?: string;
|
|
18
135
|
}
|
|
19
|
-
declare function DisclosureArrow({ open, openDirection, closedDirection, icon, className, }: DisclosureArrowProps): SafeHtml;
|
|
136
|
+
declare function DisclosureArrow({ open, openDirection, closedDirection, icon, size, className, slot, }: DisclosureArrowProps): SafeHtml;
|
|
20
137
|
|
|
21
138
|
export { DisclosureArrow, type DisclosureArrowProps, type DisclosureDirection };
|
|
22
139
|
```
|
|
@@ -24,19 +141,71 @@ export { DisclosureArrow, type DisclosureArrowProps, type DisclosureDirection };
|
|
|
24
141
|
## `@kerfjs/ui/toolbar`
|
|
25
142
|
|
|
26
143
|
```ts
|
|
27
|
-
import
|
|
144
|
+
import * as kerfjs from 'kerfjs';
|
|
145
|
+
import { PaneSeparatorSide } from './pane.js';
|
|
146
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
147
|
+
import { S as Sides } from './sides-BPSWde0A.js';
|
|
28
148
|
|
|
149
|
+
type ToolbarPosition = 'header' | 'footer';
|
|
29
150
|
interface ToolbarProps {
|
|
30
|
-
leading?:
|
|
31
|
-
center?:
|
|
32
|
-
trailing?:
|
|
151
|
+
leading?: KerfUiContent;
|
|
152
|
+
center?: KerfUiContent;
|
|
153
|
+
trailing?: KerfUiContent;
|
|
33
154
|
label?: string;
|
|
34
|
-
|
|
155
|
+
/** Use footer semantics for a bottom toolbar; defaults to header. */
|
|
156
|
+
position?: ToolbarPosition;
|
|
157
|
+
/**
|
|
158
|
+
* Physical divider edges in canonical top/right/bottom/left order, drawn
|
|
159
|
+
* always. Defaults to none: a toolbar pinned over or under scrolling content
|
|
160
|
+
* gets its divider from the scroll state instead — a `Pane` draws the line
|
|
161
|
+
* between its chrome and content while content is scrolled away beneath it,
|
|
162
|
+
* and `wireScrollDividers` `targets` can name a toolbar as chrome, which
|
|
163
|
+
* then draws its facing side the same way.
|
|
164
|
+
*/
|
|
165
|
+
dividerSides?: Sides;
|
|
166
|
+
/** `balanced` gives both side zones equal tracks, centering the middle zone on the toolbar even if only one side has controls. */
|
|
167
|
+
centerAlign?: 'center' | 'stretch' | 'balanced';
|
|
168
|
+
/**
|
|
169
|
+
* Component-owned responsive layout; applications choose the policy rather
|
|
170
|
+
* than restyling toolbar internals. Under every policy the trailing zone
|
|
171
|
+
* wraps its groups instead of clipping an action, and the center zone keeps
|
|
172
|
+
* its whole content width: when the zones do not fit one row, the leading
|
|
173
|
+
* title truncates with an ellipsis rather than the center overlapping it.
|
|
174
|
+
* - `none` keeps one row; the leading identity truncates first.
|
|
175
|
+
* - `stack` stacks the zones at `responsiveAt`, wrapping stacked control
|
|
176
|
+
* groups onto further rows.
|
|
177
|
+
* - `wrap` keeps one row while every zone fits at its natural width, and
|
|
178
|
+
* otherwise moves the trailing zone below a whole leading identity.
|
|
179
|
+
* - `center-priority` gives an expanded center control the full row.
|
|
180
|
+
* - `trailing-priority` moves an expanded trailing control to a full row
|
|
181
|
+
* below the leading identity at `responsiveAt`.
|
|
182
|
+
*/
|
|
183
|
+
responsive?: 'none' | 'stack' | 'wrap' | 'center-priority' | 'trailing-priority';
|
|
184
|
+
/** Container width at which `stack` or `trailing-priority` activates. */
|
|
185
|
+
responsiveAt?: 'compact' | 'narrow';
|
|
186
|
+
/**
|
|
187
|
+
* Screen edges this toolbar claims for device safe-area compensation, for an
|
|
188
|
+
* app bar or bottom bar that sits directly at a screen edge rather than in a
|
|
189
|
+
* Pane header or footer. Each listed side pads by the inset its surrounding
|
|
190
|
+
* layout reports through `--kui-edge-inset-*`, or the full device inset when
|
|
191
|
+
* nothing routes that edge, while the toolbar's box and dividers paint
|
|
192
|
+
* through. Omitted, the toolbar pads only the inline edges an owner such as
|
|
193
|
+
* a Pane header hands it, and never a block edge.
|
|
194
|
+
*/
|
|
195
|
+
safeAreaEdges?: readonly PaneSeparatorSide[];
|
|
35
196
|
className?: string;
|
|
197
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
198
|
+
slot?: string;
|
|
36
199
|
}
|
|
37
|
-
|
|
200
|
+
/**
|
|
201
|
+
* A toolbar's configuration, apart from its content: the props a composite
|
|
202
|
+
* that renders a `Toolbar` for the app (a Workbench or CollapsiblePanel
|
|
203
|
+
* toolbar) forwards, so the app configures that toolbar instead of styling it.
|
|
204
|
+
*/
|
|
205
|
+
type ToolbarConfig = Pick<ToolbarProps, 'dividerSides' | 'centerAlign' | 'responsive' | 'responsiveAt' | 'safeAreaEdges'>;
|
|
206
|
+
declare function Toolbar({ leading, center, trailing, label, position, dividerSides, centerAlign, responsive, responsiveAt, safeAreaEdges, className, slot, }: ToolbarProps): kerfjs.SafeHtml;
|
|
38
207
|
|
|
39
|
-
export { Toolbar, type ToolbarProps };
|
|
208
|
+
export { Sides, Toolbar, type ToolbarConfig, type ToolbarPosition, type ToolbarProps };
|
|
40
209
|
```
|
|
41
210
|
|
|
42
211
|
## `@kerfjs/ui/toolbar-text`
|
|
@@ -44,116 +213,512 @@ export { Toolbar, type ToolbarProps };
|
|
|
44
213
|
```ts
|
|
45
214
|
import * as kerfjs from 'kerfjs';
|
|
46
215
|
|
|
47
|
-
type ToolbarTextSize = 'xlarge' | 'large' | 'default' | 'small';
|
|
48
|
-
|
|
216
|
+
type ToolbarTextSize = 'xlarge' | 'xlarge-fixed' | 'large' | 'default' | 'small' | 'xsmall';
|
|
217
|
+
/** ARIA heading level for a title exposed as a heading landmark. */
|
|
218
|
+
type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
219
|
+
interface ToolbarTextBaseProps {
|
|
49
220
|
text: string;
|
|
50
221
|
size?: ToolbarTextSize;
|
|
51
222
|
className?: string;
|
|
52
223
|
/** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */
|
|
53
224
|
id?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Expose heading semantics (`role="heading"` + `aria-level`) so the text acts as
|
|
227
|
+
* a heading landmark — e.g. a page's primary title. Omit to keep the plain span
|
|
228
|
+
* (the default), which suits a dialog title referenced via `aria-labelledby`.
|
|
229
|
+
*/
|
|
230
|
+
headingLevel?: HeadingLevel;
|
|
54
231
|
/** Render the text as an unanimated loading skeleton instead of its value. */
|
|
55
232
|
placeholder?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Show a trailing ellipsis (…) where the text is truncated — on the single line
|
|
235
|
+
* (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip
|
|
236
|
+
* instead. Default true.
|
|
237
|
+
*/
|
|
238
|
+
ellipsis?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Grow to fill the free space of the flex row it sits in (a Toolbar zone),
|
|
241
|
+
* truncating at the space left by its siblings instead of taking only its
|
|
242
|
+
* text's width. Default false.
|
|
243
|
+
*/
|
|
244
|
+
fill?: boolean;
|
|
245
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
246
|
+
slot?: string;
|
|
56
247
|
}
|
|
57
|
-
|
|
248
|
+
type ToolbarTextWrappingProps = {
|
|
249
|
+
/** Wrap onto multiple lines; combine with `maxLines` to cap them. */
|
|
250
|
+
wrap: true;
|
|
251
|
+
maxLines?: number | null;
|
|
252
|
+
} | {
|
|
253
|
+
wrap?: false;
|
|
254
|
+
maxLines?: never;
|
|
255
|
+
};
|
|
256
|
+
type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;
|
|
257
|
+
declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, fill, slot, }: ToolbarTextProps): kerfjs.SafeHtml;
|
|
58
258
|
|
|
59
|
-
export { ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
259
|
+
export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
|
|
60
260
|
```
|
|
61
261
|
|
|
62
262
|
## `@kerfjs/ui/toolbar-control-group`
|
|
63
263
|
|
|
64
264
|
```ts
|
|
65
|
-
import
|
|
66
|
-
|
|
265
|
+
import * as kerfjs from 'kerfjs';
|
|
266
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
267
|
+
|
|
268
|
+
type ToolbarControlGroupAppearance = 'contained' | 'borderless';
|
|
269
|
+
type ToolbarControlGroupTone = 'default' | 'dark';
|
|
270
|
+
type ToolbarControlGroupButtonAppearance = 'plain' | 'push';
|
|
271
|
+
type ToolbarControlGroupShape = 'pill' | 'rounded';
|
|
272
|
+
type ToolbarControlGroupSize = 'default' | 'compact';
|
|
273
|
+
type ToolbarControlGroupDensity = 'comfortable' | 'tight';
|
|
274
|
+
type ToolbarControlGroupContent = 'icon' | 'text' | 'mixed' | 'avatar' | 'search';
|
|
275
|
+
type ToolbarControlGroupFocusRing = 'control' | 'outline' | 'halo';
|
|
276
|
+
type ToolbarControlGroupSelectedChrome = 'raised' | 'filled' | 'outline';
|
|
277
|
+
type ToolbarControlGroupSelectedTone = 'brand' | 'neutral' | 'pop';
|
|
278
|
+
type ToolbarControlGroupOverflow = 'visible' | 'scroll' | 'wrap';
|
|
279
|
+
type ToolbarControlGroupMenuInset = 'standard' | 'compact' | 'list-zero';
|
|
280
|
+
type ToolbarControlGroupVisibility = 'always' | 'compact-only' | 'hide-collapsed-tiny' | 'yield-to-expanded-sibling';
|
|
281
|
+
type ToolbarControlGroupSizing = 'content' | 'grow' | 'fill';
|
|
282
|
+
type ToolbarControlGroupPlacement = 'start' | 'end';
|
|
283
|
+
interface ToolbarActionLinkProps {
|
|
284
|
+
href: string;
|
|
285
|
+
label: string;
|
|
286
|
+
icon?: KerfUiContent;
|
|
287
|
+
/** Optional machine-readable detail hidden visually but included in the default accessible name. */
|
|
288
|
+
detail?: string;
|
|
289
|
+
/** Override the accessible name when surrounding context is needed. */
|
|
290
|
+
ariaLabel?: string;
|
|
291
|
+
/** Open in a new tab with a safe rel and announce that behavior. */
|
|
292
|
+
external?: boolean;
|
|
293
|
+
className?: string;
|
|
294
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
295
|
+
slot?: string;
|
|
296
|
+
}
|
|
297
|
+
/** A semantic anchor with ToolbarControlGroup-owned action geometry. */
|
|
298
|
+
declare function ToolbarActionLink({ href, label, icon, detail, ariaLabel, external, className, slot, }: ToolbarActionLinkProps): kerfjs.SafeHtml;
|
|
67
299
|
interface ToolbarControlGroupProps {
|
|
68
|
-
children:
|
|
300
|
+
children: KerfUiContent;
|
|
69
301
|
label?: string;
|
|
70
302
|
className?: string;
|
|
71
303
|
expanded?: boolean;
|
|
72
304
|
single?: boolean;
|
|
73
|
-
appearance?:
|
|
74
|
-
tone?:
|
|
75
|
-
buttonAppearance?:
|
|
305
|
+
appearance?: ToolbarControlGroupAppearance;
|
|
306
|
+
tone?: ToolbarControlGroupTone;
|
|
307
|
+
buttonAppearance?: ToolbarControlGroupButtonAppearance;
|
|
308
|
+
/** Corner shape: fully round `pill` (default) or a softer `rounded` rectangle. */
|
|
309
|
+
shape?: ToolbarControlGroupShape;
|
|
310
|
+
size?: ToolbarControlGroupSize;
|
|
311
|
+
density?: ToolbarControlGroupDensity;
|
|
312
|
+
content?: ToolbarControlGroupContent;
|
|
313
|
+
/** Whether controls paint focus individually or the group paints an outline/halo on focus-within. */
|
|
314
|
+
focusRing?: ToolbarControlGroupFocusRing;
|
|
315
|
+
selectedChrome?: ToolbarControlGroupSelectedChrome;
|
|
316
|
+
selectedTone?: ToolbarControlGroupSelectedTone;
|
|
317
|
+
/** Size a nested Web Awesome dropdown trigger as part of this group. */
|
|
318
|
+
nestedDropdown?: boolean;
|
|
319
|
+
/** Configure the nested dropdown menu inset without consumer ::part() CSS. */
|
|
320
|
+
menuInset?: ToolbarControlGroupMenuInset;
|
|
321
|
+
/** Keep an overlong row inside the available width by scrolling or wrapping. */
|
|
322
|
+
overflow?: ToolbarControlGroupOverflow;
|
|
323
|
+
/** Responsive visibility owned by the enclosing Toolbar container. */
|
|
324
|
+
visibility?: ToolbarControlGroupVisibility;
|
|
325
|
+
/** Intrinsic (default), grow from a basis, or occupy a full wrapping row. */
|
|
326
|
+
sizing?: ToolbarControlGroupSizing;
|
|
327
|
+
/** Place this group at the end of its flex row in a wrapping Toolbar zone. */
|
|
328
|
+
placement?: ToolbarControlGroupPlacement;
|
|
329
|
+
/** CSS length used as the minimum width and flex basis for `sizing="grow"`; defaults to 19rem. */
|
|
330
|
+
growBasis?: string;
|
|
331
|
+
/** Move this group into the work-area toolbar when its panel collapses. */
|
|
332
|
+
relocateOnCollapse?: boolean;
|
|
333
|
+
/** Add contrast behind photo-backed avatar content. */
|
|
334
|
+
scrim?: boolean;
|
|
335
|
+
/** Block the group's controls and show a spinner without changing its dimensions. */
|
|
336
|
+
busy?: boolean;
|
|
337
|
+
/** Announced status while busy; defaults to “Working”. */
|
|
338
|
+
busyLabel?: string;
|
|
339
|
+
/**
|
|
340
|
+
* Avatar image URL. A single-control group paints it on the group; a
|
|
341
|
+
* multi-control group paints it only on the pressed selection highlight.
|
|
342
|
+
*/
|
|
343
|
+
avatarImage?: string;
|
|
344
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
345
|
+
slot?: string;
|
|
76
346
|
}
|
|
77
|
-
declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance }: ToolbarControlGroupProps): SafeHtml;
|
|
347
|
+
declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, size, density, content, focusRing, selectedChrome, selectedTone, nestedDropdown, menuInset, overflow, visibility, sizing, placement, growBasis, relocateOnCollapse, scrim, busy, busyLabel, avatarImage, slot, }: ToolbarControlGroupProps): kerfjs.SafeHtml;
|
|
78
348
|
|
|
79
|
-
export { ToolbarControlGroup, type ToolbarControlGroupProps };
|
|
349
|
+
export { ToolbarActionLink, type ToolbarActionLinkProps, ToolbarControlGroup, type ToolbarControlGroupAppearance, type ToolbarControlGroupButtonAppearance, type ToolbarControlGroupContent, type ToolbarControlGroupDensity, type ToolbarControlGroupFocusRing, type ToolbarControlGroupMenuInset, type ToolbarControlGroupOverflow, type ToolbarControlGroupPlacement, type ToolbarControlGroupProps, type ToolbarControlGroupSelectedChrome, type ToolbarControlGroupSelectedTone, type ToolbarControlGroupShape, type ToolbarControlGroupSize, type ToolbarControlGroupSizing, type ToolbarControlGroupTone, type ToolbarControlGroupVisibility };
|
|
80
350
|
```
|
|
81
351
|
|
|
82
|
-
## `@kerfjs/ui/
|
|
352
|
+
## `@kerfjs/ui/floating-toolbar`
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
import * as kerfjs from 'kerfjs';
|
|
356
|
+
import { CssLength } from './css-values.js';
|
|
357
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
358
|
+
|
|
359
|
+
/** Where a {@link FloatingToolbar} floats within its positioned container. */
|
|
360
|
+
type FloatingToolbarPosition = 'bottom' | 'bottom-start' | 'bottom-end' | 'top' | 'top-start' | 'top-end';
|
|
361
|
+
interface FloatingToolbarProps {
|
|
362
|
+
/** Toolbar contents — normally one or more `ToolbarControlGroup`s. */
|
|
363
|
+
children: KerfUiContent;
|
|
364
|
+
/** Accessible name for the toolbar (required — it exposes `role="toolbar"`). */
|
|
365
|
+
label: string;
|
|
366
|
+
/**
|
|
367
|
+
* Corner or edge it floats to inside its nearest positioned ancestor.
|
|
368
|
+
* Default: `'bottom-end'`.
|
|
369
|
+
*/
|
|
370
|
+
position?: FloatingToolbarPosition;
|
|
371
|
+
/** Keep the toolbar in normal document flow instead of floating over content. */
|
|
372
|
+
placement?: 'floating' | 'inline';
|
|
373
|
+
/**
|
|
374
|
+
* Distance from the container edges named by `position`. Default:
|
|
375
|
+
* `space('m')` (16px, 8px past a top toolbar's own inset). Omit it inside a
|
|
376
|
+
* `Workbench`, `CollapsiblePanel`, or `ResizableRegion` restore corner: the
|
|
377
|
+
* corner owns the inset there and sets it to zero.
|
|
378
|
+
*/
|
|
379
|
+
inset?: CssLength;
|
|
380
|
+
/** Add device or layout-routed safe-area insets to the positioned edges. */
|
|
381
|
+
safeAreaInsets?: boolean;
|
|
382
|
+
className?: string;
|
|
383
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
384
|
+
slot?: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* A toolbar that floats above the main content of its nearest positioned
|
|
388
|
+
* ancestor — a transparent, forced-dark cluster of controls (e.g. a drawer
|
|
389
|
+
* restore button) that sits over the content but NOT over dialogs or overlays
|
|
390
|
+
* (it is not in the top layer). It is inset from the container edges by
|
|
391
|
+
* `inset` (default `--kui-space-m`, i.e. 8px more than a top toolbar's own
|
|
392
|
+
* inset); pass a typed length to move it. Inside a `Workbench`, `CollapsiblePanel`, or
|
|
393
|
+
* `ResizableRegion` restore corner the corner owns the inset, so the toolbar
|
|
394
|
+
* floats from the corner's own position. While one of those layouts has a
|
|
395
|
+
* side overlay open over the toolbar's region (a Workbench rail overlay, a
|
|
396
|
+
* `wireSidebar` compact overlay, an overlay `CollapsiblePanel` or horizontal
|
|
397
|
+
* `ResizableRegion`), the toolbar is hidden — unfocusable and out of the
|
|
398
|
+
* accessibility tree — until the overlay closes. The app owns the controls
|
|
399
|
+
* and their behavior — wire them with `delegate()` as usual. Set
|
|
400
|
+
* `placement="inline"` for normal flow when an owner already positions the
|
|
401
|
+
* control; floating placement can add safe-area insets to its per-edge tokens.
|
|
402
|
+
*/
|
|
403
|
+
declare function FloatingToolbar({ children, label, position, placement, inset, safeAreaInsets, className, slot, }: FloatingToolbarProps): kerfjs.SafeHtml;
|
|
404
|
+
|
|
405
|
+
export { FloatingToolbar, type FloatingToolbarPosition, type FloatingToolbarProps };
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## `@kerfjs/ui/popup-menu`
|
|
83
409
|
|
|
84
410
|
```ts
|
|
85
411
|
import { SafeHtml } from 'kerfjs';
|
|
412
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
86
413
|
|
|
87
|
-
type
|
|
414
|
+
type PopupMenuPlacement = 'bottom-start' | 'bottom' | 'bottom-end' | 'top-start' | 'top' | 'top-end';
|
|
415
|
+
type PopupMenuDataAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
416
|
+
'data-action'?: never;
|
|
417
|
+
'data-component'?: never;
|
|
418
|
+
'data-key'?: never;
|
|
419
|
+
'data-morph-skip-children'?: never;
|
|
420
|
+
}>;
|
|
421
|
+
/** One command in the menu. */
|
|
422
|
+
interface PopupMenuItem {
|
|
423
|
+
kind?: 'item';
|
|
424
|
+
label: string;
|
|
425
|
+
/** Delegated `data-action` the app handles when the item is chosen. */
|
|
426
|
+
action?: string;
|
|
427
|
+
/** Native `wa-dropdown-item` value, reported by its `wa-select` event. */
|
|
428
|
+
value?: string;
|
|
429
|
+
/** Leading icon, typically a `LucideIcon`; it is placed in the item's icon slot. */
|
|
430
|
+
icon?: SafeHtml;
|
|
431
|
+
/** A checkbox choice, including nested choices; omit for a plain command. */
|
|
432
|
+
checked?: boolean;
|
|
433
|
+
/** Trailing safe content, such as secondary status. */
|
|
434
|
+
details?: SafeHtml;
|
|
435
|
+
/** Destructive command styling. */
|
|
436
|
+
tone?: 'default' | 'danger';
|
|
437
|
+
disabled?: boolean;
|
|
438
|
+
/** Native tooltip text for a disabled command. */
|
|
439
|
+
disabledReason?: string;
|
|
440
|
+
/** Application `data-*` metadata such as a record id. */
|
|
441
|
+
attributes?: PopupMenuDataAttributes;
|
|
442
|
+
/** Child commands, headings, and dividers opened by hover or keyboard navigation. */
|
|
443
|
+
submenu?: readonly PopupMenuEntry[];
|
|
444
|
+
}
|
|
445
|
+
/** A labeled group heading; items that follow it belong to the group. */
|
|
446
|
+
interface PopupMenuHeading {
|
|
447
|
+
kind: 'heading';
|
|
448
|
+
label: string;
|
|
449
|
+
}
|
|
450
|
+
/** A separator between groups of items. */
|
|
451
|
+
interface PopupMenuDivider {
|
|
452
|
+
kind: 'divider';
|
|
453
|
+
}
|
|
454
|
+
type PopupMenuEntry = PopupMenuItem | PopupMenuHeading | PopupMenuDivider;
|
|
455
|
+
type PopupMenuTriggerName = {
|
|
456
|
+
/** Visible trigger text, which is also its accessible name. */
|
|
457
|
+
text: string;
|
|
458
|
+
label?: never;
|
|
459
|
+
} | {
|
|
460
|
+
text?: never;
|
|
461
|
+
/**
|
|
462
|
+
* Accessible name of an icon-only trigger, rendered as visually hidden
|
|
463
|
+
* slotted text (a Web Awesome button takes its name from its content).
|
|
464
|
+
*/
|
|
465
|
+
label: string;
|
|
466
|
+
};
|
|
467
|
+
type PopupMenuTrigger = (PopupMenuTriggerName & {
|
|
468
|
+
context?: false;
|
|
469
|
+
}) | {
|
|
470
|
+
context: true;
|
|
471
|
+
label: string;
|
|
472
|
+
text?: never;
|
|
473
|
+
icon?: never;
|
|
474
|
+
caret?: never;
|
|
475
|
+
disabled?: never;
|
|
476
|
+
};
|
|
477
|
+
type PopupMenuProps = PopupMenuTrigger & {
|
|
478
|
+
/** Trigger icon, typically a `LucideIcon`, before any visible text. */
|
|
479
|
+
icon?: KerfUiContent;
|
|
480
|
+
items: readonly PopupMenuEntry[];
|
|
481
|
+
/** Where the menu opens relative to its trigger. Defaults to `bottom-start`. */
|
|
482
|
+
placement?: PopupMenuPlacement;
|
|
483
|
+
/** Show the disclosure caret after the trigger content. Defaults to true. */
|
|
484
|
+
caret?: boolean;
|
|
485
|
+
disabled?: boolean;
|
|
486
|
+
/** Application `data-*` metadata on the menu root. */
|
|
487
|
+
rootAttributes?: PopupMenuDataAttributes;
|
|
488
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
489
|
+
slot?: string;
|
|
490
|
+
};
|
|
491
|
+
/** A rendered context PopupMenu with Web Awesome's controlled open state. */
|
|
492
|
+
type PopupMenuElement = HTMLElement & {
|
|
493
|
+
open: boolean;
|
|
494
|
+
};
|
|
495
|
+
/** Open a context PopupMenu at viewport pointer coordinates. */
|
|
496
|
+
declare function openPopupMenuAt(menu: PopupMenuElement, x: number, y: number): void;
|
|
497
|
+
/** Close a programmatically opened PopupMenu. */
|
|
498
|
+
declare function closePopupMenu(menu: PopupMenuElement): void;
|
|
499
|
+
/**
|
|
500
|
+
* An action menu: a trigger button that opens a list of commands. Renders the
|
|
501
|
+
* `wa-dropdown` root directly, so a `single` `ToolbarControlGroup` (with
|
|
502
|
+
* `nestedDropdown`) or a `PopupSurface` sizes and insets it as usual. Items
|
|
503
|
+
* dispatch through delegated `data-action`s; the app owns the commands and any
|
|
504
|
+
* open-state reaction. Import `@kerfjs/ui/popup-menu/register` once to register
|
|
505
|
+
* the Web Awesome elements. At viewport widths up to 480px, submenus appear
|
|
506
|
+
* above or below their parent menu so their rows do not cover the parent list.
|
|
507
|
+
*/
|
|
508
|
+
declare function PopupMenu({ text, label, icon, items, placement, caret, disabled, rootAttributes, slot, context, }: PopupMenuProps): SafeHtml;
|
|
509
|
+
|
|
510
|
+
export { PopupMenu, type PopupMenuDivider, type PopupMenuElement, type PopupMenuEntry, type PopupMenuHeading, type PopupMenuItem, type PopupMenuPlacement, type PopupMenuProps, closePopupMenu, openPopupMenuAt };
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
## `@kerfjs/ui/list-header`
|
|
514
|
+
|
|
515
|
+
```ts
|
|
516
|
+
import { SafeHtml } from 'kerfjs';
|
|
517
|
+
import { HeadingLevel } from './toolbar-text.js';
|
|
518
|
+
|
|
519
|
+
type ListHeaderRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
88
520
|
'data-component'?: never;
|
|
89
521
|
'data-action'?: never;
|
|
90
522
|
'data-has-badge'?: never;
|
|
91
523
|
'data-has-count'?: never;
|
|
524
|
+
'data-density'?: never;
|
|
525
|
+
'data-divider'?: never;
|
|
526
|
+
'data-inline'?: never;
|
|
527
|
+
'data-width'?: never;
|
|
528
|
+
'data-indicator-tone'?: never;
|
|
92
529
|
'data-toggle'?: never;
|
|
93
530
|
}>;
|
|
94
|
-
type
|
|
531
|
+
type ListHeaderTriggerAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
95
532
|
'data-action'?: never;
|
|
533
|
+
'data-kui-disabled'?: never;
|
|
96
534
|
popoverTarget?: string;
|
|
97
535
|
popoverTargetAction?: 'toggle' | 'show' | 'hide';
|
|
98
536
|
'aria-controls'?: string;
|
|
99
537
|
'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';
|
|
100
538
|
}>;
|
|
101
|
-
interface
|
|
539
|
+
interface ListHeaderBaseProps {
|
|
102
540
|
label: string;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
541
|
+
density?: 'standard' | 'compact';
|
|
542
|
+
divider?: 'none' | 'before' | 'after' | 'both';
|
|
543
|
+
/** Shrink-wrap the header without its default outer margin, border, or padding. */
|
|
544
|
+
inline?: boolean;
|
|
545
|
+
/** Fill the available row or shrink-wrap while retaining normal header geometry. */
|
|
546
|
+
width?: 'fill' | 'content';
|
|
547
|
+
indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';
|
|
110
548
|
/** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */
|
|
111
549
|
placeholder?: boolean;
|
|
112
|
-
rootAttributes?:
|
|
113
|
-
triggerAttributes?:
|
|
550
|
+
rootAttributes?: ListHeaderRootAttributes;
|
|
551
|
+
triggerAttributes?: ListHeaderTriggerAttributes;
|
|
552
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
553
|
+
slot?: string;
|
|
114
554
|
}
|
|
115
|
-
type
|
|
555
|
+
type ListHeaderModeProps = {
|
|
556
|
+
/** Render the title as a controlled disclosure trigger. */
|
|
557
|
+
toggle: true;
|
|
558
|
+
/** A toggle's label is its button text, not a heading. */
|
|
559
|
+
headingLevel?: never;
|
|
560
|
+
action: string;
|
|
561
|
+
expanded: boolean;
|
|
562
|
+
actionIcon?: SafeHtml;
|
|
563
|
+
actionLabel?: never;
|
|
564
|
+
actionDisabled?: boolean;
|
|
565
|
+
disabledReason?: string;
|
|
566
|
+
} | {
|
|
567
|
+
/** Render a separately named trailing action. */
|
|
568
|
+
toggle?: false;
|
|
569
|
+
/**
|
|
570
|
+
* Native heading level (`h1`–`h6`) of the label. Default `2`. Match the
|
|
571
|
+
* document outline; the visual treatment does not change.
|
|
572
|
+
*/
|
|
573
|
+
headingLevel?: HeadingLevel;
|
|
574
|
+
action: string;
|
|
575
|
+
actionLabel: string;
|
|
576
|
+
actionIcon: SafeHtml;
|
|
577
|
+
expanded?: never;
|
|
578
|
+
actionDisabled?: boolean;
|
|
579
|
+
disabledReason?: string;
|
|
580
|
+
} | {
|
|
581
|
+
/** Render a passive section heading. */
|
|
582
|
+
toggle?: false;
|
|
583
|
+
/**
|
|
584
|
+
* Native heading level (`h1`–`h6`) of the label. Default `2`. Match the
|
|
585
|
+
* document outline; the visual treatment does not change.
|
|
586
|
+
*/
|
|
587
|
+
headingLevel?: HeadingLevel;
|
|
588
|
+
action?: never;
|
|
589
|
+
actionLabel?: never;
|
|
590
|
+
actionIcon?: never;
|
|
591
|
+
expanded?: never;
|
|
592
|
+
actionDisabled?: never;
|
|
593
|
+
disabledReason?: never;
|
|
594
|
+
};
|
|
595
|
+
type ListHeaderIndicatorProps = {
|
|
116
596
|
count: number;
|
|
117
597
|
countLabel: string;
|
|
118
598
|
badge?: never;
|
|
599
|
+
status?: never;
|
|
600
|
+
} | {
|
|
601
|
+
count?: never;
|
|
602
|
+
countLabel?: never;
|
|
603
|
+
badge: SafeHtml;
|
|
604
|
+
status?: never;
|
|
119
605
|
} | {
|
|
120
606
|
count?: never;
|
|
121
607
|
countLabel?: never;
|
|
122
|
-
badge?:
|
|
608
|
+
badge?: never;
|
|
609
|
+
status?: SafeHtml;
|
|
123
610
|
};
|
|
124
|
-
type
|
|
125
|
-
declare function
|
|
611
|
+
type ListHeaderProps = ListHeaderBaseProps & ListHeaderIndicatorProps & ListHeaderModeProps;
|
|
612
|
+
declare function ListHeader({ label, headingLevel, count, countLabel, badge, status, density, divider, inline, width, indicatorTone, action, actionLabel, actionIcon, actionDisabled, disabledReason, expanded, toggle, placeholder, rootAttributes, triggerAttributes, slot, }: ListHeaderProps): SafeHtml;
|
|
126
613
|
|
|
127
|
-
export {
|
|
614
|
+
export { ListHeader, type ListHeaderProps };
|
|
128
615
|
```
|
|
129
616
|
|
|
130
|
-
## `@kerfjs/ui/
|
|
617
|
+
## `@kerfjs/ui/list`
|
|
618
|
+
|
|
619
|
+
```ts
|
|
620
|
+
import * as kerfjs from 'kerfjs';
|
|
621
|
+
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
622
|
+
import { H as HorizontalAlignment, L as ListVerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
|
|
623
|
+
export { V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
|
|
624
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
625
|
+
import { S as Sides } from './sides-BPSWde0A.js';
|
|
626
|
+
|
|
627
|
+
type ListRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
628
|
+
'data-component'?: never;
|
|
629
|
+
'data-gap'?: never;
|
|
630
|
+
'data-flex'?: never;
|
|
631
|
+
'data-fill'?: never;
|
|
632
|
+
'data-h-align'?: never;
|
|
633
|
+
'data-v-align'?: never;
|
|
634
|
+
'data-scrollable'?: never;
|
|
635
|
+
'data-text-insets'?: never;
|
|
636
|
+
'data-control-insets'?: never;
|
|
637
|
+
}>;
|
|
638
|
+
interface ListProps {
|
|
639
|
+
children?: KerfUiContent;
|
|
640
|
+
/** Make this list a labeled multi-select grid for `ContentItem selectionMode="multiple"` rows. */
|
|
641
|
+
selectionMode?: 'multiple';
|
|
642
|
+
/** Accessible name for the multi-select grid. */
|
|
643
|
+
ariaLabel?: string;
|
|
644
|
+
/** Use the standard item gap, a named UI spacing token, or a typed CSS length. Defaults to no gap. */
|
|
645
|
+
gap?: boolean | UiSpaceName | CssLength;
|
|
646
|
+
/** Allow this list to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
647
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
648
|
+
/**
|
|
649
|
+
* Fill the height of a parent with a definite height, such as an app root or
|
|
650
|
+
* a fixed-height frame, when this list is that parent's layout root. Inside a
|
|
651
|
+
* flex layout use `flex` instead. Defaults to false.
|
|
652
|
+
*/
|
|
653
|
+
fill?: boolean;
|
|
654
|
+
/** Horizontal alignment. Defaults to full to preserve stretch-aligned list children. */
|
|
655
|
+
hAlign?: HorizontalAlignment;
|
|
656
|
+
/** Vertical distribution. Defaults to top. */
|
|
657
|
+
vAlign?: ListVerticalAlignment;
|
|
658
|
+
/** Own vertical scrolling and overscroll containment. */
|
|
659
|
+
scrollable?: boolean;
|
|
660
|
+
/** Physical divider edges in canonical top/right/bottom/left order. */
|
|
661
|
+
dividerSides?: Sides;
|
|
662
|
+
/** Physical sides that receive the standard 17px text inset. */
|
|
663
|
+
textInsets?: Sides;
|
|
664
|
+
/** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
|
|
665
|
+
controlInsets?: Sides;
|
|
666
|
+
className?: string;
|
|
667
|
+
/** Safe `data-*` metadata; List-owned structural attributes remain protected. */
|
|
668
|
+
rootAttributes?: ListRootAttributes;
|
|
669
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
670
|
+
slot?: string;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* A list's configuration, apart from its content and styling hooks: the props a
|
|
674
|
+
* composite that renders a `List` for the app (the Workbench's `mainHeader` /
|
|
675
|
+
* `mainFooter` chrome) forwards, so the app configures that list instead of
|
|
676
|
+
* styling it. An omitted or `undefined` field keeps the composite's default.
|
|
677
|
+
*/
|
|
678
|
+
type ListConfig = Pick<ListProps, 'gap' | 'hAlign' | 'vAlign' | 'dividerSides' | 'textInsets' | 'controlInsets'>;
|
|
679
|
+
/** A stretch-aligned vertical stack with optional gap, flex, fill, scroll, and dividers. */
|
|
680
|
+
declare function List({ children, selectionMode, ariaLabel, gap, flex, fill, hAlign, vAlign, scrollable, dividerSides, textInsets, controlInsets, className, rootAttributes, slot, }: ListProps): kerfjs.SafeHtml;
|
|
681
|
+
|
|
682
|
+
export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, List, type ListConfig, type ListProps, ListVerticalAlignment, Sides, UiSpaceName };
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
## `@kerfjs/ui/list-action-row`
|
|
131
686
|
|
|
132
687
|
```ts
|
|
133
688
|
import { SafeHtml } from 'kerfjs';
|
|
134
689
|
|
|
135
|
-
type
|
|
690
|
+
type ListActionRowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
136
691
|
'data-component'?: never;
|
|
137
692
|
'data-action'?: never;
|
|
138
693
|
'data-item-id'?: never;
|
|
139
694
|
'data-has-icon'?: never;
|
|
140
695
|
'data-multiline'?: never;
|
|
696
|
+
'data-density'?: never;
|
|
697
|
+
'data-divider'?: never;
|
|
698
|
+
'data-busy'?: never;
|
|
699
|
+
'data-trailing-visibility'?: never;
|
|
141
700
|
'data-state'?: never;
|
|
142
701
|
'data-selected'?: never;
|
|
143
702
|
'data-pressed'?: never;
|
|
144
703
|
}>;
|
|
145
|
-
type
|
|
704
|
+
type ListActionRowTrailingAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
146
705
|
'data-component'?: never;
|
|
147
706
|
'data-action'?: never;
|
|
148
707
|
'data-item-id'?: never;
|
|
708
|
+
'data-kui-disabled'?: never;
|
|
149
709
|
popoverTarget?: string;
|
|
150
710
|
popoverTargetAction?: 'toggle' | 'show' | 'hide';
|
|
151
711
|
'aria-controls'?: string;
|
|
152
712
|
'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';
|
|
153
713
|
}>;
|
|
154
|
-
interface
|
|
714
|
+
interface ListActionRowProps {
|
|
155
715
|
/** Visible dormant content for the primary button. Must not contain interactive descendants. */
|
|
156
716
|
label: string | SafeHtml;
|
|
717
|
+
description?: string | SafeHtml;
|
|
718
|
+
status?: string | SafeHtml;
|
|
719
|
+
busy?: boolean;
|
|
720
|
+
density?: 'standard' | 'compact';
|
|
721
|
+
divider?: 'none' | 'before' | 'after' | 'both';
|
|
157
722
|
/** Decorative dormant content for the primary button. Must not contain interactive descendants. */
|
|
158
723
|
icon?: SafeHtml;
|
|
159
724
|
action: string;
|
|
@@ -166,7 +731,7 @@ interface MenuActionRowProps {
|
|
|
166
731
|
state?: string;
|
|
167
732
|
disabled?: boolean;
|
|
168
733
|
tabIndex?: number;
|
|
169
|
-
/** Render as an unanimated loading skeleton, disabling both actions. */
|
|
734
|
+
/** Render as an unanimated loading skeleton, disabling both actions: label, description, icon, and status text become skeletons; the `busy` indicator stays live. */
|
|
170
735
|
placeholder?: boolean;
|
|
171
736
|
trailingAction: string;
|
|
172
737
|
trailingActionLabel: string;
|
|
@@ -174,91 +739,239 @@ interface MenuActionRowProps {
|
|
|
174
739
|
trailingActionIcon: SafeHtml;
|
|
175
740
|
trailingActionDisabled?: boolean;
|
|
176
741
|
trailingActionTitle?: string;
|
|
742
|
+
trailingActionVisibility?: 'always' | 'interaction';
|
|
177
743
|
className?: string;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
744
|
+
rootAttributes?: ListActionRowRootAttributes;
|
|
745
|
+
trailingActionAttributes?: ListActionRowTrailingAttributes;
|
|
746
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
747
|
+
slot?: string;
|
|
181
748
|
}
|
|
182
|
-
declare function
|
|
749
|
+
declare function ListActionRow({ label, description, status, busy, density, divider, icon, action, itemId, selected, pressed, accessibleLabel, title, multiline, state, disabled, tabIndex, placeholder, trailingAction, trailingActionLabel, trailingActionIcon, trailingActionDisabled, trailingActionTitle, trailingActionVisibility, className, rootAttributes, trailingActionAttributes, slot, }: ListActionRowProps): SafeHtml;
|
|
183
750
|
|
|
184
|
-
export {
|
|
751
|
+
export { ListActionRow, type ListActionRowProps };
|
|
185
752
|
```
|
|
186
753
|
|
|
187
|
-
## `@kerfjs/ui/
|
|
754
|
+
## `@kerfjs/ui/list-item`
|
|
188
755
|
|
|
189
756
|
```ts
|
|
190
757
|
import { SafeHtml } from 'kerfjs';
|
|
758
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
191
759
|
|
|
192
|
-
type
|
|
760
|
+
type ListItemRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
193
761
|
'data-component'?: never;
|
|
194
762
|
'data-action'?: never;
|
|
195
763
|
'data-item-id'?: never;
|
|
196
764
|
'data-has-icon'?: never;
|
|
765
|
+
'data-has-description'?: never;
|
|
197
766
|
'data-multiline'?: never;
|
|
767
|
+
'data-density'?: never;
|
|
768
|
+
'data-divider'?: never;
|
|
769
|
+
'data-busy'?: never;
|
|
198
770
|
'data-state'?: never;
|
|
771
|
+
'data-kui-disabled'?: never;
|
|
772
|
+
'data-icon-align'?: never;
|
|
199
773
|
}>;
|
|
200
|
-
interface
|
|
774
|
+
interface ListItemProps {
|
|
201
775
|
label: string | SafeHtml;
|
|
776
|
+
/** App-owned supporting text rendered in the component's stable label stack. */
|
|
777
|
+
description?: string | SafeHtml;
|
|
202
778
|
icon?: SafeHtml;
|
|
203
|
-
|
|
779
|
+
/** Dormant author content at the row's end; a placeholder renders it as a skeleton. */
|
|
780
|
+
trailing?: KerfUiContent;
|
|
781
|
+
/** Dormant status metadata rendered before trailing content; a placeholder renders it as a skeleton. */
|
|
782
|
+
status?: string | SafeHtml;
|
|
783
|
+
/** Show a progress indicator and expose the row as busy without replacing its content; a placeholder keeps the indicator. */
|
|
784
|
+
busy?: boolean;
|
|
785
|
+
density?: 'standard' | 'compact' | 'spacious';
|
|
786
|
+
divider?: 'none' | 'before' | 'after' | 'both';
|
|
204
787
|
selected?: boolean;
|
|
205
788
|
action: string;
|
|
206
789
|
itemId?: string;
|
|
207
790
|
className?: string;
|
|
208
|
-
style?: string;
|
|
209
791
|
pressed?: boolean;
|
|
210
792
|
accessibleLabel?: string;
|
|
211
793
|
title?: string;
|
|
212
794
|
multiline?: boolean;
|
|
795
|
+
/** Alignment of an icon beside a wrapped label. Defaults to its first line. */
|
|
796
|
+
multilineIconAlign?: 'first-line' | 'center';
|
|
213
797
|
state?: string;
|
|
214
798
|
disabled?: boolean;
|
|
215
799
|
tabIndex?: number;
|
|
216
|
-
/** Render the row as an unanimated loading skeleton, disabling its action. */
|
|
800
|
+
/** Render the row as an unanimated loading skeleton, disabling its action: label, description, icon, status, and trailing content become skeletons; the `busy` indicator stays live. */
|
|
217
801
|
placeholder?: boolean;
|
|
218
|
-
rootAttributes?:
|
|
802
|
+
rootAttributes?: ListItemRootAttributes;
|
|
803
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
804
|
+
slot?: string;
|
|
805
|
+
}
|
|
806
|
+
interface ListItemLinkProps extends Omit<ListItemProps, 'action' | 'pressed'> {
|
|
807
|
+
/** Native destination for this navigation row. */
|
|
808
|
+
href: string;
|
|
809
|
+
/** Open in a new tab with a safe rel and announce that behavior. */
|
|
810
|
+
external?: boolean;
|
|
811
|
+
action?: never;
|
|
812
|
+
pressed?: never;
|
|
219
813
|
}
|
|
220
|
-
declare function
|
|
814
|
+
declare function ListItem({ label, description, icon, trailing, status, busy, density, divider, selected, action, itemId, className, pressed, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, rootAttributes, slot, }: ListItemProps): SafeHtml;
|
|
815
|
+
/** A navigation row with native link activation and ListItem geometry. */
|
|
816
|
+
declare function ListItemLink({ href, external, label, description, icon, trailing, status, busy, density, divider, selected, itemId, className, accessibleLabel, title, multiline, multilineIconAlign, state, disabled, tabIndex, placeholder, rootAttributes, slot, }: ListItemLinkProps): SafeHtml;
|
|
221
817
|
|
|
222
|
-
export {
|
|
818
|
+
export { ListItem, ListItemLink, type ListItemLinkProps, type ListItemProps };
|
|
223
819
|
```
|
|
224
820
|
|
|
225
|
-
## `@kerfjs/ui/
|
|
821
|
+
## `@kerfjs/ui/list-inset-control`
|
|
226
822
|
|
|
227
823
|
```ts
|
|
228
|
-
import
|
|
824
|
+
import * as kerfjs from 'kerfjs';
|
|
825
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
826
|
+
import { S as Sides } from './sides-BPSWde0A.js';
|
|
827
|
+
|
|
828
|
+
interface ListInsetControlProps {
|
|
829
|
+
/** Control(s) that own their own border and padding (e.g. an input, a `wa-*`). */
|
|
830
|
+
children: KerfUiContent;
|
|
831
|
+
/** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */
|
|
832
|
+
sides?: Sides;
|
|
833
|
+
className?: string;
|
|
834
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
835
|
+
slot?: string;
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Insets a control into a pane/list content region: an 8px inline margin (so its
|
|
839
|
+
* edges line up with `.kui-content` items) and a stretch flex row with an 8px gap.
|
|
840
|
+
* Use it for controls that carry their own border and padding but no outer margin
|
|
841
|
+
* — the wrapper adds only the alignment margin and layout, not a second inset.
|
|
842
|
+
*/
|
|
843
|
+
declare function ListInsetControl({ children, sides, className, slot, }: ListInsetControlProps): kerfjs.SafeHtml;
|
|
229
844
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
845
|
+
export { ListInsetControl, type ListInsetControlProps, Sides };
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
## `@kerfjs/ui/list-inset-text`
|
|
849
|
+
|
|
850
|
+
```ts
|
|
851
|
+
import * as kerfjs from 'kerfjs';
|
|
852
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
853
|
+
import { S as Sides } from './sides-BPSWde0A.js';
|
|
854
|
+
|
|
855
|
+
type ListInsetTextRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
856
|
+
'data-component'?: never;
|
|
857
|
+
'data-sides'?: never;
|
|
858
|
+
}>;
|
|
859
|
+
interface ListInsetTextProps {
|
|
860
|
+
/** Text (or inline content) that carries no margin, border, or padding of its own. */
|
|
861
|
+
children: KerfUiContent | string;
|
|
862
|
+
/** Physical inset sides in canonical top/right/bottom/left order. Defaults to all sides. */
|
|
863
|
+
sides?: Sides;
|
|
864
|
+
className?: string;
|
|
865
|
+
/** Safe `data-*` metadata; component-owned structural attributes stay protected. */
|
|
866
|
+
rootAttributes?: ListInsetTextRootAttributes;
|
|
867
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
868
|
+
slot?: string;
|
|
240
869
|
}
|
|
241
870
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
871
|
+
* Gives bare text the content-item geometry — an 8px inline margin, a 1px
|
|
872
|
+
* transparent border, and 8px padding — so a plain string lines up with
|
|
873
|
+
* bordered `.kui-content` items (its text edge lands at the same 17px inset).
|
|
874
|
+
* Use it for text elements that have no margin, border, or padding of their own.
|
|
875
|
+
* Pass `sides="rl"` to keep the horizontal inset but drop the vertical box
|
|
876
|
+
* space for tight text layout.
|
|
877
|
+
*/
|
|
878
|
+
declare function ListInsetText({ children, sides, className, rootAttributes, slot, }: ListInsetTextProps): kerfjs.SafeHtml;
|
|
879
|
+
|
|
880
|
+
export { ListInsetText, type ListInsetTextProps, Sides };
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
## `@kerfjs/ui/content-item`
|
|
884
|
+
|
|
885
|
+
```ts
|
|
886
|
+
import * as kerfjs from 'kerfjs';
|
|
887
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
888
|
+
|
|
889
|
+
/** Whether the item's always-reserved 1px border is transparent or visible. */
|
|
890
|
+
type ContentItemFrame = 'none' | 'framed';
|
|
891
|
+
/** Corner shape: the 12px rounded rectangle or the 22px pill. */
|
|
892
|
+
type ContentItemShape = 'rounded' | 'pill';
|
|
893
|
+
/** `single` uses an option; `multiple` uses a grid row; `toggle` uses a pressed button. */
|
|
894
|
+
type ContentItemSelectionMode = 'none' | 'single' | 'multiple' | 'toggle';
|
|
895
|
+
type ContentItemRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
896
|
+
'data-component'?: never;
|
|
897
|
+
}>;
|
|
898
|
+
type ContentItemInteractiveRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
899
|
+
'data-component'?: never;
|
|
900
|
+
'data-action'?: never;
|
|
901
|
+
'data-item-id'?: never;
|
|
902
|
+
'data-interactive'?: never;
|
|
903
|
+
'data-selected'?: never;
|
|
904
|
+
'data-disabled'?: never;
|
|
905
|
+
'data-selection-mode'?: never;
|
|
906
|
+
'data-kui-pressed'?: never;
|
|
907
|
+
}>;
|
|
908
|
+
interface ContentItemBaseProps {
|
|
909
|
+
/** Item content; a plain string is allowed for bare copy. */
|
|
910
|
+
children?: KerfUiContent | string;
|
|
911
|
+
/**
|
|
912
|
+
* `framed` paints the standard neutral border in the 1px the item always
|
|
913
|
+
* reserves, so framing never changes geometry. Frame only an item that
|
|
914
|
+
* marks a real distinction. Defaults to `none` (transparent border).
|
|
915
|
+
*/
|
|
916
|
+
frame?: ContentItemFrame;
|
|
917
|
+
/** Remove block padding and block borders while retaining inline geometry. */
|
|
918
|
+
flush?: boolean;
|
|
919
|
+
/** Corner shape. Defaults to `rounded`. */
|
|
920
|
+
shape?: ContentItemShape;
|
|
921
|
+
/** Native hover tooltip. */
|
|
922
|
+
title?: string;
|
|
923
|
+
/**
|
|
924
|
+
* Names the item as a distinct region (`role="region"`). Omit it for an
|
|
925
|
+
* ordinary item, which stays a non-landmark grouping.
|
|
926
|
+
*/
|
|
927
|
+
ariaLabel?: string;
|
|
928
|
+
/**
|
|
929
|
+
* Makes the item a programmatic focus target (`tabindex="-1"`, never a tab
|
|
930
|
+
* stop), for example the preferred initial focus of a NavStack view when
|
|
931
|
+
* combined with `data-nav-focus` in `rootAttributes`.
|
|
932
|
+
*/
|
|
933
|
+
focusTarget?: boolean;
|
|
934
|
+
className?: string;
|
|
935
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
936
|
+
slot?: string;
|
|
937
|
+
}
|
|
938
|
+
type ContentItemProps = ContentItemBaseProps & ({
|
|
939
|
+
interactive?: false;
|
|
940
|
+
action?: never;
|
|
941
|
+
itemId?: never;
|
|
942
|
+
selectionMode?: never;
|
|
943
|
+
selected?: never;
|
|
944
|
+
disabled?: never;
|
|
945
|
+
/** Existing static `data-*` metadata remains available. */
|
|
946
|
+
rootAttributes?: ContentItemRootAttributes;
|
|
947
|
+
} | {
|
|
948
|
+
/** Enable a keyboard reachable card; wire `wireContentItems` once on its containing root. */
|
|
949
|
+
interactive: true;
|
|
950
|
+
/** Delegated action dispatched by pointer, Enter, or Space. */
|
|
951
|
+
action: string;
|
|
952
|
+
itemId?: string;
|
|
953
|
+
selectionMode?: ContentItemSelectionMode;
|
|
954
|
+
selected?: boolean;
|
|
955
|
+
disabled?: boolean;
|
|
956
|
+
/** Safe app metadata; interaction attributes are component-owned. */
|
|
957
|
+
rootAttributes?: ContentItemInteractiveRootAttributes;
|
|
958
|
+
});
|
|
959
|
+
/**
|
|
960
|
+
* One self-contained `.kui-content` child: an 8px inline margin, a real 1px
|
|
961
|
+
* border (transparent unless `framed`), 8px padding, and a rounded or pill
|
|
962
|
+
* radius. It owns that whole geometry, so wrappers must not add more.
|
|
252
963
|
*/
|
|
253
|
-
declare function
|
|
964
|
+
declare function ContentItem({ children, frame, flush, shape, title, ariaLabel, focusTarget, interactive, action, itemId, selectionMode, selected, disabled, className, rootAttributes, slot, }: ContentItemProps): kerfjs.SafeHtml;
|
|
254
965
|
|
|
255
|
-
export {
|
|
966
|
+
export { ContentItem, type ContentItemFrame, type ContentItemProps, type ContentItemSelectionMode, type ContentItemShape };
|
|
256
967
|
```
|
|
257
968
|
|
|
258
969
|
## `@kerfjs/ui/value-table`
|
|
259
970
|
|
|
260
971
|
```ts
|
|
972
|
+
import * as kerfjs from 'kerfjs';
|
|
261
973
|
import { SafeHtml } from 'kerfjs';
|
|
974
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
262
975
|
|
|
263
976
|
interface ValueTableRowProps {
|
|
264
977
|
label: string | SafeHtml;
|
|
@@ -267,15 +980,21 @@ interface ValueTableRowProps {
|
|
|
267
980
|
className?: string;
|
|
268
981
|
/** Render the value as an unanimated loading skeleton, keeping the field label. */
|
|
269
982
|
placeholder?: boolean;
|
|
983
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
984
|
+
slot?: string;
|
|
270
985
|
}
|
|
271
|
-
declare function ValueTableRow({ label, value, icon, className, placeholder }: ValueTableRowProps): SafeHtml;
|
|
986
|
+
declare function ValueTableRow({ label, value, icon, className, placeholder, slot, }: ValueTableRowProps): SafeHtml;
|
|
272
987
|
|
|
273
988
|
interface ValueTableProps {
|
|
274
989
|
label: string;
|
|
990
|
+
/** Compact row spacing for metadata-dense surfaces. */
|
|
991
|
+
density?: 'default' | 'compact';
|
|
275
992
|
className?: string;
|
|
276
|
-
children:
|
|
993
|
+
children: KerfUiContent;
|
|
994
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
995
|
+
slot?: string;
|
|
277
996
|
}
|
|
278
|
-
declare function ValueTable({ label, className, children }: ValueTableProps): SafeHtml;
|
|
997
|
+
declare function ValueTable({ label, density, className, children, slot, }: ValueTableProps): kerfjs.SafeHtml;
|
|
279
998
|
|
|
280
999
|
export { ValueTable, type ValueTableProps, ValueTableRow, type ValueTableRowProps };
|
|
281
1000
|
```
|
|
@@ -284,6 +1003,7 @@ export { ValueTable, type ValueTableProps, ValueTableRow, type ValueTableRowProp
|
|
|
284
1003
|
|
|
285
1004
|
```ts
|
|
286
1005
|
import { SafeHtml } from 'kerfjs';
|
|
1006
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
287
1007
|
|
|
288
1008
|
type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
289
1009
|
'data-component'?: never;
|
|
@@ -292,15 +1012,36 @@ type AppTabRootAttributes = Readonly<Record<`data-${string}`, string | undefined
|
|
|
292
1012
|
'data-selected'?: never;
|
|
293
1013
|
'data-tab-dragging'?: never;
|
|
294
1014
|
'data-tab-drop-position'?: never;
|
|
1015
|
+
'data-attention'?: never;
|
|
1016
|
+
'data-drop-target'?: never;
|
|
1017
|
+
'data-name-overflow'?: never;
|
|
1018
|
+
'data-pinned'?: never;
|
|
295
1019
|
}>;
|
|
1020
|
+
type AppTabPresentation = 'pill' | 'segmented' | 'icon-only';
|
|
1021
|
+
type AppTabSize = 'default' | 'compact';
|
|
1022
|
+
type AppTabNameOverflow = 'ellipsis' | 'visible';
|
|
296
1023
|
interface AppTabProps {
|
|
297
1024
|
id: string;
|
|
298
1025
|
name: string;
|
|
299
1026
|
selected?: boolean;
|
|
1027
|
+
/** Emphasize the visible tab name with the attention color token. */
|
|
1028
|
+
attention?: boolean;
|
|
1029
|
+
/** Highlight this tab as the target of a drag over its content. */
|
|
1030
|
+
dropTarget?: boolean;
|
|
1031
|
+
/** Keep the leading tab visible within its TabBar tablist while peers scroll. */
|
|
1032
|
+
pinned?: boolean;
|
|
300
1033
|
closable?: boolean;
|
|
301
1034
|
draggable?: boolean;
|
|
302
|
-
leading?:
|
|
303
|
-
trailing?:
|
|
1035
|
+
leading?: KerfUiContent;
|
|
1036
|
+
trailing?: KerfUiContent;
|
|
1037
|
+
/** Visual treatment within a TabBar. Icon-only tabs retain `name` as their accessible name. */
|
|
1038
|
+
presentation?: AppTabPresentation;
|
|
1039
|
+
/** Compact tabs use the 32px application-rail height. */
|
|
1040
|
+
size?: AppTabSize;
|
|
1041
|
+
/** Maximum visible label width in CSS pixels before ellipsis. */
|
|
1042
|
+
labelMaxWidth?: number;
|
|
1043
|
+
/** Keep the full name visible for an inline loading treatment. */
|
|
1044
|
+
nameOverflow?: AppTabNameOverflow;
|
|
304
1045
|
/** Decorative dormant content for the close button. Must not contain interactive descendants. */
|
|
305
1046
|
closeIcon?: SafeHtml;
|
|
306
1047
|
selectAction?: string;
|
|
@@ -308,35 +1049,85 @@ interface AppTabProps {
|
|
|
308
1049
|
className?: string;
|
|
309
1050
|
/** Render as an unanimated loading skeleton, disabling select/close and dragging. */
|
|
310
1051
|
placeholder?: boolean;
|
|
1052
|
+
/**
|
|
1053
|
+
* Named and still opening: the tab is known but its content is loading.
|
|
1054
|
+
* Keeps `name` visible in the quiet text color and as the tab's accessible
|
|
1055
|
+
* name, shows `trailing` (for example a `LoadingSpinner`), and marks the
|
|
1056
|
+
* tab `aria-busy`. Unlike `placeholder` it stays selectable — the
|
|
1057
|
+
* application shows placeholder content in its panel until loading
|
|
1058
|
+
* completes — while close and dragging stay disabled. Same pill geometry
|
|
1059
|
+
* as the live tab, so swapping it in place does not shift the bar.
|
|
1060
|
+
* `placeholder` wins when both are set.
|
|
1061
|
+
*/
|
|
1062
|
+
pending?: boolean;
|
|
311
1063
|
rootAttributes?: AppTabRootAttributes;
|
|
1064
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1065
|
+
slot?: string;
|
|
312
1066
|
}
|
|
313
|
-
declare function AppTab({ id, name, selected, closable, draggable, leading, trailing, closeIcon, selectAction, closeAction, className, placeholder, rootAttributes }: AppTabProps): SafeHtml;
|
|
1067
|
+
declare function AppTab({ id, name, selected, attention, dropTarget, pinned, closable, draggable, leading, trailing, presentation, size, labelMaxWidth, nameOverflow, closeIcon, selectAction, closeAction, className, placeholder, pending, rootAttributes, slot, }: AppTabProps): SafeHtml;
|
|
314
1068
|
|
|
315
|
-
export { AppTab, type AppTabProps };
|
|
1069
|
+
export { AppTab, type AppTabNameOverflow, type AppTabPresentation, type AppTabProps, type AppTabSize };
|
|
316
1070
|
```
|
|
317
1071
|
|
|
318
1072
|
## `@kerfjs/ui/tab-bar`
|
|
319
1073
|
|
|
320
1074
|
```ts
|
|
321
|
-
import
|
|
322
|
-
|
|
1075
|
+
import * as kerfjs from 'kerfjs';
|
|
1076
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1077
|
+
|
|
1078
|
+
type TabActivation = 'automatic' | 'manual';
|
|
1079
|
+
type TabBarAllocation = 'intrinsic' | 'fill';
|
|
1080
|
+
type TabBarPresentation = 'rail' | 'segmented' | 'inspector';
|
|
1081
|
+
type TabBarTrailingPlacement = 'separate' | 'adjacent';
|
|
1082
|
+
/** Tablist width where segmented AppTabs switch to icon-only. */
|
|
1083
|
+
type TabBarIconOnlyAt = 'wide' | 'narrow' | 'compact';
|
|
323
1084
|
interface TabBarProps {
|
|
324
1085
|
id: string;
|
|
325
1086
|
label: string;
|
|
326
|
-
children:
|
|
327
|
-
leading?:
|
|
328
|
-
|
|
1087
|
+
children: KerfUiContent;
|
|
1088
|
+
leading?: KerfUiContent;
|
|
1089
|
+
/** Tab-local action: a ToolbarControlGroup or a standalone Web Awesome button. */
|
|
1090
|
+
trailing?: KerfUiContent;
|
|
1091
|
+
/**
|
|
1092
|
+
* Action pinned to the far edge of the bar. Combine with an adjacent `trailing`
|
|
1093
|
+
* action when the tab-local and workspace-level actions must remain distinct.
|
|
1094
|
+
* Accepts a ToolbarControlGroup or a standalone Web Awesome button.
|
|
1095
|
+
*/
|
|
1096
|
+
end?: KerfUiContent;
|
|
329
1097
|
className?: string;
|
|
1098
|
+
/**
|
|
1099
|
+
* Keyboard activation mode for this strip, emitted as `data-tab-activation` for
|
|
1100
|
+
* `wireTabBars` to read (overrides its `activation` option). `'automatic'` (default)
|
|
1101
|
+
* selects on arrow / Home / End; `'manual'` moves roving focus only and the user
|
|
1102
|
+
* selects with Enter / Space / click — use it when selecting a tab is a heavy action.
|
|
1103
|
+
*/
|
|
1104
|
+
activation?: TabActivation;
|
|
1105
|
+
/** How available strip width is allocated across child AppTabs. */
|
|
1106
|
+
allocation?: TabBarAllocation;
|
|
1107
|
+
/** Named strip chrome for application rails, segmented tabs, or inspectors. */
|
|
1108
|
+
presentation?: TabBarPresentation;
|
|
1109
|
+
/** Switch segmented AppTabs to icon-only at tablist widths of 832, 704, or 448px. Each tab needs a leading icon. */
|
|
1110
|
+
iconOnlyAt?: TabBarIconOnlyAt;
|
|
1111
|
+
/** Keep a trailing action beside the final tab or at the far edge of the bar. */
|
|
1112
|
+
trailingPlacement?: TabBarTrailingPlacement;
|
|
1113
|
+
/** Settle scrolling peers at whole-tab starts; wireTabBars measures a pinned leading tab's inset. */
|
|
1114
|
+
snapTabs?: boolean;
|
|
1115
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1116
|
+
slot?: string;
|
|
330
1117
|
}
|
|
331
1118
|
/** Render a controlled tab strip. The application owns selection, order, and persistence. */
|
|
332
|
-
declare function TabBar({ id, label, children, leading, trailing, className }: TabBarProps): SafeHtml;
|
|
1119
|
+
declare function TabBar({ id, label, children, leading, trailing, end, className, activation, allocation, presentation, iconOnlyAt, trailingPlacement, snapTabs, slot, }: TabBarProps): kerfjs.SafeHtml;
|
|
333
1120
|
|
|
334
|
-
export { TabBar, type TabBarProps };
|
|
1121
|
+
export { type TabActivation, TabBar, type TabBarAllocation, type TabBarIconOnlyAt, type TabBarPresentation, type TabBarProps, type TabBarTrailingPlacement };
|
|
335
1122
|
```
|
|
336
1123
|
|
|
337
1124
|
## `@kerfjs/ui/wire-tab-bars`
|
|
338
1125
|
|
|
339
1126
|
```ts
|
|
1127
|
+
import { TabActivation } from './tab-bar.js';
|
|
1128
|
+
import 'kerfjs';
|
|
1129
|
+
import './semantic-content-BbzjvSu9.js';
|
|
1130
|
+
|
|
340
1131
|
type TabReorderSource = 'pointer' | 'keyboard';
|
|
341
1132
|
type TabDropPosition = 'before' | 'after';
|
|
342
1133
|
interface TabReorder {
|
|
@@ -346,20 +1137,115 @@ interface TabReorder {
|
|
|
346
1137
|
position: TabDropPosition;
|
|
347
1138
|
source: TabReorderSource;
|
|
348
1139
|
}
|
|
1140
|
+
|
|
349
1141
|
interface WireTabBarsOptions {
|
|
350
1142
|
onReorder: (change: TabReorder) => void;
|
|
1143
|
+
/**
|
|
1144
|
+
* How arrow / Home / End keys activate tabs (default `'automatic'`):
|
|
1145
|
+
* - `'automatic'` moves roving focus **and** selects the focused tab (clicks it).
|
|
1146
|
+
* - `'manual'` moves roving focus only; the user selects with Enter / Space / click
|
|
1147
|
+
* (the ARIA Tabs manual-activation pattern). Use this when activation is a heavy or
|
|
1148
|
+
* side-effecting action (e.g. a tab that loads a project) so arrowing through the
|
|
1149
|
+
* strip doesn't trigger it on every tab.
|
|
1150
|
+
*
|
|
1151
|
+
* A per-bar `data-tab-activation="manual" | "automatic"` attribute (see the `TabBar`
|
|
1152
|
+
* `activation` prop) overrides this option for that strip.
|
|
1153
|
+
*/
|
|
1154
|
+
activation?: TabActivation;
|
|
351
1155
|
}
|
|
352
1156
|
declare function reorderTabs<T>(items: readonly T[], getId: (item: T) => string, sourceId: string, targetId: string, position: TabDropPosition): T[];
|
|
353
1157
|
/** Wire reordering and keyboard navigation while leaving controlled state in the application. */
|
|
354
|
-
declare function wireTabBars(root: HTMLElement | Document, { onReorder }: WireTabBarsOptions): () => void;
|
|
1158
|
+
declare function wireTabBars(root: HTMLElement | Document, { onReorder, activation }: WireTabBarsOptions): () => void;
|
|
1159
|
+
|
|
1160
|
+
export { TabActivation, type TabDropPosition, type TabReorder, type TabReorderSource, type WireTabBarsOptions, reorderTabs, wireTabBars };
|
|
1161
|
+
```
|
|
1162
|
+
|
|
1163
|
+
## `@kerfjs/ui/wire-scroll-dividers`
|
|
1164
|
+
|
|
1165
|
+
```ts
|
|
1166
|
+
/**
|
|
1167
|
+
* An app-owned scroll arrangement outside a `Pane`: the `id` of the element
|
|
1168
|
+
* that scrolls and the `id`s of the pinned chrome on each physical side of it.
|
|
1169
|
+
* Each named chrome element shows its divider on the side facing the scroller
|
|
1170
|
+
* while content is scrolled away beyond that side. Ids are resolved below the
|
|
1171
|
+
* wired root on every refresh, so a re-render that replaces an element keeps
|
|
1172
|
+
* the pairing.
|
|
1173
|
+
*/
|
|
1174
|
+
interface ScrollDividerTarget {
|
|
1175
|
+
/** The `id` of the scrolling element. */
|
|
1176
|
+
scroller: string;
|
|
1177
|
+
/** Chrome above the scroller: shows its bottom divider once scrolled down. */
|
|
1178
|
+
top?: string;
|
|
1179
|
+
/**
|
|
1180
|
+
* Chrome right of the scroller: shows its left divider while content is
|
|
1181
|
+
* hidden beyond the scroller's right edge (never when nothing overflows).
|
|
1182
|
+
*/
|
|
1183
|
+
right?: string;
|
|
1184
|
+
/**
|
|
1185
|
+
* Chrome below the scroller: shows its top divider while content is hidden
|
|
1186
|
+
* beyond the scroller's bottom edge (never when nothing overflows).
|
|
1187
|
+
*/
|
|
1188
|
+
bottom?: string;
|
|
1189
|
+
/** Chrome left of the scroller: shows its right divider once scrolled right. */
|
|
1190
|
+
left?: string;
|
|
1191
|
+
}
|
|
1192
|
+
interface WireScrollDividersOptions {
|
|
1193
|
+
/**
|
|
1194
|
+
* App-owned scroll arrangements to pair beyond the ones found by structure
|
|
1195
|
+
* (every `Pane`'s header and footer around its content, every `NavStack`'s
|
|
1196
|
+
* and `TabScaffold`'s chrome around its active region, and every `TabBar`
|
|
1197
|
+
* strip).
|
|
1198
|
+
*/
|
|
1199
|
+
targets?: readonly ScrollDividerTarget[];
|
|
1200
|
+
}
|
|
1201
|
+
type Root = HTMLElement | Document;
|
|
1202
|
+
/**
|
|
1203
|
+
* Wire scroll dividers below `root`: a divider between pinned chrome and the
|
|
1204
|
+
* content that scrolls beside it shows only while content is scrolled away
|
|
1205
|
+
* from that edge. Near edges (top, left) hide at the scroll start; far edges
|
|
1206
|
+
* (bottom, right) hide at the scroll end and whenever nothing overflows.
|
|
1207
|
+
*
|
|
1208
|
+
* The wiring only reports scroll state; each component draws its own divider
|
|
1209
|
+
* from it. It writes `data-scroll-overflow` (the edges with hidden content, in
|
|
1210
|
+
* canonical `t`/`r`/`b`/`l` order) on each scroller, and `data-scroll-divider`
|
|
1211
|
+
* (the sides to draw) on each paired chrome element:
|
|
1212
|
+
*
|
|
1213
|
+
* - every `Pane` with a header or footer: its header shows a bottom divider and
|
|
1214
|
+
* its footer a top divider (drawn by the Pane, per its `chromeDividers`);
|
|
1215
|
+
* - every `NavStack`'s top chrome and bottom toolbar around its active view,
|
|
1216
|
+
* and every `TabScaffold`'s bar under its active scene: the chrome shows a
|
|
1217
|
+
* bottom (top chrome) or top (bottom toolbar, bar) divider. The scroller is
|
|
1218
|
+
* whichever element actually scrolls there: the view or scene itself, or,
|
|
1219
|
+
* through a sole child with no chrome of its own on that edge, a `Pane`'s
|
|
1220
|
+
* content or a nested `NavStack` / `TabScaffold` region (a Pane's own header
|
|
1221
|
+
* or footer draws that boundary instead);
|
|
1222
|
+
* - every `TabBar` strip: the bar draws a divider on each side of the strip
|
|
1223
|
+
* whose tabs are scrolled out of view;
|
|
1224
|
+
* - each app-owned `targets` pairing: a `Toolbar` or `List` named as chrome
|
|
1225
|
+
* draws the divider on its facing side.
|
|
1226
|
+
*
|
|
1227
|
+
* Structure is re-read after every DOM change below root (a re-render that
|
|
1228
|
+
* drops the attributes gets them back before paint), scroll is tracked with
|
|
1229
|
+
* one capturing listener per registered root, and size changes of each
|
|
1230
|
+
* scroller and its children with a `ResizeObserver`. Overlapping registrations
|
|
1231
|
+
* share one attribute writer; each disposer removes its registration, and the
|
|
1232
|
+
* final disposer removes the wiring-owned attributes. See
|
|
1233
|
+
* `docs/23-app-layouts.md` §3.7.
|
|
1234
|
+
*/
|
|
1235
|
+
declare function wireScrollDividers(root: Root, { targets }?: WireScrollDividersOptions): () => void;
|
|
355
1236
|
|
|
356
|
-
export { type
|
|
1237
|
+
export { type ScrollDividerTarget, type WireScrollDividersOptions, wireScrollDividers };
|
|
357
1238
|
```
|
|
358
1239
|
|
|
359
1240
|
## `@kerfjs/ui/nav-stack`
|
|
360
1241
|
|
|
361
1242
|
```ts
|
|
362
|
-
import
|
|
1243
|
+
import * as kerfjs from 'kerfjs';
|
|
1244
|
+
import { PaneAppearance } from './pane.js';
|
|
1245
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1246
|
+
import { ToolbarConfig } from './toolbar.js';
|
|
1247
|
+
import { ToolbarTextSize, HeadingLevel } from './toolbar-text.js';
|
|
1248
|
+
import './sides-BPSWde0A.js';
|
|
363
1249
|
|
|
364
1250
|
/**
|
|
365
1251
|
* One entry in a {@link NavStack}. The app owns the stack as an array (usually a
|
|
@@ -368,11 +1254,34 @@ import { SafeHtml } from 'kerfjs';
|
|
|
368
1254
|
interface NavStackView {
|
|
369
1255
|
/** Stable identity for keyed reconcile and transition direction. */
|
|
370
1256
|
key: string;
|
|
371
|
-
content:
|
|
1257
|
+
content: KerfUiContent;
|
|
1258
|
+
/** Background of this view's scrolling work surface. */
|
|
1259
|
+
appearance?: PaneAppearance;
|
|
372
1260
|
/** Title shown in the top toolbar for this view. */
|
|
373
1261
|
title?: string;
|
|
1262
|
+
/** Leading groups for this view's top toolbar, after the back control and before the title. */
|
|
1263
|
+
leading?: KerfUiContent;
|
|
1264
|
+
/** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */
|
|
1265
|
+
center?: KerfUiContent;
|
|
374
1266
|
/** Trailing actions for this view's top toolbar. */
|
|
375
|
-
toolbar?:
|
|
1267
|
+
toolbar?: KerfUiContent;
|
|
1268
|
+
/** Fixed chrome below this view's toolbar, above its scrolling content. */
|
|
1269
|
+
header?: KerfUiContent;
|
|
1270
|
+
/** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */
|
|
1271
|
+
bottomToolbar?: KerfUiContent;
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* The top toolbar's configuration. Its `ToolbarConfig` forwards to the real
|
|
1275
|
+
* `Toolbar` the stack renders; by default that toolbar draws no divider and
|
|
1276
|
+
* claims the top and side safe-area edges the stack still touches.
|
|
1277
|
+
*/
|
|
1278
|
+
interface NavStackToolbarConfig extends ToolbarConfig {
|
|
1279
|
+
/** Accessible name of the top toolbar (default: none). */
|
|
1280
|
+
label?: string;
|
|
1281
|
+
/** Size of the view title's `ToolbarText` (default `large`). */
|
|
1282
|
+
titleSize?: ToolbarTextSize;
|
|
1283
|
+
/** Expose the view title as a heading at this level (default: a plain span). */
|
|
1284
|
+
headingLevel?: HeadingLevel;
|
|
376
1285
|
}
|
|
377
1286
|
interface NavStackProps {
|
|
378
1287
|
id: string;
|
|
@@ -380,23 +1289,51 @@ interface NavStackProps {
|
|
|
380
1289
|
label: string;
|
|
381
1290
|
/** The stack, root first; the last entry is the active top view. */
|
|
382
1291
|
views: NavStackView[];
|
|
383
|
-
/** Accessible label for the back control (default "Back"). */
|
|
1292
|
+
/** Accessible label for the icon-only back control (default "Back"). */
|
|
384
1293
|
backLabel?: string;
|
|
1294
|
+
/** The back control's icon (default a chevron-left `LucideIcon`). */
|
|
1295
|
+
backIcon?: KerfUiContent;
|
|
1296
|
+
/**
|
|
1297
|
+
* Visible text beside the back icon, such as the previous view's title
|
|
1298
|
+
* (default: icon only). When set, the text names the control and
|
|
1299
|
+
* `backLabel` is not used.
|
|
1300
|
+
*/
|
|
1301
|
+
backText?: string;
|
|
1302
|
+
/** The top toolbar's configuration, forwarded to its `Toolbar`. */
|
|
1303
|
+
toolbarConfig?: NavStackToolbarConfig;
|
|
1304
|
+
/** Persistent last group in every view's top toolbar, supplied by a hosting panel. */
|
|
1305
|
+
panelToggle?: KerfUiContent;
|
|
385
1306
|
/** Hide the top toolbar entirely (rare — a fully custom-chrome view). */
|
|
386
1307
|
hideToolbar?: boolean;
|
|
387
|
-
/** Optional persistent bottom toolbar. */
|
|
388
|
-
bottomToolbar?:
|
|
1308
|
+
/** Optional persistent bottom toolbar used when the active view does not provide one. */
|
|
1309
|
+
bottomToolbar?: KerfUiContent;
|
|
1310
|
+
/**
|
|
1311
|
+
* The line under the top chrome and over the bottom toolbar, where they
|
|
1312
|
+
* meet the active view. `scroll` (default) shows the chrome's line only
|
|
1313
|
+
* while the view's content is scrolled beneath it, and the bottom
|
|
1314
|
+
* toolbar's only while more content lies below — never when the content
|
|
1315
|
+
* fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is
|
|
1316
|
+
* wired above the stack; unwired, neither shows. `always` shows both
|
|
1317
|
+
* without the wiring; `none` neither, even when wired. The line is drawn
|
|
1318
|
+
* inside the chrome, so no state moves the chrome or the content. A
|
|
1319
|
+
* `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.
|
|
1320
|
+
*/
|
|
1321
|
+
chromeDividers?: 'scroll' | 'always' | 'none';
|
|
389
1322
|
className?: string;
|
|
1323
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1324
|
+
slot?: string;
|
|
390
1325
|
}
|
|
391
1326
|
/**
|
|
392
1327
|
* A navigation stack (iOS-style push/pop). Renders every entry stacked, the last
|
|
393
1328
|
* one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and
|
|
394
|
-
* cross-fades the chrome across a change.
|
|
395
|
-
*
|
|
1329
|
+
* cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the
|
|
1330
|
+
* back control and title lead, the active view's `leading` / `center` / `toolbar`
|
|
1331
|
+
* content fills the zones, and `toolbarConfig` configures it. A single-pane
|
|
1332
|
+
* layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.
|
|
396
1333
|
*/
|
|
397
|
-
declare function NavStack({ id, label, views, backLabel, hideToolbar, bottomToolbar, className }: NavStackProps): SafeHtml;
|
|
1334
|
+
declare function NavStack({ id, label, views, backLabel, backIcon, backText, toolbarConfig, panelToggle, hideToolbar, bottomToolbar, chromeDividers, className, slot, }: NavStackProps): kerfjs.SafeHtml;
|
|
398
1335
|
|
|
399
|
-
export { NavStack, type NavStackProps, type NavStackView };
|
|
1336
|
+
export { NavStack, type NavStackProps, type NavStackToolbarConfig, type NavStackView };
|
|
400
1337
|
```
|
|
401
1338
|
|
|
402
1339
|
## `@kerfjs/ui/wire-nav-stack`
|
|
@@ -412,7 +1349,10 @@ interface WireNavStackOptions {
|
|
|
412
1349
|
* Animate a `NavStack`'s push/pop transitions and wire its back control. The app
|
|
413
1350
|
* owns the stack (a signal of `NavStackView[]`) and re-renders `NavStack` when it
|
|
414
1351
|
* changes; this helper slides the content and settles the chrome across each
|
|
415
|
-
* change,
|
|
1352
|
+
* change, moves focus into every new top view, restores that view's last focused
|
|
1353
|
+
* descendant on pop, and calls `onBack` when the back control is used. Mark a
|
|
1354
|
+
* preferred initial target with `data-nav-focus`; otherwise the first focusable
|
|
1355
|
+
* descendant (or the view itself) receives focus. Returns a disposer.
|
|
416
1356
|
*/
|
|
417
1357
|
declare function wireNavStack(root: Element, options?: WireNavStackOptions): () => void;
|
|
418
1358
|
|
|
@@ -422,20 +1362,48 @@ export { type WireNavStackOptions, wireNavStack };
|
|
|
422
1362
|
## `@kerfjs/ui/split-view`
|
|
423
1363
|
|
|
424
1364
|
```ts
|
|
425
|
-
import
|
|
1365
|
+
import * as kerfjs from 'kerfjs';
|
|
1366
|
+
import { NavStackProps, NavStackView } from './nav-stack.js';
|
|
1367
|
+
import { ResizableRegionProps } from './resizable-region.js';
|
|
1368
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1369
|
+
import './pane.js';
|
|
1370
|
+
import './toolbar.js';
|
|
1371
|
+
import './sides-BPSWde0A.js';
|
|
1372
|
+
import './toolbar-text.js';
|
|
1373
|
+
import './css-values.js';
|
|
426
1374
|
|
|
427
|
-
|
|
1375
|
+
/**
|
|
1376
|
+
* The roomy list pane's `ResizableRegion`: its committed `size` and `min` /
|
|
1377
|
+
* `max` limits, plus the region configuration that forwards unchanged
|
|
1378
|
+
* (`separator`, `handleIcon`, `contentOverflow`, and collapse:
|
|
1379
|
+
* `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,
|
|
1380
|
+
* `restorePosition`). Omitted options keep the region's defaults.
|
|
1381
|
+
*/
|
|
1382
|
+
interface SplitViewResizable extends Pick<ResizableRegionProps, 'separator' | 'handleIcon' | 'contentOverflow' | 'collapsed' | 'transitioning' | 'collapseMotion' | 'restoreControl' | 'restorePosition'> {
|
|
428
1383
|
size: number;
|
|
429
1384
|
min: number;
|
|
430
1385
|
max: number;
|
|
431
1386
|
}
|
|
1387
|
+
/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */
|
|
1388
|
+
type SplitViewCompactViewToolbars = Pick<NavStackView, 'leading' | 'center' | 'toolbar' | 'bottomToolbar'>;
|
|
1389
|
+
/**
|
|
1390
|
+
* The compact `NavStack`'s configuration: its toolbar configuration, back
|
|
1391
|
+
* control, persistent bottom toolbar, and chrome dividers forward to the
|
|
1392
|
+
* stack, and `list` / `detail` give each view its own toolbar groups.
|
|
1393
|
+
*/
|
|
1394
|
+
interface SplitViewCompactStack extends Pick<NavStackProps, 'toolbarConfig' | 'backIcon' | 'backText' | 'hideToolbar' | 'bottomToolbar' | 'chromeDividers'> {
|
|
1395
|
+
/** Toolbar content for the list (root) view. */
|
|
1396
|
+
list?: SplitViewCompactViewToolbars;
|
|
1397
|
+
/** Toolbar content for the pushed detail view. */
|
|
1398
|
+
detail?: SplitViewCompactViewToolbars;
|
|
1399
|
+
}
|
|
432
1400
|
interface SplitViewProps {
|
|
433
1401
|
id: string;
|
|
434
1402
|
label: string;
|
|
435
1403
|
/** The list (primary) pane. */
|
|
436
|
-
list:
|
|
1404
|
+
list: KerfUiContent;
|
|
437
1405
|
/** The detail (secondary) pane. */
|
|
438
|
-
detail:
|
|
1406
|
+
detail: KerfUiContent;
|
|
439
1407
|
/**
|
|
440
1408
|
* Compact ("one pane at a time") classes — a handset or portrait tablet.
|
|
441
1409
|
* Derive from `deviceClass().value.compact`. When true the split collapses to
|
|
@@ -450,81 +1418,810 @@ interface SplitViewProps {
|
|
|
450
1418
|
detailTitle?: string;
|
|
451
1419
|
/** Back label for the compact NavStack (default "Back"). */
|
|
452
1420
|
backLabel?: string;
|
|
1421
|
+
/** Compact NavStack configuration and per-view toolbars. */
|
|
1422
|
+
compactStack?: SplitViewCompactStack;
|
|
453
1423
|
/** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */
|
|
454
1424
|
resizable?: SplitViewResizable;
|
|
455
1425
|
className?: string;
|
|
1426
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1427
|
+
slot?: string;
|
|
456
1428
|
}
|
|
457
1429
|
/**
|
|
458
|
-
* A list-detail
|
|
1430
|
+
* A list-detail split. On roomy classes it shows both panes side
|
|
459
1431
|
* by side with an optional resizable separator; on compact classes it collapses
|
|
460
1432
|
* to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the
|
|
461
1433
|
* resizable wiring with `wireResizableRegions` and the compact back with
|
|
462
1434
|
* `wireNavStack`.
|
|
463
1435
|
*/
|
|
464
|
-
declare function SplitView({ id, label, list, detail, compact, detailActive, listTitle, detailTitle, backLabel, resizable, className }: SplitViewProps): SafeHtml;
|
|
1436
|
+
declare function SplitView({ id, label, list, detail, compact, detailActive, listTitle, detailTitle, backLabel, compactStack, resizable, className, slot, }: SplitViewProps): kerfjs.SafeHtml;
|
|
1437
|
+
|
|
1438
|
+
export { SplitView, type SplitViewCompactStack, type SplitViewCompactViewToolbars, type SplitViewProps, type SplitViewResizable };
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
## `@kerfjs/ui/pane`
|
|
1442
|
+
|
|
1443
|
+
```ts
|
|
1444
|
+
import * as kerfjs from 'kerfjs';
|
|
1445
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1446
|
+
|
|
1447
|
+
/**
|
|
1448
|
+
* Logical pane sides: where a {@link Pane} can show a separator and where it can
|
|
1449
|
+
* compensate for a device safe-area inset.
|
|
1450
|
+
*/
|
|
1451
|
+
type PaneSeparatorSide = 'block-start' | 'block-end' | 'inline-start' | 'inline-end';
|
|
1452
|
+
/** Semantic root elements supported by {@link Pane}. */
|
|
1453
|
+
type PaneElement = 'article' | 'aside' | 'div' | 'main' | 'section';
|
|
1454
|
+
/** Semantic elements supported by the scrolling content slot. */
|
|
1455
|
+
type PaneContentElement = 'div' | 'main' | 'nav' | 'section';
|
|
1456
|
+
type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
1457
|
+
'data-component'?: never;
|
|
1458
|
+
'data-separator-block-start'?: never;
|
|
1459
|
+
'data-separator-block-end'?: never;
|
|
1460
|
+
'data-separator-inline-start'?: never;
|
|
1461
|
+
'data-separator-inline-end'?: never;
|
|
1462
|
+
'data-safe-area-block-start'?: never;
|
|
1463
|
+
'data-safe-area-block-end'?: never;
|
|
1464
|
+
'data-safe-area-inline-start'?: never;
|
|
1465
|
+
'data-safe-area-inline-end'?: never;
|
|
1466
|
+
'data-chrome-placement'?: never;
|
|
1467
|
+
'data-chrome-dividers'?: never;
|
|
1468
|
+
'data-appearance'?: never;
|
|
1469
|
+
}>;
|
|
1470
|
+
/** How a Pane's header and footer relate to its scrolling content. */
|
|
1471
|
+
type PaneChromePlacement = 'fixed' | 'auto';
|
|
1472
|
+
/**
|
|
1473
|
+
* When a Pane draws the divider between its pinned header or footer and its
|
|
1474
|
+
* scrolling content: `scroll` while content is scrolled away beneath that
|
|
1475
|
+
* chrome, as `wireScrollDividers` reports; `always`; or `none`.
|
|
1476
|
+
*/
|
|
1477
|
+
type PaneChromeDividers = 'scroll' | 'always' | 'none';
|
|
1478
|
+
/** Background treatment of the Pane's scrolling work surface. */
|
|
1479
|
+
type PaneAppearance = 'default' | 'sunken';
|
|
1480
|
+
interface PaneProps {
|
|
1481
|
+
/** Optional fixed chrome above the scrolling content, arranged vertically. */
|
|
1482
|
+
header?: KerfUiContent;
|
|
1483
|
+
/** The pane's primary vertical, scrolling content stack. */
|
|
1484
|
+
children?: KerfUiContent;
|
|
1485
|
+
/** Optional fixed chrome below the scrolling content. */
|
|
1486
|
+
footer?: KerfUiContent;
|
|
1487
|
+
/**
|
|
1488
|
+
* Whether the header and footer stay pinned around the scrolling content.
|
|
1489
|
+
* `fixed` (default) always pins them. `auto` pins them while the pane is
|
|
1490
|
+
* tall enough, and below 480px of height (30rem, so it scales with the text
|
|
1491
|
+
* size) lets the whole pane scroll as one column, so tall chrome can never
|
|
1492
|
+
* squeeze the content to nothing.
|
|
1493
|
+
*/
|
|
1494
|
+
chromePlacement?: PaneChromePlacement;
|
|
1495
|
+
/**
|
|
1496
|
+
* The divider under the header and over the footer, where they meet the
|
|
1497
|
+
* scrolling content. Omitted defaults to `scroll` for a plain pane and
|
|
1498
|
+
* `always` for `appearance="sunken"`. `scroll` shows the header's divider only
|
|
1499
|
+
* while the content is scrolled down, and the footer's only while more
|
|
1500
|
+
* content lies below — never when the content fits — once
|
|
1501
|
+
* `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above
|
|
1502
|
+
* the pane; unwired, neither shows. `always` shows both; `none` neither.
|
|
1503
|
+
* The line is drawn inside the chrome, so no state moves the content.
|
|
1504
|
+
*/
|
|
1505
|
+
chromeDividers?: PaneChromeDividers;
|
|
1506
|
+
/** Paint the scrolling work surface with the shared lowered-surface color. */
|
|
1507
|
+
appearance?: PaneAppearance;
|
|
1508
|
+
/** Root semantics. Defaults to `div`. */
|
|
1509
|
+
element?: PaneElement;
|
|
1510
|
+
/** Scrolling content semantics. Defaults to `div`. */
|
|
1511
|
+
contentElement?: PaneContentElement;
|
|
1512
|
+
/** Independent logical-edge separator lines. Defaults to none. */
|
|
1513
|
+
separators?: readonly PaneSeparatorSide[];
|
|
1514
|
+
/**
|
|
1515
|
+
* Sides on which the pane may compensate for a device safe-area inset.
|
|
1516
|
+
* Defaults to every side: the pane pads its slots for each side that still
|
|
1517
|
+
* reaches an unsafe screen edge, as its surrounding layout reports, while its
|
|
1518
|
+
* background and separators paint through. List only the sides an app-owned
|
|
1519
|
+
* layout places at a screen edge, or pass `[]` to opt out.
|
|
1520
|
+
*/
|
|
1521
|
+
safeAreaEdges?: readonly PaneSeparatorSide[];
|
|
1522
|
+
id?: string;
|
|
1523
|
+
/** Accessible name for a landmark root such as `aside` or `main`. */
|
|
1524
|
+
label?: string;
|
|
1525
|
+
/** Accessible name for a landmark scrolling slot such as `nav`. */
|
|
1526
|
+
contentLabel?: string;
|
|
1527
|
+
className?: string;
|
|
1528
|
+
headerClassName?: string;
|
|
1529
|
+
contentClassName?: string;
|
|
1530
|
+
footerClassName?: string;
|
|
1531
|
+
/** Safe `data-*` metadata; Pane-owned structural attributes remain protected. */
|
|
1532
|
+
rootAttributes?: PaneRootAttributes;
|
|
1533
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1534
|
+
slot?: string;
|
|
1535
|
+
}
|
|
1536
|
+
/**
|
|
1537
|
+
* A pane's configuration, apart from its content and styling hooks: the props a
|
|
1538
|
+
* composite that renders a `Pane` for the app (a Workbench panel or work area,
|
|
1539
|
+
* or a CollapsiblePanel) forwards, so the app configures that pane instead of
|
|
1540
|
+
* styling it. An omitted or `undefined` field keeps the composite's default.
|
|
1541
|
+
*/
|
|
1542
|
+
type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'appearance'>;
|
|
1543
|
+
/**
|
|
1544
|
+
* An unpadded application column with optional fixed header/footer slots and one
|
|
1545
|
+
* scrolling vertical content owner. Separator lines are independently opt-in on
|
|
1546
|
+
* each logical edge, so the same component works as a sidebar, main area,
|
|
1547
|
+
* inspector, or dialog column.
|
|
1548
|
+
*/
|
|
1549
|
+
declare function Pane({ header, children, footer, chromePlacement, chromeDividers, appearance, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
|
|
465
1550
|
|
|
466
|
-
export {
|
|
1551
|
+
export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
|
|
467
1552
|
```
|
|
468
1553
|
|
|
469
1554
|
## `@kerfjs/ui/workbench`
|
|
470
1555
|
|
|
471
1556
|
```ts
|
|
472
1557
|
import { SafeHtml } from 'kerfjs';
|
|
1558
|
+
import { ListConfig } from './list.js';
|
|
1559
|
+
import { NavStackProps } from './nav-stack.js';
|
|
1560
|
+
import { PaneConfig } from './pane.js';
|
|
1561
|
+
import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
|
|
1562
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1563
|
+
import { ToolbarConfig } from './toolbar.js';
|
|
1564
|
+
import { a as PanelToolbar, b as PanelChromePlacement, c as PanelBottomToolbar, d as PanelToggle } from './panel-toolbar-DDKh4uKd.js';
|
|
1565
|
+
import './css-values.js';
|
|
1566
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
1567
|
+
import './sides-BPSWde0A.js';
|
|
1568
|
+
import './toolbar-text.js';
|
|
1569
|
+
import './lucide-icon.js';
|
|
1570
|
+
import 'lucide';
|
|
1571
|
+
|
|
1572
|
+
/** The standard toggle a Workbench renders for a panel (see {@link PanelToggle}). */
|
|
1573
|
+
type WorkbenchPanelToggle = PanelToggle;
|
|
1574
|
+
/**
|
|
1575
|
+
* A Workbench panel's top toolbar, composed by the Workbench so its groups can
|
|
1576
|
+
* follow the panel's open state (see {@link PanelToolbar} for the roles).
|
|
1577
|
+
* A collapsed rail's marked groups and toggle go to the leading edge of
|
|
1578
|
+
* `mainToolbar` (left rail) or its trailing edge (right rail); a collapsed
|
|
1579
|
+
* drawer's go to the trailing edge of `mainBottomToolbar`, else to a
|
|
1580
|
+
* `FloatingToolbar` in the work area's bottom-end corner.
|
|
1581
|
+
*/
|
|
1582
|
+
type WorkbenchPanelToolbar = PanelToolbar;
|
|
1583
|
+
type WorkbenchPanelBottomToolbar = PanelBottomToolbar;
|
|
1584
|
+
/**
|
|
1585
|
+
* The work area's top toolbar; collapsed rails add their groups to it. Its
|
|
1586
|
+
* configuration forwards to its `Toolbar`. It draws no divider of its own by
|
|
1587
|
+
* default: the work area's `Pane` draws one under its header chrome, wherever
|
|
1588
|
+
* that chrome ends, while `main` is scrolled (`mainPane.chromeDividers`).
|
|
1589
|
+
*/
|
|
1590
|
+
interface WorkbenchMainToolbar extends ToolbarConfig {
|
|
1591
|
+
label: string;
|
|
1592
|
+
/** The work area's title, usually an extra-large `ToolbarText`. */
|
|
1593
|
+
title?: KerfUiContent;
|
|
1594
|
+
/** Groups after the title. */
|
|
1595
|
+
leading?: KerfUiContent;
|
|
1596
|
+
center?: KerfUiContent;
|
|
1597
|
+
/** Groups at the trailing edge, before a collapsed right rail's groups. */
|
|
1598
|
+
trailing?: KerfUiContent;
|
|
1599
|
+
}
|
|
1600
|
+
/**
|
|
1601
|
+
* The work area's bottom toolbar; a collapsed drawer adds its groups to it.
|
|
1602
|
+
* Its configuration forwards to its `Toolbar`. It draws no divider of its own
|
|
1603
|
+
* by default: the work area's `Pane` draws one over its footer chrome while
|
|
1604
|
+
* more of `main` lies below (`mainPane.chromeDividers`).
|
|
1605
|
+
*/
|
|
1606
|
+
interface WorkbenchMainBottomToolbar extends ToolbarConfig {
|
|
1607
|
+
label: string;
|
|
1608
|
+
leading?: KerfUiContent;
|
|
1609
|
+
center?: KerfUiContent;
|
|
1610
|
+
trailing?: KerfUiContent;
|
|
1611
|
+
}
|
|
1612
|
+
/**
|
|
1613
|
+
* Whether the work area's header or footer chrome stays pinned (`fixed`),
|
|
1614
|
+
* scrolls away with the content (`scroll`), or stays pinned while the work
|
|
1615
|
+
* area is tall enough and scrolls with the content when it is short (`auto`,
|
|
1616
|
+
* the Pane's `chromePlacement="auto"`; it applies to the pinned header and
|
|
1617
|
+
* footer together).
|
|
1618
|
+
*/
|
|
1619
|
+
type WorkbenchChromePlacement = PanelChromePlacement;
|
|
473
1620
|
|
|
474
|
-
/**
|
|
475
|
-
|
|
476
|
-
|
|
1621
|
+
/**
|
|
1622
|
+
* The Workbench container breakpoint below which a panel presents as an
|
|
1623
|
+
* overlay: `narrow` (704px or less) or `compact` (448px or less) — the same
|
|
1624
|
+
* breakpoints as `ResizableRegion`'s `responsiveFillAt` — or `never` to keep
|
|
1625
|
+
* it inline at every width.
|
|
1626
|
+
*/
|
|
1627
|
+
type WorkbenchResponsiveOverlayAt = 'compact' | 'narrow' | 'never' | number;
|
|
1628
|
+
/**
|
|
1629
|
+
* How wide a rail's overlay is in a compact (448px or less) Workbench: `inset`
|
|
1630
|
+
* fills the Workbench less a dismiss margin on the side away from the rail's
|
|
1631
|
+
* edge, so a press beside it closes it; `full` fills the Workbench.
|
|
1632
|
+
*/
|
|
1633
|
+
type WorkbenchCompactOverlay = 'inset' | 'full';
|
|
1634
|
+
/** Drag-resize limits for a resizable Workbench panel, in px. */
|
|
1635
|
+
interface WorkbenchPanelResizable {
|
|
1636
|
+
/** Smallest size (default 180 for a rail, 120 for the drawer). */
|
|
1637
|
+
min?: number;
|
|
1638
|
+
/** Largest size (default 480). */
|
|
1639
|
+
max?: number;
|
|
1640
|
+
}
|
|
1641
|
+
/** Region sizing, collapse, and presentation shared by either panel body. */
|
|
1642
|
+
interface WorkbenchPanelBase {
|
|
477
1643
|
/** Whether the panel is currently collapsed (the app owns this). */
|
|
478
1644
|
collapsed?: boolean;
|
|
479
|
-
/**
|
|
1645
|
+
/**
|
|
1646
|
+
* Rail width, or drawer height, in px. Overrides the CSS default. For a
|
|
1647
|
+
* resizable panel it is the current size (default 280 for a rail, 220 for
|
|
1648
|
+
* the drawer), clamped to the limits; the app owns it and `wireWorkbench`
|
|
1649
|
+
* reports each resize.
|
|
1650
|
+
*/
|
|
480
1651
|
size?: number;
|
|
1652
|
+
/**
|
|
1653
|
+
* Opt in to drag and keyboard resizing on the panel's inner separator:
|
|
1654
|
+
* `true` for the default limits, or `{ min, max }`. Off by default. Pair it
|
|
1655
|
+
* with `wireWorkbench` from `@kerfjs/ui/wire-workbench`.
|
|
1656
|
+
*/
|
|
1657
|
+
resizable?: boolean | WorkbenchPanelResizable;
|
|
481
1658
|
/** Accessible name for the panel region. */
|
|
482
1659
|
label?: string;
|
|
1660
|
+
separator?: ResizableRegionSeparator;
|
|
1661
|
+
collapseMotion?: ResizableRegionCollapseMotion;
|
|
1662
|
+
contentOverflow?: ResizableRegionContentOverflow;
|
|
1663
|
+
presentation?: ResizableRegionPresentation;
|
|
1664
|
+
/**
|
|
1665
|
+
* Present the panel as an overlay, without a separator, below a Workbench
|
|
1666
|
+
* container breakpoint, and inline above it. `compact` and `narrow` use
|
|
1667
|
+
* CSS container queries; a positive number is a pixel threshold measured
|
|
1668
|
+
* by `wireWorkbench` and requires a `collapsed` signal. A rail overlays from its side at full
|
|
1669
|
+
* height, over the work area and an open drawer; the bottom drawer
|
|
1670
|
+
* overlays the bottom of the work-area column. Rails default to `narrow`
|
|
1671
|
+
* (pass `never` to keep one inline); the drawer defaults to inline.
|
|
1672
|
+
*/
|
|
1673
|
+
responsiveOverlayAt?: WorkbenchResponsiveOverlayAt;
|
|
1674
|
+
/**
|
|
1675
|
+
* A rail's overlay width in a compact Workbench (default `inset`: the
|
|
1676
|
+
* Workbench less `--kui-workbench-overlay-dismiss-margin`, 44px). Ignored
|
|
1677
|
+
* by the drawer.
|
|
1678
|
+
*/
|
|
1679
|
+
compactOverlay?: WorkbenchCompactOverlay;
|
|
1680
|
+
/**
|
|
1681
|
+
* Control shown while collapsed, in a safe-area-aware corner of the
|
|
1682
|
+
* Workbench (not the viewport); the bottom drawer's sits in the work-area
|
|
1683
|
+
* column. Prefer `toolbar.toggle`, which the Workbench relocates into the
|
|
1684
|
+
* work area's toolbar (or this corner when that toolbar is absent).
|
|
1685
|
+
*/
|
|
1686
|
+
restoreControl?: SafeHtml;
|
|
1687
|
+
restorePosition?: ResizableRegionRestorePosition;
|
|
483
1688
|
}
|
|
1689
|
+
/** The original static panel body: one toolbar, optional fixed chrome, and one Pane. */
|
|
1690
|
+
interface WorkbenchStaticPanel extends WorkbenchPanelBase {
|
|
1691
|
+
content: KerfUiContent;
|
|
1692
|
+
/** The composed toolbar; marked groups and its toggle relocate on collapse. */
|
|
1693
|
+
toolbar?: WorkbenchPanelToolbar;
|
|
1694
|
+
header?: KerfUiContent;
|
|
1695
|
+
headerList?: ListConfig;
|
|
1696
|
+
headerPlacement?: WorkbenchChromePlacement;
|
|
1697
|
+
footer?: KerfUiContent;
|
|
1698
|
+
footerList?: ListConfig;
|
|
1699
|
+
bottomToolbar?: WorkbenchPanelBottomToolbar;
|
|
1700
|
+
footerPlacement?: WorkbenchChromePlacement;
|
|
1701
|
+
/** Configuration for the static toolbar panel's Pane. */
|
|
1702
|
+
pane?: PaneConfig;
|
|
1703
|
+
navStack?: never;
|
|
1704
|
+
}
|
|
1705
|
+
/** A panel whose active NavStack view supplies the toolbar, fixed header, and scroll body. */
|
|
1706
|
+
interface WorkbenchNavigationPanel extends WorkbenchPanelBase {
|
|
1707
|
+
navStack: Omit<NavStackProps, 'panelToggle' | 'hideToolbar' | 'className' | 'slot'>;
|
|
1708
|
+
/** Supplies the standard toggle; active view groups precede it and may relocate on collapse. */
|
|
1709
|
+
toolbar: Omit<WorkbenchPanelToolbar, 'title' | 'leading' | 'center' | 'trailing'> & {
|
|
1710
|
+
toggle: NonNullable<WorkbenchPanelToolbar['toggle']>;
|
|
1711
|
+
};
|
|
1712
|
+
content?: never;
|
|
1713
|
+
header?: never;
|
|
1714
|
+
headerList?: never;
|
|
1715
|
+
headerPlacement?: never;
|
|
1716
|
+
footer?: never;
|
|
1717
|
+
footerList?: never;
|
|
1718
|
+
bottomToolbar?: never;
|
|
1719
|
+
footerPlacement?: never;
|
|
1720
|
+
pane?: never;
|
|
1721
|
+
}
|
|
1722
|
+
/** A collapsible Workbench side rail or bottom drawer. */
|
|
1723
|
+
type WorkbenchPanel = WorkbenchStaticPanel | WorkbenchNavigationPanel;
|
|
484
1724
|
interface WorkbenchProps {
|
|
1725
|
+
/**
|
|
1726
|
+
* The Workbench's `id`. Each panel's `id` derives from it —
|
|
1727
|
+
* `<id>-left-rail`, `<id>-right-rail`, `<id>-bottom-drawer` — so a toggle
|
|
1728
|
+
* can name the panel it shows and hides with `aria-controls`.
|
|
1729
|
+
*/
|
|
485
1730
|
id: string;
|
|
486
1731
|
label: string;
|
|
487
1732
|
/** The central work area. */
|
|
488
|
-
main:
|
|
1733
|
+
main: KerfUiContent;
|
|
1734
|
+
/**
|
|
1735
|
+
* The work area's top toolbar. A collapsed left rail's marked groups
|
|
1736
|
+
* and toggle lead it; a collapsed right rail's trail it. With it, `main`
|
|
1737
|
+
* renders in a `Pane` below the toolbar.
|
|
1738
|
+
*/
|
|
1739
|
+
mainToolbar?: WorkbenchMainToolbar;
|
|
1740
|
+
/**
|
|
1741
|
+
* Fixed content under `mainToolbar` — supporting copy such as a
|
|
1742
|
+
* description — divided from the scrolling `main` below it.
|
|
1743
|
+
*/
|
|
1744
|
+
mainHeader?: KerfUiContent;
|
|
1745
|
+
/**
|
|
1746
|
+
* Fixed content over `mainBottomToolbar` — a status line or a resource
|
|
1747
|
+
* toolbar — divided from the scrolling `main` above it.
|
|
1748
|
+
*/
|
|
1749
|
+
mainFooter?: KerfUiContent;
|
|
1750
|
+
/**
|
|
1751
|
+
* The work area's bottom toolbar. A collapsed drawer's marked groups and
|
|
1752
|
+
* toggle trail it; without it they float in the work area's corner.
|
|
1753
|
+
*/
|
|
1754
|
+
mainBottomToolbar?: WorkbenchMainBottomToolbar;
|
|
1755
|
+
/**
|
|
1756
|
+
* Whether `mainToolbar` and `mainHeader` stay pinned (`fixed`, default),
|
|
1757
|
+
* scroll away with `main` (`scroll`) — useful where large text would leave
|
|
1758
|
+
* pinned chrome little room — or stay pinned while the work area is tall
|
|
1759
|
+
* enough and scroll with `main` when it is short (`auto`).
|
|
1760
|
+
*/
|
|
1761
|
+
mainHeaderPlacement?: WorkbenchChromePlacement;
|
|
1762
|
+
/** The same for `mainFooter` and `mainBottomToolbar` (default `fixed`). */
|
|
1763
|
+
mainFooterPlacement?: WorkbenchChromePlacement;
|
|
1764
|
+
/**
|
|
1765
|
+
* Configuration for the work area's `Pane` (`contentElement`,
|
|
1766
|
+
* `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`), which it has whenever it
|
|
1767
|
+
* has a toolbar, `mainHeader`, or `mainFooter`; without that chrome, `main`
|
|
1768
|
+
* renders as given and this is ignored. Omitted or `undefined` fields keep
|
|
1769
|
+
* the `Pane` defaults.
|
|
1770
|
+
*/
|
|
1771
|
+
mainPane?: PaneConfig;
|
|
1772
|
+
/**
|
|
1773
|
+
* Configuration for the `List` that holds `mainHeader` (`gap`, `hAlign`,
|
|
1774
|
+
* `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Omitted or
|
|
1775
|
+
* `undefined` fields keep the defaults (no divider: the work area's
|
|
1776
|
+
* `Pane` draws the line under its header chrome).
|
|
1777
|
+
*/
|
|
1778
|
+
mainHeaderList?: ListConfig;
|
|
1779
|
+
/**
|
|
1780
|
+
* The same for the `List` that holds `mainFooter` (no divider by default:
|
|
1781
|
+
* the work area's `Pane` draws the line over its footer chrome).
|
|
1782
|
+
*/
|
|
1783
|
+
mainFooterList?: ListConfig;
|
|
489
1784
|
leftRail?: WorkbenchPanel;
|
|
490
1785
|
rightRail?: WorkbenchPanel;
|
|
491
1786
|
bottomDrawer?: WorkbenchPanel;
|
|
1787
|
+
/**
|
|
1788
|
+
* Minimum width, in px, the work area keeps beside the inline rails, fixed
|
|
1789
|
+
* or `resizable` (default 320; `0` turns it off). Resizing a rail stops
|
|
1790
|
+
* where the work area would drop below it, and inline rails shrink
|
|
1791
|
+
* proportionally when the Workbench gets narrower. Workbenches without a
|
|
1792
|
+
* rail ignore it.
|
|
1793
|
+
*/
|
|
1794
|
+
mainMinSize?: number;
|
|
1795
|
+
/**
|
|
1796
|
+
* Minimum height, in px, the work area keeps above an inline bottom drawer,
|
|
1797
|
+
* fixed or `resizable` (default 120; `0` turns it off) — the drawer's
|
|
1798
|
+
* counterpart of `mainMinSize`. Resizing the drawer stops where the work
|
|
1799
|
+
* area would drop below it, and the drawer shrinks when the Workbench gets
|
|
1800
|
+
* shorter. Workbenches without a drawer ignore it.
|
|
1801
|
+
*/
|
|
1802
|
+
mainMinHeight?: number;
|
|
1803
|
+
/** Dim the work area below any open overlay and absorb outside presses; off by default. */
|
|
1804
|
+
overlayBackdrop?: boolean;
|
|
1805
|
+
className?: string;
|
|
1806
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1807
|
+
slot?: string;
|
|
1808
|
+
}
|
|
1809
|
+
/**
|
|
1810
|
+
* The Xcode-like multi-panel workspace: a collapsible left rail, right rail, and
|
|
1811
|
+
* bottom drawer around a central work area (any absent). Collapsing snaps the
|
|
1812
|
+
* panel's track to zero in one reflow while its fixed-size content slides out via
|
|
1813
|
+
* a composited transform — the instant-width / sliding-content technique, so the
|
|
1814
|
+
* work area relayouts once, not per frame. Bottom-drawer content stays anchored
|
|
1815
|
+
* to the shell's stable bottom edge throughout that transition. The app owns
|
|
1816
|
+
* each `collapsed` flag; the collapse is pure CSS. A collapsed panel renders
|
|
1817
|
+
* `inert` and `aria-hidden`, so neither Tab nor assistive technology reaches
|
|
1818
|
+
* controls that have slid out of view or an empty landmark (its restore control
|
|
1819
|
+
* lives outside it and stays reachable). A panel may opt in to drag and keyboard resizing with
|
|
1820
|
+
* `resizable`, which `wireWorkbench` drives. See `docs/23-app-layouts.md` §3.3.
|
|
1821
|
+
*/
|
|
1822
|
+
declare function Workbench({ id, label, main, leftRail, rightRail, bottomDrawer, mainToolbar, mainHeader, mainFooter, mainBottomToolbar, mainHeaderPlacement, mainFooterPlacement, mainPane, mainHeaderList, mainFooterList, mainMinSize, mainMinHeight, overlayBackdrop, className, slot, }: WorkbenchProps): SafeHtml;
|
|
1823
|
+
|
|
1824
|
+
export { Workbench, type WorkbenchChromePlacement, type WorkbenchCompactOverlay, type WorkbenchMainBottomToolbar, type WorkbenchMainToolbar, type WorkbenchNavigationPanel, type WorkbenchPanel, type WorkbenchPanelBottomToolbar, type WorkbenchPanelResizable, type WorkbenchPanelToggle, type WorkbenchPanelToolbar, type WorkbenchProps, type WorkbenchResponsiveOverlayAt, type WorkbenchStaticPanel };
|
|
1825
|
+
```
|
|
1826
|
+
|
|
1827
|
+
## `@kerfjs/ui/wire-workbench`
|
|
1828
|
+
|
|
1829
|
+
```ts
|
|
1830
|
+
import { Signal, ReadonlySignal } from 'kerfjs';
|
|
1831
|
+
import { DeviceClass } from './device-class.js';
|
|
1832
|
+
|
|
1833
|
+
/** A Workbench panel slot, named after its `WorkbenchProps` prop. */
|
|
1834
|
+
type WorkbenchPanelKey = 'leftRail' | 'rightRail' | 'bottomDrawer';
|
|
1835
|
+
|
|
1836
|
+
/** Minimal `localStorage`-shaped store, so the persistence hook is testable. */
|
|
1837
|
+
interface WorkbenchStorage {
|
|
1838
|
+
getItem(key: string): string | null;
|
|
1839
|
+
setItem(key: string, value: string): void;
|
|
1840
|
+
}
|
|
1841
|
+
/** One Workbench panel's app-owned state. */
|
|
1842
|
+
interface WireWorkbenchPanel {
|
|
1843
|
+
/**
|
|
1844
|
+
* The app-owned size signal a `resizable` panel renders as its `size`.
|
|
1845
|
+
* `wireWorkbench` writes each committed resize here; collapsing never
|
|
1846
|
+
* touches it, so an expanded panel returns at the size it had. Omit it for
|
|
1847
|
+
* a panel that is not resizable.
|
|
1848
|
+
*/
|
|
1849
|
+
size?: Signal<number>;
|
|
1850
|
+
/**
|
|
1851
|
+
* When set with `size`, the size is loaded from and saved to `storage`
|
|
1852
|
+
* under this key, so the panel remembers the user's size.
|
|
1853
|
+
*/
|
|
1854
|
+
storageKey?: string;
|
|
1855
|
+
/**
|
|
1856
|
+
* The app-owned signal the panel renders as its `collapsed`. With it (and
|
|
1857
|
+
* `dismissOverlays`, on by default) `wireWorkbench` treats the panel as a
|
|
1858
|
+
* transient overlay while it presents as one: it collapses when its
|
|
1859
|
+
* `responsiveOverlayAt` breakpoint begins to apply and gets its inline state
|
|
1860
|
+
* back when the breakpoint stops applying, an open overlay takes focus and
|
|
1861
|
+
* keeps Tab inside it, and it closes on Escape or a press outside it.
|
|
1862
|
+
*/
|
|
1863
|
+
collapsed?: Signal<boolean>;
|
|
1864
|
+
/**
|
|
1865
|
+
* Treat presses in a portal surface launched by this panel (for example a
|
|
1866
|
+
* body-level menu or dialog) as inside it. The predicate receives each Node
|
|
1867
|
+
* in the press's composed path; return true for the portal root. Ordinary
|
|
1868
|
+
* presses outside the panel and its allowed surfaces still dismiss it.
|
|
1869
|
+
*/
|
|
1870
|
+
keepOpenOn?: (target: Node) => boolean;
|
|
1871
|
+
}
|
|
1872
|
+
/** A resize the user made, after `wireWorkbench` wrote it to the size signal. */
|
|
1873
|
+
interface WorkbenchResize {
|
|
1874
|
+
panel: WorkbenchPanelKey;
|
|
1875
|
+
size: number;
|
|
1876
|
+
source: 'keyboard' | 'pointer';
|
|
1877
|
+
}
|
|
1878
|
+
interface WireWorkbenchOptions {
|
|
1879
|
+
/** The `id` the `Workbench` was rendered with. */
|
|
1880
|
+
id: string;
|
|
1881
|
+
/**
|
|
1882
|
+
* The wired panels, keyed like the `Workbench` props. Render a panel given
|
|
1883
|
+
* a `size` with `resizable` and `size={panel.size.value}`, and one given a
|
|
1884
|
+
* `collapsed` signal with `collapsed={panel.collapsed.value}`.
|
|
1885
|
+
*/
|
|
1886
|
+
panels: Partial<Record<WorkbenchPanelKey, WireWorkbenchPanel>>;
|
|
1887
|
+
/**
|
|
1888
|
+
* When provided, resizing is suspended while `deviceClass.compact` is true —
|
|
1889
|
+
* the classes where rails become overlay drawers or are replaced.
|
|
1890
|
+
*/
|
|
1891
|
+
deviceClass?: ReadonlySignal<DeviceClass>;
|
|
1892
|
+
/** Persistence store (default `globalThis.localStorage`, if present). */
|
|
1893
|
+
storage?: WorkbenchStorage;
|
|
1894
|
+
/** Keyboard step in px (default 16). */
|
|
1895
|
+
step?: number;
|
|
1896
|
+
/** Shift+arrow step in px (default 64). */
|
|
1897
|
+
largeStep?: number;
|
|
1898
|
+
/** Called after each committed resize. */
|
|
1899
|
+
onResize?: (change: WorkbenchResize) => void;
|
|
1900
|
+
/**
|
|
1901
|
+
* Treat the panels given a `collapsed` signal as transient overlays while
|
|
1902
|
+
* they present as overlays (default `true`), like `wireSidebar`'s compact
|
|
1903
|
+
* overlay: a panel whose `responsiveOverlayAt` breakpoint begins to apply
|
|
1904
|
+
* starts collapsed, with no collapse motion, and gets its inline collapsed
|
|
1905
|
+
* state back when the breakpoint stops applying (and on disposal); an open
|
|
1906
|
+
* overlay panel, responsive or `presentation: "overlay"`, closes on Escape
|
|
1907
|
+
* or a press that starts and ends outside it. A panel that opens as an
|
|
1908
|
+
* overlay takes focus on its first focusable control, and while it is open
|
|
1909
|
+
* Tab and Shift+Tab cycle through its controls instead of reaching the
|
|
1910
|
+
* work area it covers (the ARIA dialog pattern of `wireSidebar`'s compact
|
|
1911
|
+
* overlay); inline panels never move focus. Focus stranded in a closing
|
|
1912
|
+
* panel — however it closed, the app's own control inside it included —
|
|
1913
|
+
* returns to the control that had it when the panel opened, else to the
|
|
1914
|
+
* panel's restore control, else to a control outside the panel whose
|
|
1915
|
+
* `aria-controls` names it (each panel's `id` is its region id, e.g.
|
|
1916
|
+
* `studio-left-rail`) — the fallback for a panel already open at wire-up.
|
|
1917
|
+
* An opener inside a panel that has closed since is skipped. `false` leaves
|
|
1918
|
+
* every `collapsed` write and all focus handling to the app.
|
|
1919
|
+
*/
|
|
1920
|
+
dismissOverlays?: boolean;
|
|
1921
|
+
/**
|
|
1922
|
+
* Keep overlays exclusive (default `true`), like `wireSidebar`'s
|
|
1923
|
+
* `exclusiveCompact`: when a panel opens while it presents as an overlay,
|
|
1924
|
+
* every other open overlay panel — rails and the bottom drawer alike —
|
|
1925
|
+
* closes, so one overlay never covers another's controls. Panels presenting
|
|
1926
|
+
* inline are never closed by it. Applies only with `dismissOverlays`.
|
|
1927
|
+
*/
|
|
1928
|
+
exclusiveOverlays?: boolean;
|
|
1929
|
+
}
|
|
1930
|
+
/**
|
|
1931
|
+
* Wire a `Workbench`'s panels. For `resizable` panels given a `size` signal:
|
|
1932
|
+
* pointer drags and arrow / Shift+arrow / Home / End on each panel's
|
|
1933
|
+
* separator, clamped to the panel's limits and to the room that leaves the
|
|
1934
|
+
* work area its minimum width and height, committed to the app-owned size signals.
|
|
1935
|
+
* Optional persistence loads and saves each size; optional `deviceClass`
|
|
1936
|
+
* suspends resizing on compact classes. Collapse stays the app's `collapsed`
|
|
1937
|
+
* flag and never changes a size. For panels given a `collapsed` signal,
|
|
1938
|
+
* overlays are transient (`dismissOverlays`): a responsive overlay starts
|
|
1939
|
+
* collapsed, an open overlay takes focus and keeps Tab inside it, it closes
|
|
1940
|
+
* on Escape or an outside press, and
|
|
1941
|
+
* opening one overlay closes the others (`exclusiveOverlays`). Returns a disposer. See `docs/23-app-layouts.md` §3.3.
|
|
1942
|
+
*/
|
|
1943
|
+
declare function wireWorkbench(root: HTMLElement, { id, panels, deviceClass, storage, step, largeStep, onResize, dismissOverlays, exclusiveOverlays, }: WireWorkbenchOptions): () => void;
|
|
1944
|
+
|
|
1945
|
+
export { type WireWorkbenchOptions, type WireWorkbenchPanel, type WorkbenchPanelKey, type WorkbenchResize, type WorkbenchStorage, wireWorkbench };
|
|
1946
|
+
```
|
|
1947
|
+
|
|
1948
|
+
## `@kerfjs/ui/collapsible-panel`
|
|
1949
|
+
|
|
1950
|
+
```ts
|
|
1951
|
+
import { SafeHtml } from 'kerfjs';
|
|
1952
|
+
import { ListConfig } from './list.js';
|
|
1953
|
+
import { PaneConfig } from './pane.js';
|
|
1954
|
+
import { P as PanelSide, a as PanelToolbar, b as PanelChromePlacement, c as PanelBottomToolbar, d as PanelToggle } from './panel-toolbar-DDKh4uKd.js';
|
|
1955
|
+
export { e as collapsiblePanelToggleIcon } from './panel-toolbar-DDKh4uKd.js';
|
|
1956
|
+
import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
|
|
1957
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
1958
|
+
import './css-values.js';
|
|
1959
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
1960
|
+
import './sides-BPSWde0A.js';
|
|
1961
|
+
import './lucide-icon.js';
|
|
1962
|
+
import 'lucide';
|
|
1963
|
+
import './toolbar.js';
|
|
1964
|
+
|
|
1965
|
+
/** Which edge a {@link CollapsiblePanel} docks to. */
|
|
1966
|
+
type CollapsiblePanelSide = PanelSide;
|
|
1967
|
+
/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */
|
|
1968
|
+
type CollapsiblePanelToolbarToggle = PanelToggle;
|
|
1969
|
+
/**
|
|
1970
|
+
* A panel's composed top toolbar. Its groups occupy `leading`, `center`, and
|
|
1971
|
+
* `trailing` while open; groups marked `relocateOnCollapse` and the standard
|
|
1972
|
+
* toggle move to the work-area toolbar through
|
|
1973
|
+
* {@link CollapsiblePanelRelocated} while it is collapsed.
|
|
1974
|
+
*/
|
|
1975
|
+
type CollapsiblePanelToolbar = PanelToolbar;
|
|
1976
|
+
type CollapsiblePanelBottomToolbar = PanelBottomToolbar;
|
|
1977
|
+
type CollapsiblePanelChromePlacement = PanelChromePlacement;
|
|
1978
|
+
interface CollapsiblePanelToggleProps {
|
|
1979
|
+
/** The panel this toggle controls. */
|
|
1980
|
+
side: CollapsiblePanelSide;
|
|
1981
|
+
/** The panel's current collapsed state (drives the icon direction). */
|
|
1982
|
+
collapsed: boolean;
|
|
1983
|
+
/** `data-action` the button carries so `wireSidebar` can delegate its click. */
|
|
1984
|
+
action: string;
|
|
1985
|
+
/** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */
|
|
1986
|
+
panelId?: string;
|
|
1987
|
+
/** Accessible label; defaults to "Collapse"/"Expand". */
|
|
1988
|
+
label?: string;
|
|
1989
|
+
className?: string;
|
|
1990
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
1991
|
+
slot?: string;
|
|
1992
|
+
}
|
|
1993
|
+
/**
|
|
1994
|
+
* A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the
|
|
1995
|
+
* recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the
|
|
1996
|
+
* `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —
|
|
1997
|
+
* put it in the panel's own header (to collapse) and somewhere always-visible
|
|
1998
|
+
* (to expand while collapsed).
|
|
1999
|
+
*/
|
|
2000
|
+
declare function CollapsiblePanelToggle({ side, collapsed, action, panelId, label, className, slot, }: CollapsiblePanelToggleProps): SafeHtml;
|
|
2001
|
+
interface CollapsiblePanelProps {
|
|
2002
|
+
/** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */
|
|
2003
|
+
id: string;
|
|
2004
|
+
/** Which edge the panel docks to: a left/right rail or a bottom drawer. */
|
|
2005
|
+
side: CollapsiblePanelSide;
|
|
2006
|
+
/** Whether the panel is currently collapsed (the app owns this signal). */
|
|
2007
|
+
collapsed?: boolean;
|
|
2008
|
+
/** Rail width or drawer height in px. Overrides the CSS default. */
|
|
2009
|
+
size?: number;
|
|
2010
|
+
/** Accessible label for the panel region. */
|
|
2011
|
+
label?: string;
|
|
2012
|
+
/** Panel content. */
|
|
2013
|
+
children?: KerfUiContent;
|
|
2014
|
+
/**
|
|
2015
|
+
* The panel's top toolbar, composed so its groups follow the panel's open
|
|
2016
|
+
* state. With it, `children` renders in a `Pane` below the toolbar; render
|
|
2017
|
+
* {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the
|
|
2018
|
+
* marked groups and toggle stay reachable while the panel is collapsed.
|
|
2019
|
+
*/
|
|
2020
|
+
toolbar?: CollapsiblePanelToolbar;
|
|
2021
|
+
/** Fixed content below a toolbar panel's top toolbar. */
|
|
2022
|
+
header?: KerfUiContent;
|
|
2023
|
+
headerList?: ListConfig;
|
|
2024
|
+
headerPlacement?: CollapsiblePanelChromePlacement;
|
|
2025
|
+
/** Fixed content above a toolbar panel's bottom toolbar. */
|
|
2026
|
+
footer?: KerfUiContent;
|
|
2027
|
+
footerList?: ListConfig;
|
|
2028
|
+
bottomToolbar?: CollapsiblePanelBottomToolbar;
|
|
2029
|
+
footerPlacement?: CollapsiblePanelChromePlacement;
|
|
2030
|
+
/**
|
|
2031
|
+
* Configuration for a `toolbar` panel's `Pane` (`contentElement`,
|
|
2032
|
+
* `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example
|
|
2033
|
+
* `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation
|
|
2034
|
+
* rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored
|
|
2035
|
+
* without a `toolbar`, where `children` renders as given.
|
|
2036
|
+
*/
|
|
2037
|
+
pane?: PaneConfig;
|
|
2038
|
+
separator?: ResizableRegionSeparator;
|
|
2039
|
+
collapseMotion?: ResizableRegionCollapseMotion;
|
|
2040
|
+
contentOverflow?: ResizableRegionContentOverflow;
|
|
2041
|
+
presentation?: ResizableRegionPresentation;
|
|
2042
|
+
/** Control shown while collapsed, in a safe-area-aware corner of the panel's container (not the viewport). */
|
|
2043
|
+
restoreControl?: SafeHtml;
|
|
2044
|
+
restorePosition?: ResizableRegionRestorePosition;
|
|
492
2045
|
className?: string;
|
|
493
2046
|
}
|
|
494
2047
|
/**
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
* panel's track to zero
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
* the
|
|
2048
|
+
* A standalone collapsible side rail or bottom drawer, outside the full
|
|
2049
|
+
* {@link Workbench} shell. It owns only the presentation: a fixed-size content
|
|
2050
|
+
* area that stays laid out while the panel's track snaps to zero and the content
|
|
2051
|
+
* slides out via `transform` (one reflow, composited — the same technique
|
|
2052
|
+
* `Workbench` and the catalog sidebar use). Bottom-drawer content stays anchored
|
|
2053
|
+
* to the panel's fixed bottom edge, so the track cannot move its layout origin
|
|
2054
|
+
* underneath the transform transition. A collapsed panel renders `inert` (with
|
|
2055
|
+
* `aria-hidden`), so neither Tab, pointer, nor assistive technology reaches
|
|
2056
|
+
* content that has slid out of view; its `restoreControl` renders outside the
|
|
2057
|
+
* panel and stays reachable.
|
|
2058
|
+
* The app owns the `collapsed` signal;
|
|
2059
|
+
* pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,
|
|
2060
|
+
* and persistence semantics, and with `CollapsiblePanelToggle` for the standard
|
|
2061
|
+
* affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.
|
|
2062
|
+
*/
|
|
2063
|
+
declare function CollapsiblePanel({ id, side, collapsed, size, label, children, toolbar, header, headerList, headerPlacement, footer, footerList, bottomToolbar, footerPlacement, pane, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, className, }: CollapsiblePanelProps): SafeHtml;
|
|
2064
|
+
interface CollapsiblePanelRelocatedProps {
|
|
2065
|
+
/** The panel's `id`. */
|
|
2066
|
+
panelId: string;
|
|
2067
|
+
side: CollapsiblePanelSide;
|
|
2068
|
+
/** The panel's current collapsed state. */
|
|
2069
|
+
collapsed: boolean;
|
|
2070
|
+
/** The same `toolbar` the panel receives. */
|
|
2071
|
+
toolbar: CollapsiblePanelToolbar;
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* A collapsed {@link CollapsiblePanel}'s marked groups and standard
|
|
2075
|
+
* toggle, for the app's work-area toolbar — nothing while the panel is open.
|
|
2076
|
+
* Put it first in the leading zone for a left rail, last in the trailing zone
|
|
2077
|
+
* for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`
|
|
2078
|
+
* `restoreControl`) for a bottom drawer. `wireSidebar` hands focus to it when
|
|
2079
|
+
* the panel closes from its own toggle.
|
|
2080
|
+
*/
|
|
2081
|
+
declare function CollapsiblePanelRelocated({ panelId, side, collapsed, toolbar, }: CollapsiblePanelRelocatedProps): SafeHtml;
|
|
2082
|
+
|
|
2083
|
+
export { CollapsiblePanel, type CollapsiblePanelBottomToolbar, type CollapsiblePanelChromePlacement, type CollapsiblePanelProps, CollapsiblePanelRelocated, type CollapsiblePanelRelocatedProps, type CollapsiblePanelSide, CollapsiblePanelToggle, type CollapsiblePanelToggleProps, type CollapsiblePanelToolbar, type CollapsiblePanelToolbarToggle };
|
|
2084
|
+
```
|
|
2085
|
+
|
|
2086
|
+
## `@kerfjs/ui/wire-sidebar`
|
|
2087
|
+
|
|
2088
|
+
```ts
|
|
2089
|
+
import { Signal, ReadonlySignal } from 'kerfjs';
|
|
2090
|
+
import { DeviceClass } from './device-class.js';
|
|
2091
|
+
|
|
2092
|
+
/** Minimal `localStorage`-shaped store, so the persistence hook is testable. */
|
|
2093
|
+
interface SidebarStorage {
|
|
2094
|
+
getItem(key: string): string | null;
|
|
2095
|
+
setItem(key: string, value: string): void;
|
|
2096
|
+
}
|
|
2097
|
+
interface WireSidebarPanel {
|
|
2098
|
+
/** The panel id — matches `CollapsiblePanel`'s `id` and a toggle's `panelId`. */
|
|
2099
|
+
id: string;
|
|
2100
|
+
/** The app-owned collapsed signal. `wireSidebar` reads it (focus, overlay) and
|
|
2101
|
+
* writes it (toggle, Escape, backdrop, persistence). */
|
|
2102
|
+
collapsed: Signal<boolean>;
|
|
2103
|
+
/** `data-action` value the panel's toggle button(s) carry. */
|
|
2104
|
+
toggleAction: string;
|
|
2105
|
+
/** When set, the panel's inline collapsed state is loaded from and saved to
|
|
2106
|
+
* `storage` under this key (a persistence hook), so the panel remembers the
|
|
2107
|
+
* user's inline choice. A compact overlay's open/closed state is transient
|
|
2108
|
+
* and is never persisted. */
|
|
2109
|
+
storageKey?: string;
|
|
2110
|
+
/** The panel's inline (non-compact) collapsed state when `storage` holds no
|
|
2111
|
+
* choice for it; wire-up seeds the signal with it. Defaults to the signal's
|
|
2112
|
+
* own value. Set it when the app seeds the signal from the device class
|
|
2113
|
+
* (`signal(device.value.compact)`) so a compact first render already starts
|
|
2114
|
+
* collapsed while a later crossing to a wide class still restores this
|
|
2115
|
+
* inline default. */
|
|
2116
|
+
inlineCollapsed?: boolean;
|
|
2117
|
+
}
|
|
2118
|
+
interface WireSidebarOptions {
|
|
2119
|
+
panels: readonly WireSidebarPanel[];
|
|
2120
|
+
/**
|
|
2121
|
+
* When provided, the sidebar adopts a compact **overlay** presentation while
|
|
2122
|
+
* `deviceClass.compact` is true: an open panel floats over the content with a
|
|
2123
|
+
* dismissable backdrop, Escape and backdrop-click collapse it, and focus is
|
|
2124
|
+
* trapped within the open panel (the ARIA dialog pattern). Without it the panel
|
|
2125
|
+
* is always inline.
|
|
2126
|
+
*
|
|
2127
|
+
* An overlay is transient and user-initiated: whenever the compact overlay
|
|
2128
|
+
* presentation begins (wire-up on a compact device, or a crossing from a wide
|
|
2129
|
+
* class), every panel starts collapsed so nothing blocks the page until the
|
|
2130
|
+
* user opens it. The inline state is remembered and restored when the device
|
|
2131
|
+
* crosses back to a wide class (and on disposal).
|
|
2132
|
+
*/
|
|
2133
|
+
deviceClass?: ReadonlySignal<DeviceClass>;
|
|
2134
|
+
/** Compact devices either overlay the panels (default) or hide them in favor
|
|
2135
|
+
* of an application-owned responsive replacement. */
|
|
2136
|
+
compactPresentation?: 'overlay' | 'hidden';
|
|
2137
|
+
/** Collapse the other panels when one opens in compact overlay mode. */
|
|
2138
|
+
exclusiveCompact?: boolean;
|
|
2139
|
+
/** Persistence store (default `globalThis.localStorage`, if present). */
|
|
2140
|
+
storage?: SidebarStorage;
|
|
2141
|
+
}
|
|
2142
|
+
/**
|
|
2143
|
+
* The reusable sidebar-semantics layer for {@link CollapsiblePanel}s: toggle
|
|
2144
|
+
* delegation with focus restore, focus-into on open, an optional compact overlay
|
|
2145
|
+
* (backdrop + Escape + focus trap) driven by {@link deviceClass}, and an optional
|
|
2146
|
+
* persistence hook. The app owns each `collapsed` signal and the layout; this wire
|
|
2147
|
+
* owns the interaction. Returns a disposer. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.
|
|
501
2148
|
*/
|
|
502
|
-
declare function
|
|
2149
|
+
declare function wireSidebar(root: HTMLElement, { panels, deviceClass, compactPresentation, exclusiveCompact, storage, }: WireSidebarOptions): () => void;
|
|
503
2150
|
|
|
504
|
-
export {
|
|
2151
|
+
export { type SidebarStorage, type WireSidebarOptions, type WireSidebarPanel, wireSidebar };
|
|
505
2152
|
```
|
|
506
2153
|
|
|
507
2154
|
## `@kerfjs/ui/tab-scaffold`
|
|
508
2155
|
|
|
509
2156
|
```ts
|
|
510
2157
|
import { SafeHtml } from 'kerfjs';
|
|
2158
|
+
import { PaneAppearance } from './pane.js';
|
|
2159
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
511
2160
|
|
|
512
|
-
interface
|
|
513
|
-
id:
|
|
2161
|
+
interface TabScaffoldTabBase<Id extends string> {
|
|
2162
|
+
id: Id;
|
|
514
2163
|
label: string;
|
|
515
2164
|
/** Decorative icon shown above the label in the bottom bar. */
|
|
516
2165
|
icon?: SafeHtml;
|
|
517
2166
|
/** The tab's content — typically a `NavStack` so each tab keeps its own stack. */
|
|
518
|
-
content:
|
|
2167
|
+
content: KerfUiContent;
|
|
2168
|
+
/** Background of this scene's scrolling work surface. */
|
|
2169
|
+
appearance?: PaneAppearance;
|
|
2170
|
+
}
|
|
2171
|
+
/** A tab with an optional count or short-status badge. */
|
|
2172
|
+
interface TabScaffoldTabCountBadge {
|
|
2173
|
+
/**
|
|
2174
|
+
* Optional count or short status shown as a solid danger `Badge` at the
|
|
2175
|
+
* top-trailing corner of the tab icon (the iOS tab-bar badge). Omitted, `''`,
|
|
2176
|
+
* or non-finite numbers render no badge. The visual badge is `aria-hidden`;
|
|
2177
|
+
* its meaning reaches assistive technology through `badgeLabel`.
|
|
2178
|
+
*
|
|
2179
|
+
* Pass `true` instead for the text-free dot (new content without a count).
|
|
2180
|
+
*/
|
|
2181
|
+
badge?: string | number;
|
|
2182
|
+
/**
|
|
2183
|
+
* Localized phrase folded into the tab's accessible name as
|
|
2184
|
+
* `"<label>, <badgeLabel>"` (for example `"3 unread"` → `"Inbox, 3 unread"`).
|
|
2185
|
+
* Defaults to the badge text itself. Ignored when no badge renders.
|
|
2186
|
+
*/
|
|
2187
|
+
badgeLabel?: string;
|
|
2188
|
+
}
|
|
2189
|
+
/** A tab with the text-free dot badge (new content without a count). */
|
|
2190
|
+
interface TabScaffoldTabDotBadge {
|
|
2191
|
+
/**
|
|
2192
|
+
* `true` shows a solid danger dot `Badge` at the top-trailing corner of the
|
|
2193
|
+
* tab icon — the iOS tab-bar dot for new content without a count.
|
|
2194
|
+
*/
|
|
2195
|
+
badge: true;
|
|
2196
|
+
/**
|
|
2197
|
+
* Required localized phrase folded into the tab's accessible name as
|
|
2198
|
+
* `"<label>, <badgeLabel>"` (for example `"New activity"` →
|
|
2199
|
+
* `"Feed, New activity"`). A dot has no text, so this is its only meaning.
|
|
2200
|
+
*/
|
|
2201
|
+
badgeLabel: string;
|
|
519
2202
|
}
|
|
520
|
-
|
|
2203
|
+
/** One bottom-bar destination: its label, optional icon and badge, and content. */
|
|
2204
|
+
type TabScaffoldTab<Id extends string = string> = TabScaffoldTabBase<Id> & (TabScaffoldTabCountBadge | TabScaffoldTabDotBadge);
|
|
2205
|
+
interface TabScaffoldProps<Id extends string = string> {
|
|
521
2206
|
id: string;
|
|
522
2207
|
/** Accessible name for the tab bar. */
|
|
523
2208
|
label: string;
|
|
524
|
-
tabs: TabScaffoldTab[];
|
|
2209
|
+
tabs: readonly TabScaffoldTab<Id>[];
|
|
525
2210
|
/** The controlled active tab id (the app owns selection). */
|
|
526
|
-
active:
|
|
2211
|
+
active: NoInfer<Id>;
|
|
2212
|
+
/**
|
|
2213
|
+
* The line over the tab bar, where it meets the active scene. `scroll`
|
|
2214
|
+
* (default) shows it only while more of the scene's content lies below —
|
|
2215
|
+
* never at the scroll end or when the content fits — once
|
|
2216
|
+
* `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above
|
|
2217
|
+
* the scaffold; unwired, it does not show. `always` shows it without the
|
|
2218
|
+
* wiring; `none` never, even when wired. The line is the bar's own 1px top
|
|
2219
|
+
* border, so no state moves the bar or a tab.
|
|
2220
|
+
*/
|
|
2221
|
+
chromeDividers?: 'scroll' | 'always' | 'none';
|
|
527
2222
|
className?: string;
|
|
2223
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2224
|
+
slot?: string;
|
|
528
2225
|
}
|
|
529
2226
|
/**
|
|
530
2227
|
* A mobile-first, iOS-like bottom tab scaffold: a bottom tab bar that switches
|
|
@@ -534,7 +2231,7 @@ interface TabScaffoldProps {
|
|
|
534
2231
|
* On larger classes, promote the tabs to a `Workbench` rail or sidebar instead of
|
|
535
2232
|
* a bottom bar. See `docs/23-app-layouts.md` §3.4.
|
|
536
2233
|
*/
|
|
537
|
-
declare function TabScaffold({ id, label, tabs, active, className }: TabScaffoldProps): SafeHtml;
|
|
2234
|
+
declare function TabScaffold<Id extends string>({ id, label, tabs, active, chromeDividers, className, slot, }: TabScaffoldProps<Id>): SafeHtml;
|
|
538
2235
|
|
|
539
2236
|
export { TabScaffold, type TabScaffoldProps, type TabScaffoldTab };
|
|
540
2237
|
```
|
|
@@ -559,9 +2256,17 @@ export { type WireTabScaffoldOptions, wireTabScaffold };
|
|
|
559
2256
|
|
|
560
2257
|
```ts
|
|
561
2258
|
import { SafeHtml } from 'kerfjs';
|
|
2259
|
+
import { CssLength } from './css-values.js';
|
|
2260
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
562
2261
|
|
|
563
2262
|
type ResizableRegionAxis = 'horizontal' | 'vertical';
|
|
564
2263
|
type ResizableRegionEdge = 'start' | 'end';
|
|
2264
|
+
type ResizableRegionSeparator = 'auto' | 'hidden';
|
|
2265
|
+
type ResizableRegionCollapseMotion = 'none' | 'slide' | 'fade-slide';
|
|
2266
|
+
type ResizableRegionContentOverflow = 'clip' | 'auto' | 'visible';
|
|
2267
|
+
type ResizableRegionPresentation = 'inline' | 'overlay' | 'hidden';
|
|
2268
|
+
type ResizableRegionRestorePosition = 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
|
|
2269
|
+
type ResizableRegionResponsiveFillAt = 'compact' | 'narrow';
|
|
565
2270
|
interface ResizableRegionProps {
|
|
566
2271
|
id: string;
|
|
567
2272
|
label: string;
|
|
@@ -570,17 +2275,38 @@ interface ResizableRegionProps {
|
|
|
570
2275
|
max: number;
|
|
571
2276
|
axis?: ResizableRegionAxis;
|
|
572
2277
|
edge?: ResizableRegionEdge;
|
|
2278
|
+
/** Snap the track to zero. The region renders `inert` and `aria-hidden`
|
|
2279
|
+
* while collapsed, so neither Tab nor assistive technology reaches it or
|
|
2280
|
+
* lands on an empty landmark; `restoreControl` renders outside the region. */
|
|
573
2281
|
collapsed?: boolean;
|
|
574
2282
|
transitioning?: boolean;
|
|
2283
|
+
/** Whether the separator line is painted. The resize hit target remains available. */
|
|
2284
|
+
separator?: ResizableRegionSeparator;
|
|
2285
|
+
/** Keep the track change instant while optionally sliding the fixed-size content. */
|
|
2286
|
+
collapseMotion?: ResizableRegionCollapseMotion;
|
|
2287
|
+
/** Use `visible` while an anchored popup must escape the content box; it raises the region to the popup layer. */
|
|
2288
|
+
contentOverflow?: ResizableRegionContentOverflow;
|
|
2289
|
+
/** Inline layout, an edge overlay, or a responsive replacement that removes the region. */
|
|
2290
|
+
presentation?: ResizableRegionPresentation;
|
|
2291
|
+
/** Always-available control rendered while collapsed, outside the clipped region. */
|
|
2292
|
+
restoreControl?: SafeHtml;
|
|
2293
|
+
/** Safe-area-aware corner of the region's container (not the viewport) for `restoreControl`. */
|
|
2294
|
+
restorePosition?: ResizableRegionRestorePosition;
|
|
2295
|
+
/** Position a restore control in its container corner or leave it in normal flow. */
|
|
2296
|
+
restorePlacement?: 'corner' | 'inline';
|
|
2297
|
+
/** Corner distance before the container's safe-area inset. */
|
|
2298
|
+
restoreInset?: CssLength;
|
|
2299
|
+
/** Fill the available inline track and hide the separator below a container breakpoint. */
|
|
2300
|
+
responsiveFillAt?: ResizableRegionResponsiveFillAt;
|
|
575
2301
|
/** Decorative dormant content for the separator handle. Must not contain interactive descendants. */
|
|
576
2302
|
handleIcon?: SafeHtml;
|
|
577
|
-
children:
|
|
2303
|
+
children: KerfUiContent;
|
|
578
2304
|
}
|
|
579
2305
|
declare const clampRegionSize: (size: number, min: number, max: number) => number;
|
|
580
2306
|
declare const resizeRegionFromPointer: (startSize: number, delta: number, edge: ResizableRegionEdge) => number;
|
|
581
|
-
declare function ResizableRegion({ id, label, size, min, max, axis, edge, collapsed, transitioning, handleIcon, children }: ResizableRegionProps): SafeHtml;
|
|
2307
|
+
declare function ResizableRegion({ id, label, size, min, max, axis, edge, collapsed, transitioning, separator, collapseMotion, contentOverflow, presentation, restoreControl, restorePosition, restorePlacement, restoreInset, responsiveFillAt, handleIcon, children, }: ResizableRegionProps): SafeHtml;
|
|
582
2308
|
|
|
583
|
-
export { ResizableRegion, type ResizableRegionAxis, type ResizableRegionEdge, type ResizableRegionProps, clampRegionSize, resizeRegionFromPointer };
|
|
2309
|
+
export { ResizableRegion, type ResizableRegionAxis, type ResizableRegionCollapseMotion, type ResizableRegionContentOverflow, type ResizableRegionEdge, type ResizableRegionPresentation, type ResizableRegionProps, type ResizableRegionResponsiveFillAt, type ResizableRegionRestorePosition, type ResizableRegionSeparator, clampRegionSize, resizeRegionFromPointer };
|
|
584
2310
|
```
|
|
585
2311
|
|
|
586
2312
|
## `@kerfjs/ui/wire-resizable-regions`
|
|
@@ -597,8 +2323,9 @@ interface WireResizableRegionsOptions {
|
|
|
597
2323
|
onPreview?: (change: ResizeCommit) => void;
|
|
598
2324
|
onCommit: (change: ResizeCommit) => void;
|
|
599
2325
|
}
|
|
2326
|
+
|
|
600
2327
|
/** Wire pointer and separator-keyboard behavior for every ResizableRegion below root. */
|
|
601
|
-
declare function wireResizableRegions(root: HTMLElement,
|
|
2328
|
+
declare function wireResizableRegions(root: HTMLElement, options: WireResizableRegionsOptions): () => void;
|
|
602
2329
|
|
|
603
2330
|
export { type ResizeCommit, type WireResizableRegionsOptions, wireResizableRegions };
|
|
604
2331
|
```
|
|
@@ -670,77 +2397,462 @@ declare function deviceClass(options?: DeviceClassOptions): ReadonlySignal<Devic
|
|
|
670
2397
|
export { DEFAULT_BREAKPOINTS, type DeviceBreakpoints, type DeviceClass, type DeviceClassOptions, type DeviceOrientation, type DeviceSize, type Viewport, classifyViewport, deviceClass };
|
|
671
2398
|
```
|
|
672
2399
|
|
|
673
|
-
## `@kerfjs/ui/
|
|
2400
|
+
## `@kerfjs/ui/catalog`
|
|
674
2401
|
|
|
675
2402
|
```ts
|
|
2403
|
+
import * as kerfjs from 'kerfjs';
|
|
676
2404
|
import { SafeHtml } from 'kerfjs';
|
|
2405
|
+
import { a as CatalogProps } from './types-BuHELdXR.js';
|
|
2406
|
+
export { b as CatalogBrand, c as CatalogEntry, d as CatalogRelated, C as CatalogResource, e as CatalogSecondaryGroup, f as CatalogSection, g as CatalogStageRootAttributes } from './types-BuHELdXR.js';
|
|
2407
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
2408
|
+
import './toolbar.js';
|
|
2409
|
+
import './pane.js';
|
|
2410
|
+
import './sides-BPSWde0A.js';
|
|
2411
|
+
import './workbench.js';
|
|
2412
|
+
import './list.js';
|
|
2413
|
+
import './css-values.js';
|
|
2414
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
2415
|
+
import './nav-stack.js';
|
|
2416
|
+
import './toolbar-text.js';
|
|
2417
|
+
import './resizable-region.js';
|
|
2418
|
+
import './panel-toolbar-DDKh4uKd.js';
|
|
2419
|
+
import './lucide-icon.js';
|
|
2420
|
+
import 'lucide';
|
|
2421
|
+
|
|
2422
|
+
/**
|
|
2423
|
+
* Controlled, stateless component-catalog shell: a `Workbench` whose left rail
|
|
2424
|
+
* is the catalog navigation and whose work area is the active entry — its
|
|
2425
|
+
* toolbar, description, preview stage, and resource footer. The sidebar's
|
|
2426
|
+
* standard toggle moves into the entry toolbar while it is collapsed, and on
|
|
2427
|
+
* a small screen the sidebar overlays the stage like any Workbench rail.
|
|
2428
|
+
*/
|
|
2429
|
+
declare function Catalog({ id, brand, sections, active, content, collapsed, theme, headerActions, secondarySections, sidebarFooter, status, geometryOverlay, stageRootAttributes, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, headerPlacement, footerPlacement, sidebar, mainToolbar, footerToolbar, className, slot, }: CatalogProps): kerfjs.SafeHtml;
|
|
2430
|
+
|
|
2431
|
+
/** How a specimen aligns its visible edge with its `ListHeader` label. */
|
|
2432
|
+
type CatalogExampleAlign = 'glyph' | 'inline-control' | 'text-trigger' | 'none';
|
|
2433
|
+
interface CatalogExampleViewport {
|
|
2434
|
+
layout?: 'grid' | 'flex' | 'flex-column';
|
|
2435
|
+
width?: 'full' | 'compact' | 'medium' | 'wide' | 'text' | 'control';
|
|
2436
|
+
/** Fixed specimen height; `app` frames an application-sized recipe or layout.
|
|
2437
|
+
* A fixed height is definite, so a child that fills with `height: 100%`
|
|
2438
|
+
* (a horizontal `ResizableRegion`, say) spans the whole frame. */
|
|
2439
|
+
height?: 'short' | 'reduced' | 'medium' | 'tall' | 'app';
|
|
2440
|
+
/** A minimum the frame may grow past. It is not a definite height: a child
|
|
2441
|
+
* sized with `height: 100%` falls back to its content height, so use
|
|
2442
|
+
* `height` when the specimen must fill the frame. */
|
|
2443
|
+
minHeight?: 'short' | 'medium';
|
|
2444
|
+
frame?: 'solid' | 'dashed';
|
|
2445
|
+
surface?: 'default' | 'lowered';
|
|
2446
|
+
overflow?: 'hidden' | 'auto-x';
|
|
2447
|
+
responsive?: 'roomy-only';
|
|
2448
|
+
shadow?: boolean;
|
|
2449
|
+
/** Public component custom properties applied to the specimen viewport. */
|
|
2450
|
+
tokens?: Readonly<Record<`--${string}`, string>>;
|
|
2451
|
+
}
|
|
2452
|
+
type CatalogExampleRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
2453
|
+
'data-catalog-example'?: never;
|
|
2454
|
+
'data-catalog-example-stack'?: never;
|
|
2455
|
+
'data-catalog-example-label'?: never;
|
|
2456
|
+
'data-catalog-example-note'?: never;
|
|
2457
|
+
'data-align'?: never;
|
|
2458
|
+
}>;
|
|
2459
|
+
interface CatalogExampleProps {
|
|
2460
|
+
label?: string;
|
|
2461
|
+
note?: SafeHtml | string;
|
|
2462
|
+
align?: CatalogExampleAlign;
|
|
2463
|
+
/** Optional catalog-owned constraints for demonstrating layout components. */
|
|
2464
|
+
viewport?: CatalogExampleViewport;
|
|
2465
|
+
/** Replacement guidance shown when a roomy-only viewport is hidden. */
|
|
2466
|
+
compactFallback?: SafeHtml | string;
|
|
2467
|
+
rootAttributes?: CatalogExampleRootAttributes;
|
|
2468
|
+
className?: string;
|
|
2469
|
+
children?: KerfUiContent;
|
|
2470
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2471
|
+
slot?: string;
|
|
2472
|
+
}
|
|
2473
|
+
/** A labeled catalog specimen with optional explanatory text and alignment. */
|
|
2474
|
+
declare function CatalogExample({ label, note, align, viewport, compactFallback, rootAttributes, className, children, slot, }: CatalogExampleProps): SafeHtml;
|
|
2475
|
+
|
|
2476
|
+
type CatalogExampleStackRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
2477
|
+
'data-catalog-example'?: never;
|
|
2478
|
+
'data-catalog-example-stack'?: never;
|
|
2479
|
+
'data-catalog-example-label'?: never;
|
|
2480
|
+
'data-catalog-example-note'?: never;
|
|
2481
|
+
'data-align'?: never;
|
|
2482
|
+
}>;
|
|
2483
|
+
interface CatalogExampleStackProps {
|
|
2484
|
+
label?: string;
|
|
2485
|
+
rootAttributes?: CatalogExampleStackRootAttributes;
|
|
2486
|
+
className?: string;
|
|
2487
|
+
children?: KerfUiContent;
|
|
2488
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2489
|
+
slot?: string;
|
|
2490
|
+
}
|
|
2491
|
+
/** A vertically stacked group of catalog examples. */
|
|
2492
|
+
declare function CatalogExampleStack({ label, rootAttributes, className, children, slot, }: CatalogExampleStackProps): kerfjs.SafeHtml;
|
|
2493
|
+
|
|
2494
|
+
export { Catalog, CatalogExample, type CatalogExampleAlign, type CatalogExampleProps, CatalogExampleStack, type CatalogExampleStackProps, type CatalogExampleViewport, CatalogProps };
|
|
2495
|
+
```
|
|
2496
|
+
|
|
2497
|
+
## `@kerfjs/ui/catalog-resources`
|
|
2498
|
+
|
|
2499
|
+
```ts
|
|
2500
|
+
import { C as CatalogResource } from './types-BuHELdXR.js';
|
|
2501
|
+
import './semantic-content-BbzjvSu9.js';
|
|
2502
|
+
import 'kerfjs';
|
|
2503
|
+
import './toolbar.js';
|
|
2504
|
+
import './pane.js';
|
|
2505
|
+
import './sides-BPSWde0A.js';
|
|
2506
|
+
import './workbench.js';
|
|
2507
|
+
import './list.js';
|
|
2508
|
+
import './css-values.js';
|
|
2509
|
+
import './flex-alignment-4ms8ZbV8.js';
|
|
2510
|
+
import './nav-stack.js';
|
|
2511
|
+
import './toolbar-text.js';
|
|
2512
|
+
import './resizable-region.js';
|
|
2513
|
+
import './panel-toolbar-DDKh4uKd.js';
|
|
2514
|
+
import './lucide-icon.js';
|
|
2515
|
+
import 'lucide';
|
|
2516
|
+
|
|
2517
|
+
/**
|
|
2518
|
+
* Standard resource labels for a Kerf catalog detail footer. Keep these labels
|
|
2519
|
+
* stable across catalogs so people and AI-generated integrations see the same
|
|
2520
|
+
* choices in the same vocabulary.
|
|
2521
|
+
*/
|
|
2522
|
+
type CatalogResourceKind = 'demoSource' | 'componentSource' | 'designTemplate' | 'guidance' | 'integrationGuidance';
|
|
2523
|
+
type CatalogGuidanceKind = 'guidance' | 'integrationGuidance';
|
|
2524
|
+
interface CatalogResourceTarget {
|
|
2525
|
+
href: string;
|
|
2526
|
+
/** Optional monospace detail, normally the repository-relative source path. */
|
|
2527
|
+
detail?: string;
|
|
2528
|
+
}
|
|
2529
|
+
interface CatalogResourcesInput {
|
|
2530
|
+
/** Required source for the runnable demonstration. */
|
|
2531
|
+
demoSource: CatalogResourceTarget;
|
|
2532
|
+
/** Source for the production component; omit for recipes and integrations. */
|
|
2533
|
+
componentSource?: CatalogResourceTarget;
|
|
2534
|
+
/** Optional design-tool template associated with the component. */
|
|
2535
|
+
designTemplate?: CatalogResourceTarget;
|
|
2536
|
+
/** Required UI or integration guidance. */
|
|
2537
|
+
guidance: CatalogResourceTarget;
|
|
2538
|
+
/** Use `integrationGuidance` when the component implementation is upstream. */
|
|
2539
|
+
guidanceKind?: CatalogGuidanceKind;
|
|
2540
|
+
}
|
|
2541
|
+
/**
|
|
2542
|
+
* Build the standard catalog resource group in its canonical order: demo,
|
|
2543
|
+
* component, optional design template, then guidance.
|
|
2544
|
+
*/
|
|
2545
|
+
declare function catalogResources(input: CatalogResourcesInput): CatalogResource[];
|
|
2546
|
+
|
|
2547
|
+
export { type CatalogGuidanceKind, type CatalogResourceKind, type CatalogResourceTarget, type CatalogResourcesInput, catalogResources };
|
|
2548
|
+
```
|
|
2549
|
+
|
|
2550
|
+
## `@kerfjs/ui/wire-catalog`
|
|
2551
|
+
|
|
2552
|
+
```ts
|
|
2553
|
+
import { Signal } from 'kerfjs';
|
|
2554
|
+
|
|
2555
|
+
interface WireCatalogOptions {
|
|
2556
|
+
/** Invoked with the entry id when a sidebar item or a related-entry option is chosen. */
|
|
2557
|
+
onSelect: (id: string) => void;
|
|
2558
|
+
/** Invoked when the sidebar collapse/expand control is activated. */
|
|
2559
|
+
onToggleSidebar?: () => void;
|
|
2560
|
+
/** Invoked when the theme toggle is activated. */
|
|
2561
|
+
onToggleTheme?: () => void;
|
|
2562
|
+
/** Invoked when the secondary (ecosystem) group's disclosure toggle is activated. */
|
|
2563
|
+
onToggleSecondary?: () => void;
|
|
2564
|
+
/** When set, `?<urlParam>=<id>` is written on select via `history.replaceState`. */
|
|
2565
|
+
urlParam?: string;
|
|
2566
|
+
/**
|
|
2567
|
+
* Reveal the chosen sidebar row after selection. `true` uses desktop-safe
|
|
2568
|
+
* defaults; pass options to customize scroll alignment or the media guard.
|
|
2569
|
+
*/
|
|
2570
|
+
revealSelection?: boolean | CatalogRevealOptions;
|
|
2571
|
+
selectAction?: string;
|
|
2572
|
+
toggleSidebarAction?: string;
|
|
2573
|
+
toggleThemeAction?: string;
|
|
2574
|
+
toggleSecondaryAction?: string;
|
|
2575
|
+
/**
|
|
2576
|
+
* The sidebar's app-owned collapsed flag. With it, the catalog's Workbench
|
|
2577
|
+
* sidebar is wired like any Workbench rail: it becomes a transient overlay
|
|
2578
|
+
* on a small screen (collapsed as the breakpoint applies, closed on Escape
|
|
2579
|
+
* or a press outside, focus handed back), and choosing an entry from the
|
|
2580
|
+
* open overlay closes it.
|
|
2581
|
+
*/
|
|
2582
|
+
collapsed?: Signal<boolean>;
|
|
2583
|
+
/**
|
|
2584
|
+
* The app-owned sidebar width signal for a Catalog rendered with
|
|
2585
|
+
* `sidebar={{ resizable: true, size: sidebarSize.value }}`. Each committed
|
|
2586
|
+
* drag or keyboard resize is written to it.
|
|
2587
|
+
*/
|
|
2588
|
+
sidebarSize?: Signal<number>;
|
|
2589
|
+
/**
|
|
2590
|
+
* With `sidebarSize`, load and save the width under this storage key so the
|
|
2591
|
+
* catalog remembers the user's sidebar width.
|
|
2592
|
+
*/
|
|
2593
|
+
sidebarStorageKey?: string;
|
|
2594
|
+
/** The Catalog's `id`, when it is not the default `kui-catalog`. */
|
|
2595
|
+
id?: string;
|
|
2596
|
+
}
|
|
2597
|
+
interface CatalogRevealOptions {
|
|
2598
|
+
/** Scroll alignment within the sidebar. Default `'nearest'`. */
|
|
2599
|
+
block?: ScrollLogicalPosition;
|
|
2600
|
+
/** Cross-axis alignment. Default `'nearest'`. */
|
|
2601
|
+
inline?: ScrollLogicalPosition;
|
|
2602
|
+
/** Scroll behavior. Default `'auto'`. */
|
|
2603
|
+
behavior?: ScrollBehavior;
|
|
2604
|
+
/**
|
|
2605
|
+
* Only reveal when this media query matches. Defaults to the Catalog's
|
|
2606
|
+
* desktop layout; pass `false` to reveal at every viewport size.
|
|
2607
|
+
*/
|
|
2608
|
+
media?: string | false;
|
|
2609
|
+
}
|
|
2610
|
+
/**
|
|
2611
|
+
* Reveal one Catalog sidebar entry after the controlled render settles without
|
|
2612
|
+
* moving focus. Returns a cancellation function for rapid selection changes.
|
|
2613
|
+
*/
|
|
2614
|
+
declare function revealCatalogEntry(root: HTMLElement, id: string, { block, inline, behavior, media, }?: CatalogRevealOptions): () => void;
|
|
2615
|
+
/**
|
|
2616
|
+
* Keep a Catalog's opt-in geometry overlay synchronized with its preview.
|
|
2617
|
+
* Specimens receive computed border highlights (or a dashed bound when they
|
|
2618
|
+
* have no border and are transparent), while positive computed margins use
|
|
2619
|
+
* devtools-style orange bands. CSS/stylesheet-only changes are observed too.
|
|
2620
|
+
* Returns a disposer.
|
|
2621
|
+
*/
|
|
2622
|
+
declare function wireCatalogGeometryOverlay(root: HTMLElement): () => void;
|
|
2623
|
+
/**
|
|
2624
|
+
* Wire a {@link Catalog}'s interactions with one delegated listener set: sidebar
|
|
2625
|
+
* item selection (and the related-entry popup menu), the sidebar collapse toggle, and
|
|
2626
|
+
* the theme toggle. The app owns the `active`/`collapsed`/`theme` signals and updates
|
|
2627
|
+
* them in the callbacks; optionally mirror the active id into the URL via `urlParam`.
|
|
2628
|
+
* It also wires the scroll dividers below root (`wireScrollDividers`), so the
|
|
2629
|
+
* catalog's panes and every example in it show their chrome dividers only
|
|
2630
|
+
* while scrolled. Returns a disposer.
|
|
2631
|
+
*/
|
|
2632
|
+
declare function wireCatalog(root: HTMLElement, { onSelect, onToggleSidebar, onToggleTheme, onToggleSecondary, urlParam, revealSelection, selectAction, toggleSidebarAction, toggleThemeAction, toggleSecondaryAction, collapsed, sidebarSize, sidebarStorageKey, id: catalogId, }: WireCatalogOptions): () => void;
|
|
2633
|
+
|
|
2634
|
+
export { type CatalogRevealOptions, type WireCatalogOptions, revealCatalogEntry, wireCatalog, wireCatalogGeometryOverlay };
|
|
2635
|
+
```
|
|
2636
|
+
|
|
2637
|
+
## `@kerfjs/ui/segmented-control`
|
|
2638
|
+
|
|
2639
|
+
```ts
|
|
2640
|
+
import * as kerfjs from 'kerfjs';
|
|
2641
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
677
2642
|
|
|
678
2643
|
type SegmentedControlAppearance = 'filled' | 'outlined' | 'toolbar';
|
|
679
2644
|
type SegmentedControlShape = 'rounded' | 'pill';
|
|
680
2645
|
type SegmentedControlSize = 'small' | 'default';
|
|
681
2646
|
type SegmentedControlLayout = 'content' | 'equal';
|
|
682
|
-
interface SegmentedControlChoice {
|
|
683
|
-
value:
|
|
2647
|
+
interface SegmentedControlChoice<Value extends string = string> {
|
|
2648
|
+
value: Value;
|
|
684
2649
|
label: string;
|
|
685
|
-
content?:
|
|
2650
|
+
content?: KerfUiContent;
|
|
686
2651
|
title?: string;
|
|
687
2652
|
disabled?: boolean;
|
|
688
2653
|
}
|
|
689
|
-
interface SegmentedControlProps {
|
|
2654
|
+
interface SegmentedControlProps<Value extends string = string> {
|
|
690
2655
|
id: string;
|
|
691
2656
|
label: string;
|
|
692
|
-
value:
|
|
693
|
-
choices: readonly SegmentedControlChoice[];
|
|
2657
|
+
value: NoInfer<Value>;
|
|
2658
|
+
choices: readonly SegmentedControlChoice<Value>[];
|
|
694
2659
|
action?: string;
|
|
695
2660
|
appearance?: SegmentedControlAppearance;
|
|
696
2661
|
shape?: SegmentedControlShape;
|
|
697
2662
|
size?: SegmentedControlSize;
|
|
698
2663
|
layout?: SegmentedControlLayout;
|
|
699
2664
|
className?: string;
|
|
700
|
-
/** Render as
|
|
2665
|
+
/** Render as a loading placeholder: every choice keeps its live label or icon, none is selected, and every segment is disabled. */
|
|
701
2666
|
placeholder?: boolean;
|
|
2667
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2668
|
+
slot?: string;
|
|
702
2669
|
}
|
|
703
|
-
declare function SegmentedControl({ id, label, value, choices, action, appearance, shape, size, layout, className, placeholder, }: SegmentedControlProps): SafeHtml;
|
|
2670
|
+
declare function SegmentedControl<Value extends string>({ id, label, value, choices, action, appearance, shape, size, layout, className, placeholder, slot, }: SegmentedControlProps<Value>): kerfjs.SafeHtml;
|
|
704
2671
|
|
|
705
2672
|
export { SegmentedControl, type SegmentedControlAppearance, type SegmentedControlChoice, type SegmentedControlLayout, type SegmentedControlProps, type SegmentedControlShape, type SegmentedControlSize };
|
|
706
2673
|
```
|
|
707
2674
|
|
|
2675
|
+
## `@kerfjs/ui/select`
|
|
2676
|
+
|
|
2677
|
+
```ts
|
|
2678
|
+
import { SafeHtml } from 'kerfjs';
|
|
2679
|
+
import { CssForegroundColor } from './css-values.js';
|
|
2680
|
+
import { LucideNode } from './lucide-icon.js';
|
|
2681
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
2682
|
+
import 'lucide';
|
|
2683
|
+
|
|
2684
|
+
interface SelectChoice<Value extends string = string> {
|
|
2685
|
+
value: Value;
|
|
2686
|
+
label: string;
|
|
2687
|
+
icon?: LucideNode;
|
|
2688
|
+
iconName?: string;
|
|
2689
|
+
/**
|
|
2690
|
+
* Foreground color for the optional icon: a semantic foreground token such
|
|
2691
|
+
* as `uiColor('success-on-quiet')`, or an application-owned
|
|
2692
|
+
* `foregroundColorVar('--app-icon-color')`. Fill tokens such as
|
|
2693
|
+
* `uiColor('success-fill-quiet')` are pale background tints and do not
|
|
2694
|
+
* type-check.
|
|
2695
|
+
*/
|
|
2696
|
+
color?: CssForegroundColor;
|
|
2697
|
+
group?: string;
|
|
2698
|
+
/** Keep an unavailable choice visible but prevent selection. */
|
|
2699
|
+
disabled?: boolean;
|
|
2700
|
+
/** Optional explanation exposed as the disabled option's native tooltip. */
|
|
2701
|
+
disabledReason?: string;
|
|
2702
|
+
/**
|
|
2703
|
+
* Draw a divider between this choice and the previous choice in the same
|
|
2704
|
+
* list. A group boundary is already a separator, so the first choice of a
|
|
2705
|
+
* group (or of the whole menu) never draws a second one.
|
|
2706
|
+
*/
|
|
2707
|
+
separatorBefore?: boolean;
|
|
2708
|
+
}
|
|
2709
|
+
type SelectAccessibleName = {
|
|
2710
|
+
label: string;
|
|
2711
|
+
ariaLabel?: string;
|
|
2712
|
+
} | {
|
|
2713
|
+
label?: never;
|
|
2714
|
+
ariaLabel: string;
|
|
2715
|
+
};
|
|
2716
|
+
type SelectPresentation = 'form' | 'toolbar-borderless' | 'navigation' | 'inline' | 'title';
|
|
2717
|
+
type SelectSize = 'default' | 'compact';
|
|
2718
|
+
type SelectSelectedPresentation = 'label' | 'icon-only';
|
|
2719
|
+
type SelectFocusRingOwner = 'select' | 'group';
|
|
2720
|
+
type SelectTriggerWidth = 'fit-content' | 'max-content' | 'fill';
|
|
2721
|
+
interface SelectBaseProps<Value extends string = string> {
|
|
2722
|
+
name: string;
|
|
2723
|
+
choices: readonly SelectChoice<Value>[];
|
|
2724
|
+
className?: string;
|
|
2725
|
+
/** Empty-value hint text shown in the closed control (the native select placeholder). */
|
|
2726
|
+
placeholderText?: string;
|
|
2727
|
+
/** Supporting text shown below the control and associated with its combobox. */
|
|
2728
|
+
hint?: string;
|
|
2729
|
+
disabled?: boolean;
|
|
2730
|
+
fitMenu?: boolean;
|
|
2731
|
+
/** Render as an unanimated loading skeleton: the label above a static, empty control box. */
|
|
2732
|
+
placeholder?: boolean;
|
|
2733
|
+
/** Form (default), borderless toolbar, intrinsic navigation, inline, or view-title chrome. */
|
|
2734
|
+
presentation?: SelectPresentation;
|
|
2735
|
+
size?: SelectSize;
|
|
2736
|
+
/** Closed trigger width; omit to keep the presentation's default. */
|
|
2737
|
+
triggerWidth?: SelectTriggerWidth;
|
|
2738
|
+
/** Show the disclosure caret (default); omit it for a compact icon-only trigger. */
|
|
2739
|
+
caret?: boolean;
|
|
2740
|
+
/** Let an enclosing ToolbarControlGroup paint the composed focus ring. */
|
|
2741
|
+
focusRingOwner?: SelectFocusRingOwner;
|
|
2742
|
+
/** Keep the trigger's focus ring inside its box when an ancestor clips overflow. */
|
|
2743
|
+
focusRingInset?: boolean;
|
|
2744
|
+
/** Maximum closed-control label width in CSS pixels before ellipsis. */
|
|
2745
|
+
labelMaxWidth?: number;
|
|
2746
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2747
|
+
slot?: string;
|
|
2748
|
+
}
|
|
2749
|
+
/** One chosen value (the default). */
|
|
2750
|
+
interface SelectSingleValueProps<Value extends string = string> {
|
|
2751
|
+
multiple?: false;
|
|
2752
|
+
value: NoInfer<Value>;
|
|
2753
|
+
renderSelected?: (choice: SelectChoice<Value>) => SafeHtml;
|
|
2754
|
+
/** Show only the selected choice icon while retaining the Select's accessible name. */
|
|
2755
|
+
selectedPresentation?: SelectSelectedPresentation;
|
|
2756
|
+
triggerIcon?: never;
|
|
2757
|
+
selectAllLabel?: never;
|
|
2758
|
+
clearLabel?: never;
|
|
2759
|
+
}
|
|
2760
|
+
/**
|
|
2761
|
+
* Any number of chosen values. The popup stays open while the person toggles
|
|
2762
|
+
* choices and closes on an outside click, Escape, or focus leaving; the closed
|
|
2763
|
+
* control summarizes the chosen labels in choice order.
|
|
2764
|
+
*/
|
|
2765
|
+
interface SelectMultipleLabelProps<Value extends string = string> {
|
|
2766
|
+
multiple: true;
|
|
2767
|
+
value: readonly NoInfer<Value>[];
|
|
2768
|
+
renderSelected?: never;
|
|
2769
|
+
selectedPresentation?: 'label';
|
|
2770
|
+
triggerIcon?: never;
|
|
2771
|
+
/** Opt in to a footer action that selects every enabled choice. */
|
|
2772
|
+
selectAllLabel?: string;
|
|
2773
|
+
/** Opt in to a footer action that clears the current selection. */
|
|
2774
|
+
clearLabel?: string;
|
|
2775
|
+
}
|
|
2776
|
+
/**
|
|
2777
|
+
* A multiple Select drawn as an icon-only toolbar trigger, such as a
|
|
2778
|
+
* "Filter by label" funnel. No single choice is selected, so the trigger shows
|
|
2779
|
+
* a fixed `triggerIcon` naming the menu's purpose; while any choice is chosen
|
|
2780
|
+
* a count badge sits beside it, and the combobox's accessible name ends with
|
|
2781
|
+
* the chosen labels in choice order.
|
|
2782
|
+
*/
|
|
2783
|
+
interface SelectMultipleIconProps<Value extends string = string> {
|
|
2784
|
+
multiple: true;
|
|
2785
|
+
value: readonly NoInfer<Value>[];
|
|
2786
|
+
renderSelected?: never;
|
|
2787
|
+
selectedPresentation: 'icon-only';
|
|
2788
|
+
/**
|
|
2789
|
+
* The trigger's fixed icon, typically a `LucideIcon` naming the menu's
|
|
2790
|
+
* purpose (a funnel for a filter), independent of the selection.
|
|
2791
|
+
*/
|
|
2792
|
+
triggerIcon: KerfUiContent;
|
|
2793
|
+
/** Opt in to a footer action that selects every enabled choice. */
|
|
2794
|
+
selectAllLabel?: string;
|
|
2795
|
+
/** Opt in to a footer action that clears the current selection. */
|
|
2796
|
+
clearLabel?: string;
|
|
2797
|
+
}
|
|
2798
|
+
type SelectMultipleValueProps<Value extends string = string> = SelectMultipleLabelProps<Value> | SelectMultipleIconProps<Value>;
|
|
2799
|
+
type SelectProps<Value extends string = string> = SelectBaseProps<Value> & SelectAccessibleName & (SelectSingleValueProps<Value> | SelectMultipleValueProps<Value>);
|
|
2800
|
+
declare function Select<Value extends string>(props: SelectProps<Value>): SafeHtml;
|
|
2801
|
+
|
|
2802
|
+
export { Select, type SelectChoice, type SelectFocusRingOwner, type SelectMultipleIconProps, type SelectMultipleLabelProps, type SelectMultipleValueProps, type SelectPresentation, type SelectProps, type SelectSelectedPresentation, type SelectSingleValueProps, type SelectSize, type SelectTriggerWidth };
|
|
2803
|
+
```
|
|
2804
|
+
|
|
708
2805
|
## `@kerfjs/ui/state-banner`
|
|
709
2806
|
|
|
710
2807
|
```ts
|
|
711
2808
|
import { SafeHtml } from 'kerfjs';
|
|
2809
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
712
2810
|
|
|
713
|
-
type StateBannerTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';
|
|
2811
|
+
type StateBannerTone = 'neutral' | 'info' | 'pop' | 'success' | 'warning' | 'danger';
|
|
2812
|
+
type StateBannerUrgency = 'status' | 'alert';
|
|
2813
|
+
type StateBannerCopyLayout = 'inline' | 'stacked';
|
|
2814
|
+
type StateBannerActionPlacement = 'trailing' | 'below';
|
|
714
2815
|
interface StateBannerProps {
|
|
715
2816
|
title: string;
|
|
716
2817
|
detail?: string;
|
|
2818
|
+
/** Optional compact status or count shown beside the title. */
|
|
2819
|
+
badge?: string;
|
|
717
2820
|
icon?: SafeHtml;
|
|
718
|
-
action?:
|
|
2821
|
+
action?: KerfUiContent;
|
|
719
2822
|
tone?: StateBannerTone;
|
|
720
|
-
urgency?:
|
|
2823
|
+
urgency?: StateBannerUrgency;
|
|
2824
|
+
/** Keep the detail beside the title, or give it its own line. */
|
|
2825
|
+
copyLayout?: StateBannerCopyLayout;
|
|
2826
|
+
/** Place the action beside the copy or on a separate trailing row. */
|
|
2827
|
+
actionPlacement?: StateBannerActionPlacement;
|
|
721
2828
|
className?: string;
|
|
722
|
-
/** Render the title and detail as unanimated loading skeletons, keeping the icon and tone. */
|
|
2829
|
+
/** Render the title, badge, and detail as unanimated loading skeletons, keeping the icon and tone. The detail line appears only when `detail` is set, as in the live banner. */
|
|
723
2830
|
placeholder?: boolean;
|
|
2831
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2832
|
+
slot?: string;
|
|
724
2833
|
}
|
|
725
|
-
declare function StateBanner({ title, detail, icon, action, tone, urgency, className, placeholder }: StateBannerProps): SafeHtml;
|
|
2834
|
+
declare function StateBanner({ title, detail, badge, icon, action, tone, urgency, copyLayout, actionPlacement, className, placeholder, slot, }: StateBannerProps): SafeHtml;
|
|
726
2835
|
|
|
727
|
-
export { StateBanner, type StateBannerProps, type StateBannerTone };
|
|
2836
|
+
export { StateBanner, type StateBannerActionPlacement, type StateBannerCopyLayout, type StateBannerProps, type StateBannerTone, type StateBannerUrgency };
|
|
728
2837
|
```
|
|
729
2838
|
|
|
730
2839
|
## `@kerfjs/ui/empty-state`
|
|
731
2840
|
|
|
732
2841
|
```ts
|
|
733
2842
|
import { SafeHtml } from 'kerfjs';
|
|
2843
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
734
2844
|
|
|
735
2845
|
interface EmptyStateProps {
|
|
736
2846
|
title: string;
|
|
737
2847
|
detail?: string;
|
|
738
2848
|
icon?: SafeHtml;
|
|
739
|
-
action?:
|
|
2849
|
+
action?: KerfUiContent;
|
|
740
2850
|
busy?: boolean;
|
|
741
2851
|
className?: string;
|
|
2852
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2853
|
+
slot?: string;
|
|
742
2854
|
}
|
|
743
|
-
declare function EmptyState({ title, detail, icon, action, busy, className }: EmptyStateProps): SafeHtml;
|
|
2855
|
+
declare function EmptyState({ title, detail, icon, action, busy, className, slot, }: EmptyStateProps): SafeHtml;
|
|
744
2856
|
|
|
745
2857
|
export { EmptyState, type EmptyStateProps };
|
|
746
2858
|
```
|
|
@@ -749,34 +2861,48 @@ export { EmptyState, type EmptyStateProps };
|
|
|
749
2861
|
|
|
750
2862
|
```ts
|
|
751
2863
|
import * as kerfjs from 'kerfjs';
|
|
2864
|
+
import { LucideIconSize } from './lucide-icon.js';
|
|
2865
|
+
import 'lucide';
|
|
752
2866
|
|
|
2867
|
+
type LoadingSpinnerSize = LucideIconSize;
|
|
753
2868
|
interface LoadingSpinnerProps {
|
|
754
2869
|
className?: string;
|
|
755
2870
|
label?: string;
|
|
2871
|
+
/** Named icon scale or positive pixel size, converted to rem. Omit for 1em. */
|
|
2872
|
+
size?: LoadingSpinnerSize;
|
|
2873
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2874
|
+
slot?: string;
|
|
756
2875
|
}
|
|
757
2876
|
/** Stable viewBox-centered progress ring based on svg-spinners' MIT-licensed 180-ring. */
|
|
758
|
-
declare function LoadingSpinner({ className, label }: LoadingSpinnerProps): kerfjs.SafeHtml;
|
|
2877
|
+
declare function LoadingSpinner({ className, label, size, slot, }: LoadingSpinnerProps): kerfjs.SafeHtml;
|
|
759
2878
|
|
|
760
|
-
export { LoadingSpinner, type LoadingSpinnerProps };
|
|
2879
|
+
export { LoadingSpinner, type LoadingSpinnerProps, type LoadingSpinnerSize };
|
|
761
2880
|
```
|
|
762
2881
|
|
|
763
2882
|
## `@kerfjs/ui/skeleton`
|
|
764
2883
|
|
|
765
2884
|
```ts
|
|
766
2885
|
import * as kerfjs from 'kerfjs';
|
|
2886
|
+
import { CssSize, CssLength } from './css-values.js';
|
|
767
2887
|
|
|
768
2888
|
interface SkeletonProps {
|
|
769
|
-
/**
|
|
770
|
-
width?:
|
|
771
|
-
/**
|
|
772
|
-
height?:
|
|
773
|
-
/**
|
|
774
|
-
radius?:
|
|
2889
|
+
/** Typed width or intrinsic sizing keyword. Defaults to filling its slot. */
|
|
2890
|
+
width?: CssSize;
|
|
2891
|
+
/** Typed height or intrinsic sizing keyword. Defaults to a single text line. */
|
|
2892
|
+
height?: CssSize;
|
|
2893
|
+
/** Typed corner-radius override. Defaults to the small radius token. */
|
|
2894
|
+
radius?: CssLength;
|
|
775
2895
|
/** Render this many stacked lines (the last one shorter), for multi-line text. */
|
|
776
2896
|
lines?: number;
|
|
2897
|
+
/** Lay the block out as `display: block` instead of the default
|
|
2898
|
+
* `inline-block`, so it takes no text line of its own: no baseline gap
|
|
2899
|
+
* below it, and it centers like an icon in a slot. Defaults to `false`. */
|
|
2900
|
+
block?: boolean;
|
|
777
2901
|
/** Accessible label. Omit to keep the block decorative (`aria-hidden`). */
|
|
778
2902
|
label?: string;
|
|
779
2903
|
className?: string;
|
|
2904
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2905
|
+
slot?: string;
|
|
780
2906
|
}
|
|
781
2907
|
/**
|
|
782
2908
|
* A subtle, deliberately **unanimated** loading placeholder block. Use it for a
|
|
@@ -784,68 +2910,107 @@ interface SkeletonProps {
|
|
|
784
2910
|
* `placeholder` prop. Decorative by default (`aria-hidden`); pass `label` to
|
|
785
2911
|
* announce it. Sizes to its slot unless `width`/`height` are given.
|
|
786
2912
|
*/
|
|
787
|
-
declare function Skeleton({ width, height, radius, lines, label, className }: SkeletonProps): kerfjs.SafeHtml;
|
|
2913
|
+
declare function Skeleton({ width, height, radius, lines, block, label, className, slot, }: SkeletonProps): kerfjs.SafeHtml;
|
|
788
2914
|
|
|
789
2915
|
export { Skeleton, type SkeletonProps };
|
|
790
2916
|
```
|
|
791
2917
|
|
|
792
|
-
## `@kerfjs/ui/
|
|
2918
|
+
## `@kerfjs/ui/sunken-panel`
|
|
793
2919
|
|
|
794
2920
|
```ts
|
|
795
|
-
import
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
disabled?: boolean;
|
|
811
|
-
autofocus?: boolean;
|
|
812
|
-
/** Allow an empty field to render as one iconic action. */
|
|
813
|
-
collapsible?: boolean;
|
|
814
|
-
/** Keep an empty collapsible field open while the application owns focus. */
|
|
815
|
-
expanded?: boolean;
|
|
816
|
-
expandAction?: string;
|
|
817
|
-
expandLabel?: string;
|
|
818
|
-
leading?: SafeHtml;
|
|
819
|
-
trailing?: SafeHtml;
|
|
820
|
-
editAction?: string;
|
|
821
|
-
removeAction?: string;
|
|
822
|
-
clearAction?: string;
|
|
823
|
-
clearLabel?: string;
|
|
2921
|
+
import * as kerfjs from 'kerfjs';
|
|
2922
|
+
import { CssFlexKeyword, CssFlex } from './css-values.js';
|
|
2923
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
2924
|
+
|
|
2925
|
+
type SunkenPanelShape = 'rounded' | 'square';
|
|
2926
|
+
interface SunkenPanelProps {
|
|
2927
|
+
children?: KerfUiContent;
|
|
2928
|
+
/** Optional accessible landmark name for a distinct application region. */
|
|
2929
|
+
ariaLabel?: string;
|
|
2930
|
+
/** Corner shape: a rounded rectangle (default) or square corners. */
|
|
2931
|
+
shape?: SunkenPanelShape;
|
|
2932
|
+
/** Grow or shrink within a flex parent, using Grid's typed flex contract. */
|
|
2933
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
2934
|
+
/** Fill a parent with a definite height; use flex inside a flex layout. */
|
|
2935
|
+
fill?: boolean;
|
|
824
2936
|
className?: string;
|
|
825
|
-
|
|
2937
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
2938
|
+
slot?: string;
|
|
826
2939
|
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
2940
|
+
/**
|
|
2941
|
+
* A lowered application surface with one compact inset and a vertical content
|
|
2942
|
+
* stack. The panel owns its background and padding; children own their own
|
|
2943
|
+
* borders and internal geometry.
|
|
2944
|
+
*/
|
|
2945
|
+
declare function SunkenPanel({ children, ariaLabel, shape, flex, fill, className, slot, }: SunkenPanelProps): kerfjs.SafeHtml;
|
|
2946
|
+
|
|
2947
|
+
export { SunkenPanel, type SunkenPanelProps, type SunkenPanelShape };
|
|
2948
|
+
```
|
|
2949
|
+
|
|
2950
|
+
## `@kerfjs/ui/token-search-field`
|
|
836
2951
|
|
|
837
|
-
|
|
2952
|
+
```ts
|
|
2953
|
+
import 'kerfjs';
|
|
2954
|
+
import './semantic-content-BbzjvSu9.js';
|
|
2955
|
+
export { T as TokenSearchEditorAttributes, a as TokenSearchField, b as TokenSearchFieldProps, c as TokenSearchFieldValue, j as TokenSearchToken, k as TokenSearchTrailingAction, p as placeTokenSearchCaret, r as readTokenSearchField } from './token-search-field-CVGwDn2y.js';
|
|
838
2956
|
```
|
|
839
2957
|
|
|
840
2958
|
## `@kerfjs/ui/wire-token-search-fields`
|
|
841
2959
|
|
|
842
2960
|
```ts
|
|
843
2961
|
import { Signal } from 'kerfjs';
|
|
2962
|
+
import { d as TokenSearchModel } from './token-search-field-CVGwDn2y.js';
|
|
2963
|
+
import './semantic-content-BbzjvSu9.js';
|
|
844
2964
|
|
|
845
2965
|
interface TokenSearchSubmit {
|
|
846
2966
|
id: string;
|
|
847
2967
|
editor: HTMLElement;
|
|
848
2968
|
}
|
|
2969
|
+
/** Reported to {@link WireTokenSearchFieldsOptions.onEdit} on every editor input. */
|
|
2970
|
+
interface TokenSearchEdit extends TokenSearchSubmit {
|
|
2971
|
+
/**
|
|
2972
|
+
* The `InputEvent` that mutated the editor — read `event.inputType` / `event.data`
|
|
2973
|
+
* to gate commit behavior (e.g. only parse a chip on whitespace-terminated input)
|
|
2974
|
+
* without keeping a separate `input` listener.
|
|
2975
|
+
*/
|
|
2976
|
+
event: InputEvent;
|
|
2977
|
+
}
|
|
2978
|
+
/** Reported when adjacent-token keyboard deletion asks the app to drop a chip. */
|
|
2979
|
+
interface TokenSearchTokenRemoval {
|
|
2980
|
+
id: string;
|
|
2981
|
+
/** The `data-token-value` of the token the app should remove from its state. */
|
|
2982
|
+
value: string;
|
|
2983
|
+
editor: HTMLElement;
|
|
2984
|
+
/** `'backward'` = the token before the caret (Backspace); `'forward'` = after (Delete). */
|
|
2985
|
+
direction: 'backward' | 'forward';
|
|
2986
|
+
}
|
|
2987
|
+
/**
|
|
2988
|
+
* Opt-in keyboard behavior for the atomic token chips. Off unless `keyboard` is
|
|
2989
|
+
* set; each piece defaults on once opted in. The helper never mutates app state:
|
|
2990
|
+
* a removal is reported through {@link TokenSearchKeyboardOptions.onRemoveToken}
|
|
2991
|
+
* for the caller to apply, while caret movement past a chip is a pure ephemeral
|
|
2992
|
+
* mechanic the helper performs itself.
|
|
2993
|
+
*/
|
|
2994
|
+
interface TokenSearchKeyboardBaseOptions {
|
|
2995
|
+
/**
|
|
2996
|
+
* From a collapsed caret with no selection, Backspace removes the token
|
|
2997
|
+
* immediately before it and Delete the token immediately after — reported via
|
|
2998
|
+
* `onRemoveToken` — instead of deleting a character. Default: true.
|
|
2999
|
+
*/
|
|
3000
|
+
/**
|
|
3001
|
+
* ArrowRight moves the caret past a trailing atomic token so text typed next
|
|
3002
|
+
* lands after the chip. Default: true.
|
|
3003
|
+
*/
|
|
3004
|
+
moveCaretPastToken?: boolean;
|
|
3005
|
+
}
|
|
3006
|
+
type TokenSearchKeyboardOptions = TokenSearchKeyboardBaseOptions & ({
|
|
3007
|
+
removeAdjacentToken?: true;
|
|
3008
|
+
/** Apply the reported removal to your controlled state, then re-render. */
|
|
3009
|
+
onRemoveToken: (removal: TokenSearchTokenRemoval) => void;
|
|
3010
|
+
} | {
|
|
3011
|
+
removeAdjacentToken: false;
|
|
3012
|
+
onRemoveToken?: never;
|
|
3013
|
+
});
|
|
849
3014
|
/**
|
|
850
3015
|
* Managed collapsible behavior for the iconic TokenSearchField. Every piece is on
|
|
851
3016
|
* by default; disable a specific one to own it in the app. Provide `signals` to
|
|
@@ -858,15 +3023,30 @@ interface TokenSearchCollapsibleOptions {
|
|
|
858
3023
|
collapseOnEmptyBlur?: boolean;
|
|
859
3024
|
/** Collapse an empty field on Escape and restore focus to its trigger. Default: true. */
|
|
860
3025
|
collapseOnEscape?: boolean;
|
|
861
|
-
/** Focus the editor on expand and the trigger on Escape-collapse. Default: true. */
|
|
3026
|
+
/** Focus the editor on expand/controlled clear and the trigger on Escape-collapse. Default: true. */
|
|
862
3027
|
manageFocus?: boolean;
|
|
3028
|
+
/**
|
|
3029
|
+
* Keep an empty field expanded when focus moves to a caller-owned surface
|
|
3030
|
+
* rendered outside the field — a suggestions dropdown, date picker, or help
|
|
3031
|
+
* popover shown beside it. Return true for any focus target that must NOT
|
|
3032
|
+
* trigger collapse-on-empty-blur. An element carrying `data-token-search-keep-open`
|
|
3033
|
+
* (or any node inside one) is always exempt, so this predicate is only needed
|
|
3034
|
+
* for surfaces you cannot mark declaratively.
|
|
3035
|
+
*/
|
|
3036
|
+
keepOpenOn?: (target: Node | null) => boolean;
|
|
863
3037
|
/** App-owned `expanded` signals keyed by field id; adopted instead of helper-created. */
|
|
864
3038
|
signals?: Readonly<Record<string, Signal<boolean>>>;
|
|
865
3039
|
}
|
|
866
3040
|
interface WireTokenSearchFieldsOptions {
|
|
3041
|
+
/** Optional automatic grammar/suggestion models, keyed by TokenSearchField id. */
|
|
3042
|
+
models?: Readonly<Record<string, TokenSearchModel>>;
|
|
867
3043
|
onSubmit?: (submission: TokenSearchSubmit) => void;
|
|
3044
|
+
/** Fired on every editor `input`, after the browser mutates it, so a caller can drop its own `input` listener. */
|
|
3045
|
+
onEdit?: (edit: TokenSearchEdit) => void;
|
|
868
3046
|
/** Managed collapsible transient behavior. `true`/omitted = on with defaults; `false` = fully off. */
|
|
869
3047
|
collapsible?: boolean | TokenSearchCollapsibleOptions;
|
|
3048
|
+
/** Opt-in atomic-chip keyboard behavior (off by default). */
|
|
3049
|
+
keyboard?: false | TokenSearchKeyboardOptions;
|
|
870
3050
|
}
|
|
871
3051
|
/**
|
|
872
3052
|
* The value returned from {@link wireTokenSearchFields}: call it (or `dispose()`) to
|
|
@@ -890,9 +3070,9 @@ interface TokenSearchFieldsHandle {
|
|
|
890
3070
|
* expand/collapse/focus. Returns a {@link TokenSearchFieldsHandle} — a disposer that also
|
|
891
3071
|
* exposes the managed `expanded` state per field id.
|
|
892
3072
|
*/
|
|
893
|
-
declare function wireTokenSearchFields(root: HTMLElement, { onSubmit, collapsible }?: WireTokenSearchFieldsOptions): TokenSearchFieldsHandle;
|
|
3073
|
+
declare function wireTokenSearchFields(root: HTMLElement, { models, onSubmit, onEdit, collapsible, keyboard, }?: WireTokenSearchFieldsOptions): TokenSearchFieldsHandle;
|
|
894
3074
|
|
|
895
|
-
export { type TokenSearchCollapsibleOptions, type TokenSearchFieldsHandle, type TokenSearchSubmit, type WireTokenSearchFieldsOptions, wireTokenSearchFields };
|
|
3075
|
+
export { type TokenSearchCollapsibleOptions, type TokenSearchEdit, type TokenSearchFieldsHandle, type TokenSearchKeyboardOptions, type TokenSearchSubmit, type TokenSearchTokenRemoval, type WireTokenSearchFieldsOptions, wireTokenSearchFields };
|
|
896
3076
|
```
|
|
897
3077
|
|
|
898
3078
|
## `kerfjs/actions`
|
|
@@ -971,3 +3151,361 @@ declare function delegateActions<E extends Element = Element>(root: HTMLElement,
|
|
|
971
3151
|
|
|
972
3152
|
export { type ActionHandler, type DelegateActionsOptions, action, delegateActions };
|
|
973
3153
|
```
|
|
3154
|
+
|
|
3155
|
+
## `@kerfjs/ui/badge`
|
|
3156
|
+
|
|
3157
|
+
```ts
|
|
3158
|
+
import { SafeHtml } from 'kerfjs';
|
|
3159
|
+
|
|
3160
|
+
type BadgeTone = 'neutral' | 'brand' | 'pop' | 'success' | 'warning' | 'danger';
|
|
3161
|
+
type BadgeAppearance = 'quiet' | 'solid' | 'outline';
|
|
3162
|
+
type BadgeShape = 'pill' | 'rounded';
|
|
3163
|
+
/** Size of a text badge. A text-free dot is the separate `size: 'dot'` form. */
|
|
3164
|
+
type BadgeSize = 'compact' | 'default';
|
|
3165
|
+
interface BadgeCommonProps {
|
|
3166
|
+
tone?: BadgeTone;
|
|
3167
|
+
className?: string;
|
|
3168
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3169
|
+
slot?: string;
|
|
3170
|
+
}
|
|
3171
|
+
/** A badge that shows a short status, count, or category as visible text. */
|
|
3172
|
+
interface BadgeTextProps extends BadgeCommonProps {
|
|
3173
|
+
children: SafeHtml | string | number;
|
|
3174
|
+
appearance?: BadgeAppearance;
|
|
3175
|
+
shape?: BadgeShape;
|
|
3176
|
+
size?: BadgeSize;
|
|
3177
|
+
/** Optional accessible name when the visible content is abbreviated. */
|
|
3178
|
+
label?: string;
|
|
3179
|
+
/** Hide a repeated visual badge from assistive technology. */
|
|
3180
|
+
ariaHidden?: boolean;
|
|
3181
|
+
}
|
|
3182
|
+
/** A labeled dot, announced as an image with its own accessible name. */
|
|
3183
|
+
interface BadgeDotLabeled {
|
|
3184
|
+
/** Accessible name for the dot, for example `"New activity"`. */
|
|
3185
|
+
label: string;
|
|
3186
|
+
ariaHidden?: false;
|
|
3187
|
+
}
|
|
3188
|
+
/** A decorative dot whose meaning the owning component already announces. */
|
|
3189
|
+
interface BadgeDotDecorative {
|
|
3190
|
+
label?: never;
|
|
3191
|
+
ariaHidden: true;
|
|
3192
|
+
}
|
|
3193
|
+
/**
|
|
3194
|
+
* A text-free status dot (the iOS "new content" dot): a small solid circle in
|
|
3195
|
+
* the badge's tone. It has no visible text, so it must either carry its own
|
|
3196
|
+
* accessible `label` (exposed as an image) or be `ariaHidden` because the
|
|
3197
|
+
* surrounding component already folds its meaning into an accessible name.
|
|
3198
|
+
*/
|
|
3199
|
+
type BadgeDotProps = BadgeCommonProps & {
|
|
3200
|
+
size: 'dot';
|
|
3201
|
+
children?: never;
|
|
3202
|
+
appearance?: never;
|
|
3203
|
+
shape?: never;
|
|
3204
|
+
} & (BadgeDotLabeled | BadgeDotDecorative);
|
|
3205
|
+
type BadgeProps = BadgeTextProps | BadgeDotProps;
|
|
3206
|
+
/** Compact, non-interactive metadata whose tone, emphasis, and shape are configured by props. */
|
|
3207
|
+
declare function Badge(props: BadgeProps): SafeHtml;
|
|
3208
|
+
|
|
3209
|
+
export { Badge, type BadgeAppearance, type BadgeDotProps, type BadgeProps, type BadgeShape, type BadgeSize, type BadgeTextProps, type BadgeTone };
|
|
3210
|
+
```
|
|
3211
|
+
|
|
3212
|
+
## `@kerfjs/ui/chip`
|
|
3213
|
+
|
|
3214
|
+
```ts
|
|
3215
|
+
import { SafeHtml } from 'kerfjs';
|
|
3216
|
+
import { BadgeTone, BadgeAppearance, BadgeShape, BadgeSize } from './badge.js';
|
|
3217
|
+
|
|
3218
|
+
interface ChipCommonProps {
|
|
3219
|
+
/** Decorative leading icon, normally an unsized LucideIcon. */
|
|
3220
|
+
icon?: SafeHtml;
|
|
3221
|
+
tone?: BadgeTone;
|
|
3222
|
+
appearance?: BadgeAppearance;
|
|
3223
|
+
shape?: BadgeShape;
|
|
3224
|
+
size?: BadgeSize;
|
|
3225
|
+
disabled?: boolean;
|
|
3226
|
+
/** Record identifier available to an application delegated action handler. */
|
|
3227
|
+
itemId?: string;
|
|
3228
|
+
className?: string;
|
|
3229
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3230
|
+
slot?: string;
|
|
3231
|
+
}
|
|
3232
|
+
/** A removable chip needs both a delegated action and a specific accessible name. */
|
|
3233
|
+
type ChipProps = ChipCommonProps & ({
|
|
3234
|
+
children: SafeHtml | string | number;
|
|
3235
|
+
truncate?: false;
|
|
3236
|
+
} | {
|
|
3237
|
+
children: string;
|
|
3238
|
+
truncate: true;
|
|
3239
|
+
}) & ({
|
|
3240
|
+
removeAction: string;
|
|
3241
|
+
removeLabel: string;
|
|
3242
|
+
} | {
|
|
3243
|
+
removeAction?: never;
|
|
3244
|
+
removeLabel?: never;
|
|
3245
|
+
});
|
|
3246
|
+
/** A short label with an optional native remove button. The application owns removal. */
|
|
3247
|
+
declare function Chip({ children, icon, truncate, tone, appearance, shape, size, disabled, itemId, className, slot, ...remove }: ChipProps): SafeHtml;
|
|
3248
|
+
|
|
3249
|
+
export { Chip, type ChipProps };
|
|
3250
|
+
```
|
|
3251
|
+
|
|
3252
|
+
## `@kerfjs/ui/lucide-icon`
|
|
3253
|
+
|
|
3254
|
+
```ts
|
|
3255
|
+
import * as kerfjs from 'kerfjs';
|
|
3256
|
+
import { IconNode } from 'lucide';
|
|
3257
|
+
|
|
3258
|
+
type LucideNode = IconNode;
|
|
3259
|
+
type LucideIconSize = 'xs' | 's' | 'm' | 'l' | 'xl' | number;
|
|
3260
|
+
interface LucideIconProps {
|
|
3261
|
+
icon: LucideNode;
|
|
3262
|
+
name: string;
|
|
3263
|
+
/** Outline by default; solid fills compatible glyphs with the current text color. */
|
|
3264
|
+
appearance?: 'outline' | 'solid';
|
|
3265
|
+
className?: string;
|
|
3266
|
+
label?: string;
|
|
3267
|
+
/** Named icon scale or positive pixel size, converted to rem. Omit for 1em. */
|
|
3268
|
+
size?: LucideIconSize;
|
|
3269
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3270
|
+
slot?: string;
|
|
3271
|
+
}
|
|
3272
|
+
/** Render a Lucide-compatible icon node without copying icon SVG strings. */
|
|
3273
|
+
declare function LucideIcon({ icon, name, appearance, className, label, size, slot, }: LucideIconProps): kerfjs.SafeHtml;
|
|
3274
|
+
|
|
3275
|
+
export { LucideIcon, type LucideIconProps, type LucideIconSize, type LucideNode };
|
|
3276
|
+
```
|
|
3277
|
+
|
|
3278
|
+
## `@kerfjs/ui/surface-scaffold`
|
|
3279
|
+
|
|
3280
|
+
```ts
|
|
3281
|
+
import * as kerfjs from 'kerfjs';
|
|
3282
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3283
|
+
|
|
3284
|
+
type DialogSurfaceSize = 'small' | 'medium' | 'large';
|
|
3285
|
+
type DialogSurfacePresentation = 'modal' | 'side-sheet' | 'fullscreen';
|
|
3286
|
+
type SurfaceInset = 'none' | 'compact' | 'comfortable';
|
|
3287
|
+
interface DialogSurfaceProps {
|
|
3288
|
+
children: KerfUiContent;
|
|
3289
|
+
size?: DialogSurfaceSize;
|
|
3290
|
+
presentation?: DialogSurfacePresentation;
|
|
3291
|
+
bodyInset?: SurfaceInset;
|
|
3292
|
+
footerInset?: SurfaceInset;
|
|
3293
|
+
className?: string;
|
|
3294
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3295
|
+
slot?: string;
|
|
3296
|
+
}
|
|
3297
|
+
/** Configure recurring Web Awesome dialog geometry without consumer ::part() CSS. */
|
|
3298
|
+
declare function DialogSurface({ children, size, presentation, bodyInset, footerInset, className, slot, }: DialogSurfaceProps): kerfjs.SafeHtml;
|
|
3299
|
+
type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';
|
|
3300
|
+
interface PopupSurfaceProps {
|
|
3301
|
+
children: KerfUiContent;
|
|
3302
|
+
inset?: PopupSurfaceInset;
|
|
3303
|
+
className?: string;
|
|
3304
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3305
|
+
slot?: string;
|
|
3306
|
+
}
|
|
3307
|
+
/** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */
|
|
3308
|
+
declare function PopupSurface({ children, inset, className, slot, }: PopupSurfaceProps): kerfjs.SafeHtml;
|
|
3309
|
+
|
|
3310
|
+
export { DialogSurface, type DialogSurfacePresentation, type DialogSurfaceProps, type DialogSurfaceSize, PopupSurface, type PopupSurfaceInset, type PopupSurfaceProps, type SurfaceInset };
|
|
3311
|
+
```
|
|
3312
|
+
|
|
3313
|
+
## `@kerfjs/ui/text`
|
|
3314
|
+
|
|
3315
|
+
```ts
|
|
3316
|
+
import * as kerfjs from 'kerfjs';
|
|
3317
|
+
import { KerfBaseAttrs } from 'kerfjs/jsx-runtime';
|
|
3318
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3319
|
+
|
|
3320
|
+
type TextVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';
|
|
3321
|
+
type TextTone = 'default' | 'quiet' | 'danger';
|
|
3322
|
+
type TextSize = 'compact' | 'default' | 'large' | 'xlarge';
|
|
3323
|
+
type TextFont = 'default' | 'monospace';
|
|
3324
|
+
type TextBorder = 'transparent' | 'none';
|
|
3325
|
+
type TextLineHeight = 'default' | 'tight';
|
|
3326
|
+
type TextWrap = 'normal' | 'anywhere' | 'nowrap' | 'truncate';
|
|
3327
|
+
type TextContent = KerfUiContent | string | number | readonly TextContent[];
|
|
3328
|
+
type FieldLabelProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
|
|
3329
|
+
children: string;
|
|
3330
|
+
class?: string;
|
|
3331
|
+
className?: string;
|
|
3332
|
+
};
|
|
3333
|
+
/** Visible field heading for a read-only preview; use its id with aria-labelledby on the preview group. */
|
|
3334
|
+
declare function FieldLabel({ children, class: classValue, className, ...attributes }: FieldLabelProps): kerfjs.SafeHtml;
|
|
3335
|
+
type TextCommonProps = Omit<KerfBaseAttrs, 'children' | 'class' | 'className'> & {
|
|
3336
|
+
/** Native heading, paragraph, or inline span element to render. Defaults to `p`. */
|
|
3337
|
+
variant?: TextVariant;
|
|
3338
|
+
/** Semantic foreground treatment. Defaults to the inherited foreground. */
|
|
3339
|
+
tone?: TextTone;
|
|
3340
|
+
/** Text sizing independent of the native semantic element. */
|
|
3341
|
+
size?: TextSize;
|
|
3342
|
+
/** Font family independent of the native semantic element. */
|
|
3343
|
+
font?: TextFont;
|
|
3344
|
+
/** Transparent alignment border or no border when embedded in owner chrome. */
|
|
3345
|
+
border?: TextBorder;
|
|
3346
|
+
/** Remove the block variant's item padding and border in compact content. */
|
|
3347
|
+
flush?: boolean;
|
|
3348
|
+
/** Use compact leading for short dialog or metadata copy. */
|
|
3349
|
+
lineHeight?: TextLineHeight;
|
|
3350
|
+
children: TextContent;
|
|
3351
|
+
class?: string;
|
|
3352
|
+
className?: string;
|
|
3353
|
+
};
|
|
3354
|
+
type TextProps = TextCommonProps & ({
|
|
3355
|
+
/** Wrap normally or break long unbroken strings. Defaults to normal. */
|
|
3356
|
+
wrap?: 'normal' | 'anywhere';
|
|
3357
|
+
/** Cap wrapped text to this positive number of lines. */
|
|
3358
|
+
maxLines?: number;
|
|
3359
|
+
} | {
|
|
3360
|
+
/** Keep one line, with or without an ellipsis. */
|
|
3361
|
+
wrap: 'nowrap' | 'truncate';
|
|
3362
|
+
maxLines?: never;
|
|
3363
|
+
});
|
|
3364
|
+
/**
|
|
3365
|
+
* Semantic heading, paragraph, or inline text. Block variants use the standard
|
|
3366
|
+
* content-item padding; `span` adds no box geometry.
|
|
3367
|
+
* All ordinary native heading/paragraph attributes pass through to the element.
|
|
3368
|
+
*/
|
|
3369
|
+
declare function Text({ variant: Variant, tone, size, font, border, flush, lineHeight, wrap, maxLines, children, class: classValue, className, ...attributes }: TextProps): kerfjs.SafeHtml;
|
|
3370
|
+
|
|
3371
|
+
export { FieldLabel, type FieldLabelProps, Text, type TextBorder, type TextContent, type TextFont, type TextLineHeight, type TextProps, type TextSize, type TextTone, type TextVariant, type TextWrap };
|
|
3372
|
+
```
|
|
3373
|
+
|
|
3374
|
+
## `@kerfjs/ui/row`
|
|
3375
|
+
|
|
3376
|
+
```ts
|
|
3377
|
+
import * as kerfjs from 'kerfjs';
|
|
3378
|
+
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
3379
|
+
import { H as HorizontalAlignment, V as VerticalAlignment } from './flex-alignment-4ms8ZbV8.js';
|
|
3380
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3381
|
+
import { S as Sides } from './sides-BPSWde0A.js';
|
|
3382
|
+
|
|
3383
|
+
type RowRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
3384
|
+
'data-component'?: never;
|
|
3385
|
+
'data-h-align'?: never;
|
|
3386
|
+
'data-v-align'?: never;
|
|
3387
|
+
'data-flex'?: never;
|
|
3388
|
+
'data-fill'?: never;
|
|
3389
|
+
'data-wrap'?: never;
|
|
3390
|
+
'data-text-insets'?: never;
|
|
3391
|
+
'data-control-insets'?: never;
|
|
3392
|
+
}>;
|
|
3393
|
+
interface RowProps {
|
|
3394
|
+
children?: KerfUiContent;
|
|
3395
|
+
/** Horizontal distribution. Defaults to left. */
|
|
3396
|
+
hAlign?: HorizontalAlignment;
|
|
3397
|
+
/** Vertical alignment and wrapped-line distribution. Defaults to full. */
|
|
3398
|
+
vAlign?: VerticalAlignment;
|
|
3399
|
+
/** A named UI spacing token or typed CSS length. Defaults to xs. */
|
|
3400
|
+
gap?: UiSpaceName | CssLength;
|
|
3401
|
+
/** Allow this row to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
3402
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
3403
|
+
/**
|
|
3404
|
+
* Fill the height of a parent with a definite height, such as an app root or
|
|
3405
|
+
* a fixed-height frame, when this row is that parent's layout root. Inside a
|
|
3406
|
+
* flex layout use `flex` instead. Defaults to false.
|
|
3407
|
+
*/
|
|
3408
|
+
fill?: boolean;
|
|
3409
|
+
/** Allow children to wrap onto additional lines. */
|
|
3410
|
+
wrap?: boolean;
|
|
3411
|
+
/** Physical sides that receive the standard 17px text inset. */
|
|
3412
|
+
textInsets?: Sides;
|
|
3413
|
+
/** Physical sides that receive the standard 8px control inset. Text insets win on overlap. */
|
|
3414
|
+
controlInsets?: Sides;
|
|
3415
|
+
className?: string;
|
|
3416
|
+
/** Safe `data-*` metadata; Row-owned structural attributes remain protected. */
|
|
3417
|
+
rootAttributes?: RowRootAttributes;
|
|
3418
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3419
|
+
slot?: string;
|
|
3420
|
+
}
|
|
3421
|
+
/** A horizontal flex row with explicit physical-axis alignment and spacing. */
|
|
3422
|
+
declare function Row({ children, hAlign, vAlign, gap, flex, fill, wrap, textInsets, controlInsets, className, rootAttributes, slot, }: RowProps): kerfjs.SafeHtml;
|
|
3423
|
+
|
|
3424
|
+
export { CssFlex, CssFlexKeyword, CssLength, HorizontalAlignment, Row, type RowProps, Sides, UiSpaceName, VerticalAlignment };
|
|
3425
|
+
```
|
|
3426
|
+
|
|
3427
|
+
## `@kerfjs/ui/grid`
|
|
3428
|
+
|
|
3429
|
+
```ts
|
|
3430
|
+
import * as kerfjs from 'kerfjs';
|
|
3431
|
+
import { UiSpaceName, CssLength, CssFlexKeyword, CssFlex } from './css-values.js';
|
|
3432
|
+
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
3433
|
+
|
|
3434
|
+
type GridRootAttributes = Readonly<Record<`data-${string}`, string | undefined> & {
|
|
3435
|
+
'data-component'?: never;
|
|
3436
|
+
'data-columns'?: never;
|
|
3437
|
+
'data-min-column-width'?: never;
|
|
3438
|
+
'data-auto-fill'?: never;
|
|
3439
|
+
'data-flex'?: never;
|
|
3440
|
+
'data-fill'?: never;
|
|
3441
|
+
}>;
|
|
3442
|
+
interface GridCommonProps {
|
|
3443
|
+
children?: KerfUiContent;
|
|
3444
|
+
/** Make this a labeled multi-select grid for `ContentItem selectionMode="multiple"` tiles. */
|
|
3445
|
+
selectionMode?: 'multiple';
|
|
3446
|
+
/** Accessible name for the multi-select grid. */
|
|
3447
|
+
ariaLabel?: string;
|
|
3448
|
+
/** A named UI spacing token or typed CSS length. Defaults to xs. */
|
|
3449
|
+
gap?: UiSpaceName | CssLength;
|
|
3450
|
+
/** Allow this grid to grow/shrink, use a keyword, or supply a typed CSS flex shorthand. */
|
|
3451
|
+
flex?: boolean | CssFlexKeyword | CssFlex;
|
|
3452
|
+
/**
|
|
3453
|
+
* Fill the height of a parent with a definite height, such as an app root or
|
|
3454
|
+
* a fixed-height frame, when this grid is that parent's layout root. Inside a
|
|
3455
|
+
* flex layout use `flex` instead. Defaults to false.
|
|
3456
|
+
*/
|
|
3457
|
+
fill?: boolean;
|
|
3458
|
+
className?: string;
|
|
3459
|
+
/** Safe `data-*` metadata; Grid-owned structural attributes remain protected. */
|
|
3460
|
+
rootAttributes?: GridRootAttributes;
|
|
3461
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3462
|
+
slot?: string;
|
|
3463
|
+
}
|
|
3464
|
+
type GridProps = GridCommonProps & ({
|
|
3465
|
+
/** Number of equal-width columns. Must be a positive safe integer. */
|
|
3466
|
+
columns: number;
|
|
3467
|
+
minColumnWidth?: never;
|
|
3468
|
+
autoFill?: never;
|
|
3469
|
+
} | {
|
|
3470
|
+
columns?: never;
|
|
3471
|
+
/** Fit equal columns of at least this width; collapse as the container narrows. */
|
|
3472
|
+
minColumnWidth: CssLength;
|
|
3473
|
+
/** Keep empty tracks instead of stretching a sparse row. Defaults to false. */
|
|
3474
|
+
autoFill?: boolean;
|
|
3475
|
+
});
|
|
3476
|
+
/** Render equal tracks with a fixed count or a responsive minimum width. */
|
|
3477
|
+
declare function Grid({ children, selectionMode, ariaLabel, columns, minColumnWidth, autoFill, gap, flex, fill, className, rootAttributes, slot, }: GridProps): kerfjs.SafeHtml;
|
|
3478
|
+
|
|
3479
|
+
export { CssFlex, CssFlexKeyword, CssLength, Grid, type GridProps, UiSpaceName };
|
|
3480
|
+
```
|
|
3481
|
+
|
|
3482
|
+
## `@kerfjs/ui/spacer`
|
|
3483
|
+
|
|
3484
|
+
```ts
|
|
3485
|
+
import * as kerfjs from 'kerfjs';
|
|
3486
|
+
import { UiSpaceName, CssLength } from './css-values.js';
|
|
3487
|
+
|
|
3488
|
+
interface SpacerProps {
|
|
3489
|
+
/** Grow and shrink to fill the available space along a parent's flex axis. */
|
|
3490
|
+
flex?: boolean;
|
|
3491
|
+
/** A named UI spacing token or typed physical width. */
|
|
3492
|
+
width?: UiSpaceName | CssLength;
|
|
3493
|
+
/** A named UI spacing token or typed physical height. */
|
|
3494
|
+
height?: UiSpaceName | CssLength;
|
|
3495
|
+
className?: string;
|
|
3496
|
+
/** Native named-slot assignment when composed inside a web component. */
|
|
3497
|
+
slot?: string;
|
|
3498
|
+
}
|
|
3499
|
+
/** A decorative fixed-size or flexible gap for Row, List, and other flex layouts. */
|
|
3500
|
+
declare function Spacer({ flex, width, height, className, slot, }: SpacerProps): kerfjs.SafeHtml;
|
|
3501
|
+
|
|
3502
|
+
export { CssLength, Spacer, type SpacerProps, UiSpaceName };
|
|
3503
|
+
```
|
|
3504
|
+
|
|
3505
|
+
## `@kerfjs/ui/token-search-model`
|
|
3506
|
+
|
|
3507
|
+
```ts
|
|
3508
|
+
import 'kerfjs';
|
|
3509
|
+
export { d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchResolvedToken, g as TokenSearchRule, h as TokenSearchState, i as TokenSearchSuggestion, l as createTokenSearchModel } from './token-search-field-CVGwDn2y.js';
|
|
3510
|
+
import './semantic-content-BbzjvSu9.js';
|
|
3511
|
+
```
|