@kerfjs/ui 4.5.0-beta.1 → 5.0.0-beta.100
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 +461 -116
- package/ai/application-ui-diagnostic-ids-v1.json +23 -1
- package/ai/application-ui-profile-sync.cjs +21 -2
- package/ai/application-ui-profile.d.ts +4 -0
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +28 -1
- package/ai/application-ui-profile.schema.json +10 -0
- package/ai/catalog-authoring.json +13 -4
- package/ai/catalog-authoring.schema.json +52 -8
- package/ai/compile-time-contracts-v1.json +63 -16
- package/ai/compile-time-contracts-v1.schema.json +4 -1
- package/ai/component-catalog-extension.schema.json +25 -0
- package/ai/component-catalog.json +5585 -1175
- package/ai/component-catalog.schema.json +78 -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-catalog-v2-overrides.json → component-composition-rules.json} +281 -49
- package/ai/component-composition.d.ts +132 -0
- package/ai/component-composition.json +8729 -0
- package/ai/component-composition.schema.json +412 -0
- package/ai/components/README.md +185 -0
- package/ai/components/anchored-surface.md +99 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +76 -0
- package/ai/components/chip.md +76 -0
- package/ai/components/choice-chips.md +87 -0
- package/ai/components/collapsible-panel.md +103 -0
- package/ai/components/column-track.md +78 -0
- package/ai/components/combobox.md +88 -0
- package/ai/components/composer.md +83 -0
- package/ai/components/content-item.md +98 -0
- package/ai/components/content-swap.md +78 -0
- package/ai/components/corner-status.md +88 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +77 -0
- package/ai/components/edge-activity-indicator.md +81 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/file-picker.md +88 -0
- package/ai/components/floating-toolbar.md +82 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/framed-list.md +80 -0
- package/ai/components/grid.md +101 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/icon-button.md +82 -0
- package/ai/components/icon-toggle-button.md +80 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +108 -0
- package/ai/components/list-header.md +91 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +108 -0
- package/ai/components/list.md +125 -0
- package/ai/components/loading-spinner.md +73 -0
- package/ai/components/lucide-icon.md +97 -0
- package/ai/components/nav-stack.md +115 -0
- package/ai/components/pane.md +115 -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 +116 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-button.md +80 -0
- package/ai/components/split-view.md +105 -0
- package/ai/components/state-banner.md +96 -0
- package/ai/components/summary-row.md +85 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +105 -0
- package/ai/components/tab-bar.md +114 -0
- package/ai/components/tab-navigator.md +100 -0
- package/ai/components/tabs.md +95 -0
- package/ai/components/text.md +90 -0
- package/ai/components/token-search-field.md +107 -0
- package/ai/components/toolbar-control-group.md +125 -0
- package/ai/components/toolbar-text.md +100 -0
- package/ai/components/toolbar.md +103 -0
- package/ai/components/value-table.md +80 -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 +60 -0
- package/ai/components/wa-button.md +59 -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 +120 -0
- package/ai/public-api-signatures-v1.md +3851 -441
- package/ai/skill.md +402 -70
- package/ai/webawesome-jsx-signatures-v1.md +9 -2
- package/analyzer/cli.mjs +5 -2
- package/analyzer/component-ownership.d.mts +72 -0
- package/analyzer/component-ownership.mjs +429 -0
- package/analyzer/index.d.mts +8 -0
- package/analyzer/index.mjs +1687 -49
- package/analyzer/loud-pairs.d.mts +49 -0
- package/analyzer/loud-pairs.mjs +357 -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/anchored-surface.d.ts +69 -0
- package/dist/anchored-surface.js +3 -0
- package/dist/anchored-surface.js.map +1 -0
- package/dist/app-tab.d.ts +39 -4
- package/dist/app-tab.js +2 -1
- package/dist/badge.d.ts +83 -0
- package/dist/badge.js +4 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/anchored-surface.js +3 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/catalog.js +28 -0
- package/dist/browser/chip.js +3 -0
- package/dist/browser/choice-chips.js +3 -0
- package/dist/browser/collapsible-panel.js +9 -0
- package/dist/browser/column-track.js +3 -0
- package/dist/browser/combobox.js +3 -0
- package/dist/browser/composer.js +4 -0
- package/dist/browser/content-item.js +3 -0
- package/dist/browser/content-swap.js +3 -0
- package/dist/browser/corner-status.js +3 -0
- package/dist/browser/edge-activity-indicator.js +3 -0
- package/dist/browser/file-picker.js +3 -0
- package/dist/browser/framed-list.js +3 -0
- package/dist/browser/grid.js +3 -0
- package/dist/browser/icon-button.js +4 -0
- package/dist/browser/icon-toggle-button.js +4 -0
- package/dist/browser/list-action-row.js +2 -0
- package/dist/browser/list-header.js +3 -1
- package/dist/browser/list-item.js +1 -0
- package/dist/browser/nav-stack.js +11 -0
- package/dist/browser/popup-menu.js +3 -0
- package/dist/browser/row.js +3 -0
- package/dist/browser/segmented-control.js +0 -1
- package/dist/browser/select.js +2 -1
- package/dist/browser/spacer.js +3 -0
- package/dist/browser/split-button.js +5 -0
- package/dist/browser/split-view.js +13 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/browser/summary-row.js +3 -0
- package/dist/browser/surface-scaffold.js +3 -0
- package/dist/browser/tab-navigator.js +4 -0
- package/dist/browser/text.js +3 -0
- package/dist/browser/toolbar-control-group.js +1 -0
- package/dist/browser/workbench.js +14 -0
- package/dist/catalog-resources.d.ts +17 -1
- package/dist/catalog-resources.js +5 -5
- package/dist/catalog-resources.js.map +1 -1
- package/dist/catalog.d.ts +123 -121
- package/dist/catalog.js +598 -269
- package/dist/catalog.js.map +1 -1
- package/dist/chip.d.ts +69 -0
- package/dist/chip.js +3 -0
- package/dist/chip.js.map +1 -0
- package/dist/choice-chips.d.ts +82 -0
- package/dist/choice-chips.js +3 -0
- package/dist/choice-chips.js.map +1 -0
- package/dist/chunk-2GOCOLQL.js +270 -0
- package/dist/chunk-2GOCOLQL.js.map +1 -0
- package/dist/chunk-2MSPNRWJ.js +82 -0
- package/dist/chunk-2MSPNRWJ.js.map +1 -0
- package/dist/chunk-34U4ANDJ.js +119 -0
- package/dist/chunk-34U4ANDJ.js.map +1 -0
- package/dist/chunk-3GLYIIFR.js +230 -0
- package/dist/chunk-3GLYIIFR.js.map +1 -0
- package/dist/{chunk-Y6LYKFXY.js → chunk-3VXDSIBJ.js} +7 -4
- package/dist/chunk-3VXDSIBJ.js.map +1 -0
- package/dist/chunk-3WYREXW4.js +120 -0
- package/dist/chunk-3WYREXW4.js.map +1 -0
- package/dist/chunk-4UB5Z3ZZ.js +68 -0
- package/dist/chunk-4UB5Z3ZZ.js.map +1 -0
- package/dist/chunk-6C6DLP3W.js +31 -0
- package/dist/chunk-6C6DLP3W.js.map +1 -0
- package/dist/chunk-7IUEBNCO.js +108 -0
- package/dist/chunk-7IUEBNCO.js.map +1 -0
- package/dist/{chunk-QO55FN2Y.js → chunk-AN5IWMTM.js} +7 -3
- package/dist/chunk-AN5IWMTM.js.map +1 -0
- package/dist/chunk-AV7CPAPT.js +82 -0
- package/dist/chunk-AV7CPAPT.js.map +1 -0
- package/dist/{chunk-PX3YSS5C.js → chunk-B53PS2LE.js} +5 -3
- package/dist/chunk-B53PS2LE.js.map +1 -0
- package/dist/chunk-CA7LNX3J.js +44 -0
- package/dist/chunk-CA7LNX3J.js.map +1 -0
- package/dist/chunk-CEJ5FK6G.js +288 -0
- package/dist/chunk-CEJ5FK6G.js.map +1 -0
- package/dist/chunk-CMETHPKR.js +175 -0
- package/dist/chunk-CMETHPKR.js.map +1 -0
- package/dist/chunk-CMLPFIC5.js +46 -0
- package/dist/chunk-CMLPFIC5.js.map +1 -0
- package/dist/{chunk-RKVQEH4J.js → chunk-CVD5IZGB.js} +10 -5
- package/dist/chunk-CVD5IZGB.js.map +1 -0
- package/dist/chunk-CXZXHZTR.js +514 -0
- package/dist/chunk-CXZXHZTR.js.map +1 -0
- package/dist/chunk-D5RGM3XA.js +38 -0
- package/dist/chunk-D5RGM3XA.js.map +1 -0
- package/dist/{chunk-KWWR5VMS.js → chunk-DZJ4GBSP.js} +19 -5
- package/dist/chunk-DZJ4GBSP.js.map +1 -0
- package/dist/chunk-EIET4QLK.js +51 -0
- package/dist/chunk-EIET4QLK.js.map +1 -0
- package/dist/chunk-ELCMSQNJ.js +49 -0
- package/dist/chunk-ELCMSQNJ.js.map +1 -0
- package/dist/chunk-EOO6PYGF.js +162 -0
- package/dist/chunk-EOO6PYGF.js.map +1 -0
- package/dist/chunk-ETCWQLJV.js +85 -0
- package/dist/chunk-ETCWQLJV.js.map +1 -0
- package/dist/chunk-FDZNYD4C.js +138 -0
- package/dist/chunk-FDZNYD4C.js.map +1 -0
- package/dist/chunk-FR76ZJQC.js +90 -0
- package/dist/chunk-FR76ZJQC.js.map +1 -0
- package/dist/chunk-G3J7JDP6.js +29 -0
- package/dist/chunk-G3J7JDP6.js.map +1 -0
- package/dist/chunk-GS2QD3N7.js +14 -0
- package/dist/chunk-GS2QD3N7.js.map +1 -0
- package/dist/chunk-HGV7J4T6.js +86 -0
- package/dist/chunk-HGV7J4T6.js.map +1 -0
- package/dist/chunk-HLDRH23D.js +84 -0
- package/dist/chunk-HLDRH23D.js.map +1 -0
- package/dist/chunk-HQZYKJ56.js +302 -0
- package/dist/chunk-HQZYKJ56.js.map +1 -0
- package/dist/chunk-HZPHCSCS.js +95 -0
- package/dist/chunk-HZPHCSCS.js.map +1 -0
- package/dist/chunk-IKS72C6P.js +53 -0
- package/dist/chunk-IKS72C6P.js.map +1 -0
- package/dist/chunk-IM3GKYOG.js +202 -0
- package/dist/chunk-IM3GKYOG.js.map +1 -0
- package/dist/{chunk-JRKSK2HX.js → chunk-INI4WDWC.js} +53 -7
- package/dist/chunk-INI4WDWC.js.map +1 -0
- package/dist/chunk-IQSRHXZR.js +164 -0
- package/dist/chunk-IQSRHXZR.js.map +1 -0
- package/dist/{chunk-M7JBER5U.js → chunk-JOR5LGYE.js} +18 -4
- package/dist/chunk-JOR5LGYE.js.map +1 -0
- package/dist/chunk-K4AT3V3J.js +545 -0
- package/dist/chunk-K4AT3V3J.js.map +1 -0
- package/dist/chunk-KCS6NJ3O.js +82 -0
- package/dist/chunk-KCS6NJ3O.js.map +1 -0
- package/dist/{chunk-SRSJO5QE.js → chunk-KH4KEMSP.js} +34 -3
- package/dist/chunk-KH4KEMSP.js.map +1 -0
- package/dist/chunk-LL45C7BB.js +122 -0
- package/dist/chunk-LL45C7BB.js.map +1 -0
- package/dist/chunk-LOSRXZAH.js +100 -0
- package/dist/chunk-LOSRXZAH.js.map +1 -0
- package/dist/{chunk-7KEUJIIC.js → chunk-MF6ZUUJZ.js} +93 -11
- package/dist/chunk-MF6ZUUJZ.js.map +1 -0
- package/dist/chunk-MHMWQ7RB.js +19 -0
- package/dist/chunk-MHMWQ7RB.js.map +1 -0
- package/dist/chunk-MJ5RU6XT.js +173 -0
- package/dist/chunk-MJ5RU6XT.js.map +1 -0
- package/dist/chunk-MXNIVEVL.js +48 -0
- package/dist/chunk-MXNIVEVL.js.map +1 -0
- package/dist/{chunk-IJBSZ4NX.js → chunk-NS2TBYM4.js} +8 -5
- package/dist/chunk-NS2TBYM4.js.map +1 -0
- package/dist/chunk-PIVY32AE.js +140 -0
- package/dist/chunk-PIVY32AE.js.map +1 -0
- package/dist/chunk-PYBBYSZ3.js +526 -0
- package/dist/chunk-PYBBYSZ3.js.map +1 -0
- package/dist/chunk-QDSZTQXL.js +28 -0
- package/dist/chunk-QDSZTQXL.js.map +1 -0
- package/dist/chunk-QH5KOFNS.js +39 -0
- package/dist/chunk-QH5KOFNS.js.map +1 -0
- package/dist/chunk-QIG4IGUP.js +139 -0
- package/dist/chunk-QIG4IGUP.js.map +1 -0
- package/dist/chunk-QLA25V2K.js +493 -0
- package/dist/chunk-QLA25V2K.js.map +1 -0
- package/dist/chunk-QROYYGWU.js +52 -0
- package/dist/chunk-QROYYGWU.js.map +1 -0
- package/dist/chunk-QYMJHS4K.js +36 -0
- package/dist/chunk-QYMJHS4K.js.map +1 -0
- package/dist/chunk-RHD7RKGI.js +176 -0
- package/dist/chunk-RHD7RKGI.js.map +1 -0
- package/dist/chunk-S2XULQEK.js +52 -0
- package/dist/chunk-S2XULQEK.js.map +1 -0
- package/dist/{chunk-LPOMRC4C.js → chunk-S3ECMF23.js} +11 -3
- package/dist/chunk-S3ECMF23.js.map +1 -0
- package/dist/chunk-S4Y3YTAI.js +35 -0
- package/dist/chunk-S4Y3YTAI.js.map +1 -0
- package/dist/chunk-S4ZGTDSG.js +18 -0
- package/dist/chunk-S4ZGTDSG.js.map +1 -0
- package/dist/{chunk-PSKN344N.js → chunk-T4WJ5VGP.js} +63 -12
- package/dist/chunk-T4WJ5VGP.js.map +1 -0
- package/dist/chunk-TDMHA7C3.js +251 -0
- package/dist/chunk-TDMHA7C3.js.map +1 -0
- package/dist/{chunk-Y45PPBDV.js → chunk-TGLUDQP2.js} +47 -14
- package/dist/chunk-TGLUDQP2.js.map +1 -0
- package/dist/chunk-TLMMFQWM.js +222 -0
- package/dist/chunk-TLMMFQWM.js.map +1 -0
- package/dist/chunk-U6QYTMDB.js +85 -0
- package/dist/chunk-U6QYTMDB.js.map +1 -0
- package/dist/chunk-UMKV7YVQ.js +20 -0
- package/dist/chunk-UMKV7YVQ.js.map +1 -0
- package/dist/chunk-VFYO3UGZ.js +45 -0
- package/dist/chunk-VFYO3UGZ.js.map +1 -0
- package/dist/chunk-W4IK7AWD.js +73 -0
- package/dist/chunk-W4IK7AWD.js.map +1 -0
- package/dist/chunk-WVS6CUCT.js +48 -0
- package/dist/chunk-WVS6CUCT.js.map +1 -0
- package/dist/chunk-Y6KT7ZTR.js +109 -0
- package/dist/chunk-Y6KT7ZTR.js.map +1 -0
- package/dist/chunk-YMUIQRWK.js +44 -0
- package/dist/chunk-YMUIQRWK.js.map +1 -0
- package/dist/chunk-YOA5W5ZH.js +807 -0
- package/dist/chunk-YOA5W5ZH.js.map +1 -0
- package/dist/chunk-YQ2AC4E2.js +59 -0
- package/dist/chunk-YQ2AC4E2.js.map +1 -0
- package/dist/chunk-ZKKO4MHC.js +25 -0
- package/dist/chunk-ZKKO4MHC.js.map +1 -0
- package/dist/chunk-ZNROKDSZ.js +54 -0
- package/dist/chunk-ZNROKDSZ.js.map +1 -0
- package/dist/collapsible-panel.d.ts +96 -17
- package/dist/collapsible-panel.js +104 -27
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/column-track.d.ts +41 -0
- package/dist/column-track.js +4 -0
- package/dist/column-track.js.map +1 -0
- package/dist/combobox.d.ts +40 -0
- package/dist/combobox.js +3 -0
- package/dist/combobox.js.map +1 -0
- package/dist/composer.d.ts +62 -0
- package/dist/composer.js +5 -0
- package/dist/composer.js.map +1 -0
- package/dist/content-item.d.ts +116 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/content-swap.d.ts +34 -0
- package/dist/content-swap.js +3 -0
- package/dist/content-swap.js.map +1 -0
- package/dist/corner-status.d.ts +36 -0
- package/dist/corner-status.js +3 -0
- package/dist/corner-status.js.map +1 -0
- package/dist/css-values.d.ts +127 -0
- package/dist/css-values.js +3 -0
- package/dist/css-values.js.map +1 -0
- package/dist/device-class.js +1 -1
- 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/edge-activity-indicator.d.ts +28 -0
- package/dist/edge-activity-indicator.js +3 -0
- package/dist/edge-activity-indicator.js.map +1 -0
- package/dist/empty-state.d.ts +5 -2
- package/dist/empty-state.js +2 -1
- package/dist/extension-attributes-mu8MFUl0.d.ts +13 -0
- package/dist/file-picker.d.ts +47 -0
- package/dist/file-picker.js +3 -0
- package/dist/file-picker.js.map +1 -0
- package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
- package/dist/floating-toolbar.d.ts +29 -6
- package/dist/floating-toolbar.js +1 -1
- package/dist/framed-list.d.ts +47 -0
- package/dist/framed-list.js +4 -0
- package/dist/framed-list.js.map +1 -0
- package/dist/grid.d.ts +58 -0
- package/dist/grid.js +6 -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/icon-button.d.ts +46 -0
- package/dist/icon-button.js +6 -0
- package/dist/icon-button.js.map +1 -0
- package/dist/icon-toggle-button.d.ts +42 -0
- package/dist/icon-toggle-button.js +6 -0
- package/dist/icon-toggle-button.js.map +1 -0
- package/dist/index.d.ts +59 -20
- package/dist/index.js +66 -29
- package/dist/list-action-row.d.ts +69 -12
- package/dist/list-action-row.js +5 -1
- package/dist/list-header.d.ts +36 -2
- package/dist/list-header.js +4 -1
- package/dist/list-icon-tile-B8dr97OW.d.ts +18 -0
- package/dist/list-inset-control.d.ts +10 -4
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +17 -12
- package/dist/list-inset-text.js +2 -1
- package/dist/list-item.d.ts +49 -5
- package/dist/list-item.js +4 -1
- package/dist/list.d.ts +121 -12
- package/dist/list.js +5 -1
- package/dist/loading-spinner.d.ts +12 -2
- package/dist/loading-spinner.js +2 -1
- package/dist/lucide-icon.d.ts +15 -3
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack-VXTumzKa.d.ts +158 -0
- package/dist/nav-stack.d.ts +15 -38
- package/dist/nav-stack.js +13 -1
- package/dist/pane.d.ts +111 -7
- package/dist/pane.js +2 -1
- package/dist/panel-toolbar-vg6Ir5Dy.d.ts +77 -0
- package/dist/popup-menu-register.d.ts +10 -0
- package/dist/popup-menu-register.js +336 -0
- package/dist/popup-menu-register.js.map +1 -0
- package/dist/popup-menu.d.ts +125 -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 +53 -0
- package/dist/row.js +7 -0
- package/dist/row.js.map +1 -0
- package/dist/scroll-clearance-BikHljTc.d.ts +14 -0
- package/dist/segmented-control.d.ts +7 -4
- package/dist/segmented-control.js +1 -2
- package/dist/select-register.js +255 -3
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +95 -6
- package/dist/select.js +4 -1
- package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
- package/dist/semantic-tone-CdW013KF.d.ts +4 -0
- package/dist/sides-BPSWde0A.d.ts +4 -0
- package/dist/skeleton.d.ts +14 -7
- package/dist/skeleton.js +2 -1
- package/dist/spacer.d.ts +18 -0
- package/dist/spacer.js +4 -0
- package/dist/spacer.js.map +1 -0
- package/dist/split-button.d.ts +57 -0
- package/dist/split-button.js +7 -0
- package/dist/split-button.js.map +1 -0
- package/dist/split-view.d.ts +63 -6
- package/dist/split-view.js +88 -9
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +37 -6
- package/dist/state-banner.js +4 -1
- package/dist/styles/anchored-surface.css +41 -0
- package/dist/styles/app-tab.css +232 -0
- package/dist/styles/badge.css +145 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +14 -0
- package/dist/styles/catalog/components/catalog-example.css +204 -0
- package/dist/styles/catalog/components/catalog-stage.css +61 -0
- package/dist/styles/catalog/components/catalog.css +26 -0
- package/dist/styles/catalog.css +5 -575
- package/dist/styles/chip.css +208 -0
- package/dist/styles/choice-chips.css +154 -0
- package/dist/styles/collapsible-panel.css +450 -16
- package/dist/styles/column-track.css +57 -0
- package/dist/styles/combobox.css +113 -0
- package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
- package/dist/styles/components/actions/icon-button/icon-button.css +22 -0
- package/dist/styles/components/actions/icon-toggle-button/icon-toggle-button.css +83 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +370 -0
- package/dist/styles/components/actions/split-button/split-button.css +95 -0
- package/dist/styles/components/actions/toolbar/toolbar.css +443 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +1069 -0
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +269 -0
- package/dist/styles/components/collections/framed-list/framed-list.css +47 -0
- package/dist/styles/components/collections/list/list.css +250 -0
- package/dist/styles/components/collections/list-action-row/list-action-row.css +466 -0
- package/dist/styles/components/collections/list-header/list-header.css +229 -0
- package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
- package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
- package/dist/styles/components/collections/list-item/list-item.css +461 -0
- package/dist/styles/components/collections/summary-row/summary-row.css +161 -0
- package/dist/styles/components/data-display/value-table/value-table.css +183 -0
- package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +41 -0
- package/dist/styles/components/feedback/badge/badge.css +145 -0
- package/dist/styles/components/feedback/chip/chip.css +208 -0
- package/dist/styles/components/feedback/corner-status/corner-status.css +60 -0
- package/dist/styles/components/feedback/edge-activity-indicator/edge-activity-indicator.css +127 -0
- package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
- package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
- package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +297 -0
- package/dist/styles/components/forms/choice-chips/choice-chips.css +154 -0
- package/dist/styles/components/forms/combobox/combobox.css +113 -0
- package/dist/styles/components/forms/composer/composer.css +100 -0
- package/dist/styles/components/forms/file-picker/file-picker.css +81 -0
- package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
- package/dist/styles/components/forms/select/select.css +455 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +432 -0
- package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
- package/dist/styles/components/layout/column-track/column-track.css +57 -0
- package/dist/styles/components/layout/content-swap/content-swap.css +154 -0
- package/dist/styles/components/layout/grid/grid.css +88 -0
- package/dist/styles/components/layout/pane/pane.css +382 -0
- package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
- package/dist/styles/components/layout/row/row.css +114 -0
- package/dist/styles/components/layout/spacer/spacer.css +11 -0
- package/dist/styles/components/layout/split-view/split-view.css +146 -0
- package/dist/styles/components/layout/workbench/workbench.css +1086 -0
- package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
- package/dist/styles/components/navigation/app-tab/app-tab.css +384 -0
- package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +342 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +197 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +325 -0
- package/dist/styles/components/surfaces/content-item/content-item.css +138 -0
- package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +31 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +425 -0
- package/dist/styles/components/typography/text/text.css +220 -0
- package/dist/styles/composer.css +100 -0
- package/dist/styles/content-item.css +138 -0
- package/dist/styles/content-swap.css +154 -0
- package/dist/styles/corner-status.css +60 -0
- package/dist/styles/document.css +98 -0
- package/dist/styles/edge-activity-indicator.css +127 -0
- package/dist/styles/file-picker.css +81 -0
- package/dist/styles/floating-toolbar.css +87 -6
- package/dist/styles/foundation.css +254 -53
- package/dist/styles/framed-list.css +47 -0
- package/dist/styles/grid.css +88 -0
- package/dist/styles/icon-button.css +22 -0
- package/dist/styles/icon-toggle-button.css +83 -0
- package/dist/styles/layout.css +1 -21
- package/dist/styles/list-action-row.css +323 -17
- package/dist/styles/list-header.css +128 -59
- package/dist/styles/list-inset-control.css +25 -2
- package/dist/styles/list-inset-text.css +27 -12
- package/dist/styles/list-item.css +371 -33
- package/dist/styles/list.css +214 -7
- package/dist/styles/loading-spinner.css +4 -0
- package/dist/styles/lucide-icon.css +9 -0
- package/dist/styles/nav-stack.css +280 -49
- package/dist/styles/pane.css +322 -2
- package/dist/styles/popup-menu.css +370 -0
- package/dist/styles/resizable-region.css +438 -4
- package/dist/styles/row.css +114 -0
- package/dist/styles/segmented-control.css +34 -3
- package/dist/styles/select.css +338 -23
- package/dist/styles/skeleton.css +64 -3
- package/dist/styles/spacer.css +11 -0
- package/dist/styles/split-button.css +95 -0
- package/dist/styles/split-view.css +114 -3
- package/dist/styles/state-banner.css +141 -42
- package/dist/styles/styles.css +22 -1
- package/dist/styles/summary-row.css +161 -0
- package/dist/styles/sunken-panel.css +13 -4
- package/dist/styles/surface-scaffold.css +425 -0
- package/dist/styles/tab-bar.css +161 -9
- package/dist/styles/tab-navigator.css +325 -0
- package/dist/styles/text.css +220 -0
- package/dist/styles/token-search-field.css +202 -59
- package/dist/styles/toolbar-control-group.css +886 -42
- package/dist/styles/toolbar-text.css +184 -7
- package/dist/styles/toolbar.css +363 -17
- package/dist/styles/value-table.css +115 -7
- package/dist/styles/webawesome.css +282 -20
- package/dist/styles/workbench.css +999 -7
- package/dist/summary-row.d.ts +56 -0
- package/dist/summary-row.js +4 -0
- package/dist/summary-row.js.map +1 -0
- package/dist/sunken-panel.d.ts +23 -4
- package/dist/sunken-panel.js +2 -1
- package/dist/surface-scaffold-register.d.ts +9 -0
- package/dist/surface-scaffold-register.js +151 -0
- package/dist/surface-scaffold-register.js.map +1 -0
- package/dist/surface-scaffold.d.ts +170 -0
- package/dist/surface-scaffold.js +4 -0
- package/dist/surface-scaffold.js.map +1 -0
- package/dist/tab-bar.d.ts +31 -6
- package/dist/tab-bar.js +1 -1
- package/dist/tab-navigator.d.ts +114 -0
- package/dist/tab-navigator.js +102 -0
- package/dist/tab-navigator.js.map +1 -0
- package/dist/text.d.ts +98 -0
- package/dist/text.js +3 -0
- package/dist/text.js.map +1 -0
- package/dist/token-search-field.d.ts +3 -59
- package/dist/token-search-field.js +2 -1
- package/dist/token-search-model-aYR0YAei.d.ts +184 -0
- package/dist/token-search-model.d.ts +3 -0
- package/dist/token-search-model.js +3 -0
- package/dist/token-search-model.js.map +1 -0
- package/dist/toolbar-control-group.d.ts +87 -4
- package/dist/toolbar-control-group.js +3 -1
- package/dist/toolbar-text.d.ts +46 -12
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +71 -9
- package/dist/toolbar.js +1 -1
- package/dist/types-CVgIwSdq.d.ts +189 -0
- package/dist/value-table.d.ts +30 -4
- package/dist/value-table.js +2 -1
- package/dist/webawesome.d.ts +8 -1
- package/dist/wire-catalog.d.ts +88 -13
- package/dist/wire-catalog.js +240 -206
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-comboboxes.d.ts +26 -0
- package/dist/wire-comboboxes.js +3 -0
- package/dist/wire-comboboxes.js.map +1 -0
- package/dist/wire-composers.d.ts +16 -0
- package/dist/wire-composers.js +3 -0
- package/dist/wire-composers.js.map +1 -0
- package/dist/wire-content-items.d.ts +11 -0
- package/dist/wire-content-items.js +139 -0
- package/dist/wire-content-items.js.map +1 -0
- package/dist/wire-corner-status.d.ts +11 -0
- package/dist/wire-corner-status.js +3 -0
- package/dist/wire-corner-status.js.map +1 -0
- package/dist/wire-file-pickers.d.ts +26 -0
- package/dist/wire-file-pickers.js +3 -0
- package/dist/wire-file-pickers.js.map +1 -0
- package/dist/wire-list-focus-scroll.d.ts +16 -0
- package/dist/wire-list-focus-scroll.js +3 -0
- package/dist/wire-list-focus-scroll.js.map +1 -0
- package/dist/wire-list-reorder.d.ts +41 -0
- package/dist/wire-list-reorder.js +3 -0
- package/dist/wire-list-reorder.js.map +1 -0
- package/dist/wire-nav-stack.d.ts +4 -1
- package/dist/wire-nav-stack.js +312 -16
- 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 +87 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/wire-sidebar.d.ts +24 -4
- package/dist/wire-sidebar.js +122 -19
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-tab-bars.d.ts +1 -0
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-navigator.d.ts +13 -0
- package/dist/wire-tab-navigator.js +153 -0
- package/dist/wire-tab-navigator.js.map +1 -0
- package/dist/wire-token-search-fields.d.ts +5 -1
- package/dist/wire-token-search-fields.js +2 -1
- package/dist/wire-toolbar-visibility.d.ts +13 -0
- package/dist/wire-toolbar-visibility.js +3 -0
- package/dist/wire-toolbar-visibility.js.map +1 -0
- package/dist/wire-workbench.d.ts +116 -0
- package/dist/wire-workbench.js +6 -0
- package/dist/wire-workbench.js.map +1 -0
- package/dist/workbench.d.ts +253 -10
- package/dist/workbench.js +20 -62
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +617 -32
- package/docs/anchored-surface.md +101 -0
- package/docs/app-layouts.md +159 -10
- package/docs/apple-hig.md +2 -0
- package/docs/catalog.md +403 -110
- package/docs/collapsible-panel.md +272 -16
- package/docs/component-contract.md +700 -79
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +908 -79
- package/docs/composer.md +143 -0
- package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -0
- package/docs/design/templates/choice-chips/color-palette.svg +1 -0
- package/docs/design/templates/choice-chips/compact-icons-dark.svg +1 -0
- package/docs/design/templates/choice-chips/compact-icons.svg +1 -0
- package/docs/design/templates/choice-chips/multiple-dark.svg +1 -0
- package/docs/design/templates/choice-chips/multiple.svg +1 -0
- package/docs/design/templates/choice-chips-dark.svg +1 -0
- package/docs/design/templates/choice-chips.svg +1 -0
- package/docs/design/templates/composer/chat-dark.svg +1 -0
- package/docs/design/templates/composer/chat.svg +1 -0
- package/docs/design/templates/composer/prompt-dark.svg +1 -0
- package/docs/design/templates/composer/prompt.svg +1 -0
- package/docs/design/templates/composer-dark.svg +1 -0
- package/docs/design/templates/composer.svg +1 -0
- package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
- package/docs/design/templates/empty-state/filtered.svg +1 -1
- package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
- package/docs/design/templates/empty-state/with-action.svg +1 -1
- package/docs/design/templates/empty-state-dark.svg +1 -1
- package/docs/design/templates/empty-state.svg +1 -1
- package/docs/design/templates/list/compact-dark.svg +1 -1
- package/docs/design/templates/list/compact.svg +1 -1
- package/docs/design/templates/list/stack-dark.svg +1 -1
- package/docs/design/templates/list/stack.svg +1 -1
- package/docs/design/templates/list-action-row/default-dark.svg +1 -1
- package/docs/design/templates/list-action-row/default.svg +1 -1
- package/docs/design/templates/list-action-row/icon-tile-dark.svg +1 -0
- package/docs/design/templates/list-action-row/icon-tile.svg +1 -0
- package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
- package/docs/design/templates/list-action-row/selected.svg +1 -1
- package/docs/design/templates/list-action-row/trailing-menu-dark.svg +1 -0
- package/docs/design/templates/list-action-row/trailing-menu.svg +1 -0
- package/docs/design/templates/list-action-row-dark.svg +1 -1
- package/docs/design/templates/list-action-row.svg +1 -1
- package/docs/design/templates/list-dark.svg +1 -1
- package/docs/design/templates/list-header/action-dark.svg +1 -1
- package/docs/design/templates/list-header/action.svg +1 -1
- package/docs/design/templates/list-header/count-dark.svg +1 -1
- package/docs/design/templates/list-header/count.svg +1 -1
- package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
- package/docs/design/templates/list-header/inline-action.svg +1 -0
- package/docs/design/templates/list-header/size-l-dark.svg +1 -0
- package/docs/design/templates/list-header/size-l.svg +1 -0
- package/docs/design/templates/list-header/size-m-dark.svg +1 -0
- package/docs/design/templates/list-header/size-m.svg +1 -0
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xl.svg +1 -0
- package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xs.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -1
- package/docs/design/templates/list-header/toggle-collapsed.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
- package/docs/design/templates/list-header-dark.svg +1 -1
- package/docs/design/templates/list-header.svg +1 -1
- package/docs/design/templates/list-item/default-dark.svg +1 -1
- package/docs/design/templates/list-item/default.svg +1 -1
- package/docs/design/templates/list-item/icon-tile-dark.svg +1 -0
- package/docs/design/templates/list-item/icon-tile.svg +1 -0
- package/docs/design/templates/list-item/multiline-dark.svg +1 -1
- package/docs/design/templates/list-item/multiline.svg +1 -1
- package/docs/design/templates/list-item/selected-dark.svg +1 -1
- package/docs/design/templates/list-item/selected.svg +1 -1
- package/docs/design/templates/list-item/trailing-dark.svg +1 -1
- package/docs/design/templates/list-item/trailing.svg +1 -1
- package/docs/design/templates/list-item-dark.svg +1 -1
- package/docs/design/templates/list-item.svg +1 -1
- package/docs/design/templates/list.svg +1 -1
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
- package/docs/design/templates/segmented-control/equal.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small.svg +1 -1
- package/docs/design/templates/segmented-control-dark.svg +1 -1
- package/docs/design/templates/segmented-control.svg +1 -1
- package/docs/design/templates/skeleton-dark.svg +1 -1
- package/docs/design/templates/skeleton.svg +1 -1
- package/docs/design/templates/state-banner/danger-dark.svg +1 -1
- package/docs/design/templates/state-banner/danger.svg +1 -1
- package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
- package/docs/design/templates/state-banner/info-badge.svg +1 -1
- package/docs/design/templates/state-banner/info-dark.svg +1 -1
- package/docs/design/templates/state-banner/info.svg +1 -1
- package/docs/design/templates/state-banner/strip-dark.svg +1 -0
- package/docs/design/templates/state-banner/strip.svg +1 -0
- package/docs/design/templates/state-banner/success-dark.svg +1 -1
- package/docs/design/templates/state-banner/success.svg +1 -1
- package/docs/design/templates/state-banner/warning-dark.svg +1 -1
- package/docs/design/templates/state-banner/warning.svg +1 -1
- package/docs/design/templates/state-banner-dark.svg +1 -1
- package/docs/design/templates/state-banner.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
- package/docs/design/templates/tab-bar-dark.svg +1 -1
- package/docs/design/templates/tab-bar.svg +1 -1
- package/docs/design/templates/token-search-field/empty-dark.svg +1 -1
- package/docs/design/templates/token-search-field/empty.svg +1 -1
- package/docs/design/templates/token-search-field/tokens-dark.svg +1 -1
- package/docs/design/templates/token-search-field/tokens.svg +1 -1
- package/docs/design/templates/token-search-field-dark.svg +1 -1
- package/docs/design/templates/token-search-field.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-tile-brand-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group.svg +1 -1
- package/docs/design/templates/toolbar-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/dark-tone-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/dark-tone.svg +1 -0
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/default.svg +1 -1
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/large.svg +1 -1
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/small.svg +1 -1
- package/docs/design/templates/toolbar-text-dark.svg +1 -1
- package/docs/design/templates/toolbar-text.svg +1 -1
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/design/templates/value-table/details-dark.svg +1 -1
- package/docs/design/templates/value-table/details.svg +1 -1
- package/docs/design/templates/value-table-dark.svg +1 -1
- package/docs/design/templates/value-table.svg +1 -1
- package/docs/design/templates.md +19 -9
- package/docs/design-philosophy.md +58 -11
- package/docs/device-class.md +2 -1
- package/docs/document-baseline.md +93 -0
- package/docs/examples/application-ui-profile.json +8 -8
- package/docs/examples/command-palette-adapter.tsx +9 -7
- package/docs/examples/component-catalog-extension.json +8 -1
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +8 -9
- package/docs/layout.md +764 -40
- package/docs/nav-stack.md +275 -11
- package/docs/recipes.md +125 -69
- package/docs/split-view.md +94 -5
- package/docs/sunken-panel.md +54 -1
- package/docs/surface-scaffold.md +270 -0
- package/docs/tab-navigator.md +255 -0
- package/docs/type-contracts.md +57 -22
- package/docs/ui-analyzer.md +334 -14
- package/docs/ui-doctor.md +207 -10
- package/docs/ui-evaluator.md +17 -0
- package/docs/ux-demo.md +47 -16
- package/docs/webawesome-theme.md +148 -14
- package/docs/workbench.md +600 -11
- package/docs/writing.md +152 -0
- package/doctor/cli.mjs +5 -0
- package/doctor/component-style-checks.mjs +457 -0
- package/doctor/config.schema.json +26 -0
- package/doctor/copy-capitalization-checks.mjs +591 -0
- package/doctor/eslint-diagnostics.d.mts +16 -0
- package/doctor/eslint-diagnostics.mjs +17 -0
- package/doctor/index.d.mts +6 -0
- package/doctor/index.mjs +214 -47
- package/evaluator/index.mjs +73 -8
- package/llms.txt +702 -56
- package/package.json +256 -25
- package/scripts/component-catalog-extension-validation.mjs +28 -0
- package/traversal-exclusions.mjs +60 -1
- package/ux-demo/recipes/app-shell.tsx +181 -189
- package/ux-demo/recipes/collapsible-sidebar.tsx +177 -139
- package/ux-demo/recipes/compact-toolbar.tsx +120 -101
- package/ux-demo/recipes/composer-form.tsx +86 -62
- package/ux-demo/recipes/list-detail-dialog.tsx +219 -114
- package/ux-demo/recipes/list-workspace-states.tsx +95 -80
- package/ux-demo/recipes/loaders.ts +5 -2
- package/ux-demo/recipes/loading-inspector.tsx +157 -117
- package/ux-demo/recipes/mount-recipe.ts +0 -5
- package/ux-demo/recipes/navigation-sidebar.tsx +98 -83
- package/ux-demo/recipes/navigation-stack.tsx +42 -29
- package/ux-demo/recipes/types.ts +14 -1
- package/ux-demo/recipes/workspace-header.tsx +77 -51
- package/vite-ux-review.d.mts +83 -0
- package/vite-ux-review.mjs +120 -0
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/ai/component-catalog-v2.d.ts +0 -67
- package/ai/component-catalog-v2.json +0 -4675
- package/ai/component-catalog-v2.schema.json +0 -246
- package/dist/browser/panel-header.js +0 -7
- package/dist/chunk-5VTB2BKP.js +0 -35
- package/dist/chunk-5VTB2BKP.js.map +0 -1
- package/dist/chunk-6WTETUZ6.js +0 -21
- package/dist/chunk-6WTETUZ6.js.map +0 -1
- package/dist/chunk-7KEUJIIC.js.map +0 -1
- package/dist/chunk-7XRDUG4Y.js +0 -58
- package/dist/chunk-7XRDUG4Y.js.map +0 -1
- package/dist/chunk-B3A3IVO5.js +0 -83
- package/dist/chunk-B3A3IVO5.js.map +0 -1
- package/dist/chunk-DPDBVKNA.js +0 -113
- package/dist/chunk-DPDBVKNA.js.map +0 -1
- package/dist/chunk-FEAMR7S4.js +0 -68
- package/dist/chunk-FEAMR7S4.js.map +0 -1
- package/dist/chunk-FEY65TBV.js +0 -15
- package/dist/chunk-FEY65TBV.js.map +0 -1
- package/dist/chunk-IJBSZ4NX.js.map +0 -1
- package/dist/chunk-J5BFYY7Q.js +0 -35
- package/dist/chunk-J5BFYY7Q.js.map +0 -1
- package/dist/chunk-JRKSK2HX.js.map +0 -1
- package/dist/chunk-KWWR5VMS.js.map +0 -1
- package/dist/chunk-LPOMRC4C.js.map +0 -1
- package/dist/chunk-M7JBER5U.js.map +0 -1
- package/dist/chunk-NENBUYX5.js +0 -79
- package/dist/chunk-NENBUYX5.js.map +0 -1
- package/dist/chunk-NWSEP5RT.js +0 -117
- package/dist/chunk-NWSEP5RT.js.map +0 -1
- package/dist/chunk-OJWWHFH3.js +0 -426
- package/dist/chunk-OJWWHFH3.js.map +0 -1
- package/dist/chunk-PSKN344N.js.map +0 -1
- package/dist/chunk-PX3YSS5C.js.map +0 -1
- package/dist/chunk-QO55FN2Y.js.map +0 -1
- package/dist/chunk-R7ZWUN64.js +0 -38
- package/dist/chunk-R7ZWUN64.js.map +0 -1
- package/dist/chunk-RKVQEH4J.js.map +0 -1
- package/dist/chunk-SRSJO5QE.js.map +0 -1
- package/dist/chunk-SYDMYBPG.js +0 -31
- package/dist/chunk-SYDMYBPG.js.map +0 -1
- package/dist/chunk-TB6DY7H5.js +0 -25
- package/dist/chunk-TB6DY7H5.js.map +0 -1
- package/dist/chunk-UFZKLBCF.js +0 -108
- package/dist/chunk-UFZKLBCF.js.map +0 -1
- package/dist/chunk-UKKSMZYT.js +0 -281
- package/dist/chunk-UKKSMZYT.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js +0 -26
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-W5L2JSBY.js +0 -40
- package/dist/chunk-W5L2JSBY.js.map +0 -1
- package/dist/chunk-Y45PPBDV.js.map +0 -1
- package/dist/chunk-Y6LYKFXY.js.map +0 -1
- package/dist/divider-sides-267FA7sY.d.ts +0 -4
- package/dist/panel-header.d.ts +0 -42
- package/dist/panel-header.js +0 -7
- package/dist/panel-header.js.map +0 -1
- package/dist/styles/panel-header.css +0 -64
- package/dist/styles/tab-scaffold.css +0 -84
- package/dist/tab-scaffold.d.ts +0 -30
- package/dist/tab-scaffold.js +0 -51
- package/dist/tab-scaffold.js.map +0 -1
- package/dist/wire-tab-scaffold.d.ts +0 -11
- package/dist/wire-tab-scaffold.js +0 -21
- package/dist/wire-tab-scaffold.js.map +0 -1
- package/docs/design/templates/panel-header/icon-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-actions.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions.svg +0 -1
- package/docs/design/templates/panel-header/no-icon-dark.svg +0 -1
- package/docs/design/templates/panel-header/no-icon.svg +0 -1
- package/docs/design/templates/panel-header/page-heading-dark.svg +0 -1
- package/docs/design/templates/panel-header/page-heading.svg +0 -1
- package/docs/design/templates/panel-header/title-only-dark.svg +0 -1
- package/docs/design/templates/panel-header/title-only.svg +0 -1
- package/docs/design/templates/panel-header-dark.svg +0 -1
- package/docs/design/templates/panel-header.svg +0 -1
- package/docs/tab-scaffold.md +0 -50
- package/ux-demo/recipes/recipes.css +0 -448
package/dist/wire-sidebar.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { effect, delegate } from 'kerfjs';
|
|
2
2
|
|
|
3
|
-
// src/wire-sidebar.ts
|
|
3
|
+
// src/components/layout/collapsible-panel/wiring/wire-sidebar.ts
|
|
4
4
|
var FOCUSABLE = 'a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
5
5
|
function focusables(panel) {
|
|
6
6
|
return [...panel.querySelectorAll(FOCUSABLE)];
|
|
@@ -12,19 +12,52 @@ function defaultStorage() {
|
|
|
12
12
|
return void 0;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
function wireSidebar(root, {
|
|
15
|
+
function wireSidebar(root, {
|
|
16
|
+
panels,
|
|
17
|
+
deviceClass,
|
|
18
|
+
compactPresentation = "overlay",
|
|
19
|
+
exclusiveCompact = true,
|
|
20
|
+
storage = defaultStorage()
|
|
21
|
+
}) {
|
|
16
22
|
const ownerDocument = root.ownerDocument;
|
|
17
23
|
const byAction = new Map(panels.map((panel) => [panel.toggleAction, panel]));
|
|
18
24
|
const returnFocus = /* @__PURE__ */ new Map();
|
|
19
25
|
const disposers = [];
|
|
26
|
+
const adapting = /* @__PURE__ */ new Set();
|
|
27
|
+
const overlayActive = () => Boolean(deviceClass?.value.compact) && compactPresentation === "overlay";
|
|
28
|
+
let inlineState;
|
|
29
|
+
const setAll = (value) => {
|
|
30
|
+
for (const panel of panels) {
|
|
31
|
+
const next = value(panel);
|
|
32
|
+
if (panel.collapsed.peek() === next) continue;
|
|
33
|
+
adapting.add(panel);
|
|
34
|
+
panel.collapsed.value = next;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const restoreInline = () => {
|
|
38
|
+
const remembered = inlineState;
|
|
39
|
+
if (!remembered) return;
|
|
40
|
+
inlineState = void 0;
|
|
41
|
+
setAll((panel) => remembered.get(panel));
|
|
42
|
+
};
|
|
43
|
+
if (overlayActive()) inlineState = /* @__PURE__ */ new Map();
|
|
44
|
+
for (const panel of panels) {
|
|
45
|
+
const stored = panel.storageKey && storage ? storage.getItem(panel.storageKey) : null;
|
|
46
|
+
const seed = stored === "true" || stored === "false" ? stored === "true" : panel.inlineCollapsed;
|
|
47
|
+
if (inlineState) {
|
|
48
|
+
inlineState.set(panel, seed ?? panel.collapsed.peek());
|
|
49
|
+
panel.collapsed.value = true;
|
|
50
|
+
} else if (seed !== void 0) {
|
|
51
|
+
panel.collapsed.value = seed;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
20
54
|
for (const panel of panels) {
|
|
21
55
|
if (!panel.storageKey || !storage) continue;
|
|
22
|
-
const stored = storage.getItem(panel.storageKey);
|
|
23
|
-
if (stored === "true" || stored === "false")
|
|
24
|
-
panel.collapsed.value = stored === "true";
|
|
25
56
|
disposers.push(
|
|
26
57
|
effect(() => {
|
|
27
|
-
|
|
58
|
+
const collapsed = panel.collapsed.value;
|
|
59
|
+
if (overlayActive()) return;
|
|
60
|
+
storage.setItem(panel.storageKey, String(collapsed));
|
|
28
61
|
})
|
|
29
62
|
);
|
|
30
63
|
}
|
|
@@ -39,9 +72,23 @@ function wireSidebar(root, { panels, deviceClass, storage = defaultStorage() })
|
|
|
39
72
|
const panel = byAction.get(trigger.dataset.action ?? "");
|
|
40
73
|
if (!panel) return;
|
|
41
74
|
returnFocus.set(panel.id, trigger);
|
|
42
|
-
|
|
75
|
+
const next = !panel.collapsed.value;
|
|
76
|
+
panel.collapsed.value = next;
|
|
77
|
+
if (!next && exclusiveCompact && overlayActive()) {
|
|
78
|
+
for (const other of panels)
|
|
79
|
+
if (other !== panel) other.collapsed.value = true;
|
|
80
|
+
}
|
|
43
81
|
})
|
|
44
82
|
);
|
|
83
|
+
const restoreFocus = (panel) => {
|
|
84
|
+
const element = panelElement(panel.id);
|
|
85
|
+
const trigger = returnFocus.get(panel.id);
|
|
86
|
+
const target = trigger?.isConnected && !element?.contains(trigger) ? trigger : [...root.querySelectorAll("[data-action]")].find(
|
|
87
|
+
(candidate) => candidate.dataset.action === panel.toggleAction && !element?.contains(candidate)
|
|
88
|
+
);
|
|
89
|
+
target?.focus();
|
|
90
|
+
return target !== void 0;
|
|
91
|
+
};
|
|
45
92
|
for (const panel of panels) {
|
|
46
93
|
let previous = panel.collapsed.value;
|
|
47
94
|
disposers.push(
|
|
@@ -50,44 +97,98 @@ function wireSidebar(root, { panels, deviceClass, storage = defaultStorage() })
|
|
|
50
97
|
if (collapsed === previous) return;
|
|
51
98
|
previous = collapsed;
|
|
52
99
|
const element = panelElement(panel.id);
|
|
53
|
-
if (
|
|
54
|
-
(
|
|
55
|
-
|
|
56
|
-
|
|
100
|
+
if (adapting.delete(panel)) {
|
|
101
|
+
if (collapsed && element?.contains(ownerDocument.activeElement))
|
|
102
|
+
restoreFocus(panel);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const replaced = deviceClass?.value.compact && compactPresentation === "hidden";
|
|
106
|
+
if (!collapsed && element && !replaced) {
|
|
107
|
+
(focusables(element)[0] ?? element).focus({ preventScroll: true });
|
|
108
|
+
} else if (collapsed && !restoreFocus(panel)) {
|
|
109
|
+
const retry = (frames) => {
|
|
110
|
+
if (!panel.collapsed.peek() || restoreFocus(panel) || frames === 0)
|
|
111
|
+
return;
|
|
112
|
+
globalThis.requestAnimationFrame(() => retry(frames - 1));
|
|
113
|
+
};
|
|
114
|
+
globalThis.queueMicrotask(() => retry(3));
|
|
57
115
|
}
|
|
58
116
|
})
|
|
59
117
|
);
|
|
60
118
|
}
|
|
61
119
|
if (deviceClass) {
|
|
62
120
|
let backdrop;
|
|
121
|
+
let hostResponsive;
|
|
122
|
+
let hostOverlay;
|
|
123
|
+
let backdropFor;
|
|
63
124
|
const openPanel = () => panels.find((panel) => !panel.collapsed.value);
|
|
64
125
|
const removeBackdrop = () => {
|
|
65
126
|
backdrop?.remove();
|
|
66
127
|
backdrop = void 0;
|
|
128
|
+
backdropFor = void 0;
|
|
129
|
+
};
|
|
130
|
+
const setHostData = (name, value) => {
|
|
131
|
+
if (root.dataset[name] === value) return;
|
|
132
|
+
if (value === void 0) delete root.dataset[name];
|
|
133
|
+
else root.dataset[name] = value;
|
|
134
|
+
};
|
|
135
|
+
const syncHost = () => {
|
|
136
|
+
setHostData("collapsibleResponsive", hostResponsive);
|
|
137
|
+
setHostData("collapsibleOverlay", hostOverlay);
|
|
138
|
+
if (!backdrop || backdropFor === void 0) return;
|
|
139
|
+
const element = panelElement(backdropFor);
|
|
140
|
+
if (element && backdrop.nextElementSibling !== element)
|
|
141
|
+
element.parentElement?.insertBefore(backdrop, element);
|
|
67
142
|
};
|
|
68
143
|
disposers.push(
|
|
69
144
|
effect(() => {
|
|
70
145
|
const compact = deviceClass.value.compact;
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
if (
|
|
146
|
+
const overlay = compact && compactPresentation === "overlay";
|
|
147
|
+
for (const panel of panels) void panel.collapsed.value;
|
|
148
|
+
if (overlay && !inlineState) {
|
|
149
|
+
inlineState = new Map(
|
|
150
|
+
panels.map((panel) => [panel, panel.collapsed.peek()])
|
|
151
|
+
);
|
|
152
|
+
setAll(() => true);
|
|
153
|
+
} else if (!overlay) {
|
|
154
|
+
restoreInline();
|
|
155
|
+
}
|
|
156
|
+
const open = overlay ? panels.find((panel) => !panel.collapsed.peek()) : void 0;
|
|
157
|
+
hostResponsive = compact ? compactPresentation : "inline";
|
|
158
|
+
hostOverlay = compact ? String(overlay) : void 0;
|
|
159
|
+
if (open) {
|
|
74
160
|
if (!backdrop) {
|
|
75
161
|
backdrop = ownerDocument.createElement("button");
|
|
76
162
|
backdrop.type = "button";
|
|
77
163
|
backdrop.className = "kui-collapsible-panel__backdrop";
|
|
78
164
|
backdrop.setAttribute("aria-label", "Close");
|
|
79
|
-
backdrop.
|
|
80
|
-
|
|
81
|
-
|
|
165
|
+
backdrop.dataset.morphPreserve = "";
|
|
166
|
+
backdrop.addEventListener("click", () => {
|
|
167
|
+
const current = openPanel();
|
|
168
|
+
if (current) collapse(current);
|
|
169
|
+
});
|
|
82
170
|
}
|
|
171
|
+
backdropFor = open.id;
|
|
83
172
|
} else {
|
|
84
173
|
removeBackdrop();
|
|
85
|
-
if (!compact) delete root.dataset.collapsibleOverlay;
|
|
86
174
|
}
|
|
175
|
+
syncHost();
|
|
87
176
|
})
|
|
88
177
|
);
|
|
178
|
+
const observer = new MutationObserver(syncHost);
|
|
179
|
+
observer.observe(root, {
|
|
180
|
+
attributes: true,
|
|
181
|
+
attributeFilter: [
|
|
182
|
+
"data-collapsible-responsive",
|
|
183
|
+
"data-collapsible-overlay"
|
|
184
|
+
],
|
|
185
|
+
childList: true,
|
|
186
|
+
subtree: true
|
|
187
|
+
});
|
|
188
|
+
disposers.push(() => observer.disconnect());
|
|
89
189
|
const onKeydown = (event) => {
|
|
90
|
-
if (!deviceClass.value.compact)
|
|
190
|
+
if (!deviceClass.value.compact || compactPresentation !== "overlay")
|
|
191
|
+
return;
|
|
91
192
|
const open = openPanel();
|
|
92
193
|
if (!open) return;
|
|
93
194
|
if (event.key === "Escape") {
|
|
@@ -119,7 +220,9 @@ function wireSidebar(root, { panels, deviceClass, storage = defaultStorage() })
|
|
|
119
220
|
}
|
|
120
221
|
return () => {
|
|
121
222
|
for (const dispose of disposers.splice(0)) dispose();
|
|
223
|
+
restoreInline();
|
|
122
224
|
delete root.dataset.collapsibleOverlay;
|
|
225
|
+
delete root.dataset.collapsibleResponsive;
|
|
123
226
|
};
|
|
124
227
|
}
|
|
125
228
|
|
package/dist/wire-sidebar.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wire-sidebar.ts"],"names":[],"mappings":"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","file":"wire-sidebar.js","sourcesContent":["import { delegate, effect, type ReadonlySignal, type Signal } from 'kerfjs';\n\nimport type { DeviceClass } from './device-class.js';\n\n/** Minimal `localStorage`-shaped store, so the persistence hook is testable. */\nexport interface SidebarStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport interface WireSidebarPanel {\n /** The panel id — matches `CollapsiblePanel`'s `id` and a toggle's `panelId`. */\n id: string;\n /** The app-owned collapsed signal. `wireSidebar` reads it (focus, overlay) and\n * writes it (toggle, Escape, backdrop, persistence). */\n collapsed: Signal<boolean>;\n /** `data-action` value the panel's toggle button(s) carry. */\n toggleAction: string;\n /** When set, the collapsed state is loaded from and saved to `storage` under\n * this key (a persistence hook), so the panel remembers its state. */\n storageKey?: string;\n}\n\nexport interface WireSidebarOptions {\n panels: readonly WireSidebarPanel[];\n /**\n * When provided, the sidebar adopts a compact **overlay** presentation while\n * `deviceClass.compact` is true: an open panel floats over the content with a\n * dismissable backdrop, Escape and backdrop-click collapse it, and focus is\n * trapped within the open panel (the ARIA dialog pattern). Without it the panel\n * is always inline.\n */\n deviceClass?: ReadonlySignal<DeviceClass>;\n /** Persistence store (default `globalThis.localStorage`, if present). */\n storage?: SidebarStorage;\n}\n\nconst FOCUSABLE =\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nfunction focusables(panel: HTMLElement): HTMLElement[] {\n // Focus only ever targets an OPEN panel, so the selector (which already drops\n // disabled controls and tabindex=\"-1\") is sufficient without a layout-based\n // visibility check that a headless DOM can't answer.\n return [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)];\n}\n\nfunction defaultStorage(): SidebarStorage | undefined {\n try {\n return globalThis.localStorage ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The reusable sidebar-semantics layer for {@link CollapsiblePanel}s: toggle\n * delegation with focus restore, focus-into on open, an optional compact overlay\n * (backdrop + Escape + focus trap) driven by {@link deviceClass}, and an optional\n * persistence hook. The app owns each `collapsed` signal and the layout; this wire\n * owns the interaction. Returns a disposer. See `docs/24-collapsible-panel.md`.\n */\nexport function wireSidebar(\n root: HTMLElement,\n { panels, deviceClass, storage = defaultStorage() }: WireSidebarOptions,\n): () => void {\n const ownerDocument = root.ownerDocument;\n const byAction = new Map(panels.map((panel) => [panel.toggleAction, panel]));\n const returnFocus = new Map<string, HTMLElement>();\n const disposers: Array<() => void> = [];\n\n // Persistence: seed from storage, then mirror on change.\n for (const panel of panels) {\n if (!panel.storageKey || !storage) continue;\n const stored = storage.getItem(panel.storageKey);\n if (stored === 'true' || stored === 'false')\n panel.collapsed.value = stored === 'true';\n disposers.push(\n effect(() => {\n storage.setItem(panel.storageKey!, String(panel.collapsed.value));\n }),\n );\n }\n\n const panelElement = (id: string): HTMLElement | null =>\n root.querySelector<HTMLElement>(`[data-collapsible-panel=\"${id}\"]`);\n\n const collapse = (panel: WireSidebarPanel): void => {\n if (panel.collapsed.value) return;\n panel.collapsed.value = true;\n };\n\n // Toggle delegation. The trigger is remembered so focus restores to it on close.\n disposers.push(\n delegate(root, 'click', '[data-action]', (_event, element) => {\n const trigger = element as HTMLElement;\n const panel = byAction.get(trigger.dataset.action ?? '');\n if (!panel) return;\n returnFocus.set(panel.id, trigger);\n panel.collapsed.value = !panel.collapsed.value;\n }),\n );\n\n // Focus: move into the panel when it opens; restore to the trigger when it closes.\n for (const panel of panels) {\n let previous = panel.collapsed.value;\n disposers.push(\n effect(() => {\n const collapsed = panel.collapsed.value;\n if (collapsed === previous) return;\n previous = collapsed;\n const element = panelElement(panel.id);\n if (!collapsed && element) {\n (focusables(element)[0] ?? element).focus();\n } else if (collapsed) {\n returnFocus.get(panel.id)?.focus();\n }\n }),\n );\n }\n\n // Compact overlay: a dismissable backdrop + Escape + focus trap while compact\n // and a panel is open.\n if (deviceClass) {\n let backdrop: HTMLButtonElement | undefined;\n const openPanel = (): WireSidebarPanel | undefined =>\n panels.find((panel) => !panel.collapsed.value);\n const removeBackdrop = (): void => {\n backdrop?.remove();\n backdrop = undefined;\n };\n disposers.push(\n effect(() => {\n const compact = deviceClass.value.compact;\n const open = compact ? openPanel() : undefined;\n root.dataset.collapsibleOverlay = String(compact);\n if (compact && open) {\n if (!backdrop) {\n backdrop = ownerDocument.createElement('button');\n backdrop.type = 'button';\n backdrop.className = 'kui-collapsible-panel__backdrop';\n backdrop.setAttribute('aria-label', 'Close');\n backdrop.addEventListener('click', () => collapse(open));\n const element = panelElement(open.id);\n element?.parentElement?.insertBefore(backdrop, element);\n }\n } else {\n removeBackdrop();\n if (!compact) delete root.dataset.collapsibleOverlay;\n }\n }),\n );\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (!deviceClass.value.compact) return;\n const open = openPanel();\n if (!open) return;\n if (event.key === 'Escape') {\n event.preventDefault();\n collapse(open);\n return;\n }\n if (event.key !== 'Tab') return;\n const element = panelElement(open.id);\n if (!element) return;\n const items = focusables(element);\n if (items.length === 0) return;\n const first = items[0]!;\n const last = items[items.length - 1]!;\n const active = ownerDocument.activeElement;\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n ownerDocument.addEventListener('keydown', onKeydown);\n disposers.push(() =>\n ownerDocument.removeEventListener('keydown', onKeydown),\n );\n disposers.push(removeBackdrop);\n }\n\n return () => {\n for (const dispose of disposers.splice(0)) dispose();\n delete root.dataset.collapsibleOverlay;\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/layout/collapsible-panel/wiring/wire-sidebar.ts"],"names":[],"mappings":"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","file":"wire-sidebar.js","sourcesContent":["import { delegate, effect, type ReadonlySignal, type Signal } from 'kerfjs';\n\nimport type { DeviceClass } from '../../../../shared/environment/device-class.js';\n\n/** Minimal `localStorage`-shaped store, so the persistence hook is testable. */\nexport interface SidebarStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n}\n\nexport interface WireSidebarPanel {\n /** The panel id — matches `CollapsiblePanel`'s `id` and a toggle's `panelId`. */\n id: string;\n /** The app-owned collapsed signal. `wireSidebar` reads it (focus, overlay) and\n * writes it (toggle, Escape, backdrop, persistence). */\n collapsed: Signal<boolean>;\n /** `data-action` value the panel's toggle button(s) carry. */\n toggleAction: string;\n /** When set, the panel's inline collapsed state is loaded from and saved to\n * `storage` under this key (a persistence hook), so the panel remembers the\n * user's inline choice. A compact overlay's open/closed state is transient\n * and is never persisted. */\n storageKey?: string;\n /** The panel's inline (non-compact) collapsed state when `storage` holds no\n * choice for it; wire-up seeds the signal with it. Defaults to the signal's\n * own value. Set it when the app seeds the signal from the device class\n * (`signal(device.value.compact)`) so a compact first render already starts\n * collapsed while a later crossing to a wide class still restores this\n * inline default. */\n inlineCollapsed?: boolean;\n}\n\nexport interface WireSidebarOptions {\n panels: readonly WireSidebarPanel[];\n /**\n * When provided, the sidebar adopts a compact **overlay** presentation while\n * `deviceClass.compact` is true: an open panel floats over the content with a\n * dismissable backdrop, Escape and backdrop-click collapse it, and focus is\n * trapped within the open panel (the ARIA dialog pattern). Without it the panel\n * is always inline.\n *\n * An overlay is transient and user-initiated: whenever the compact overlay\n * presentation begins (wire-up on a compact device, or a crossing from a wide\n * class), every panel starts collapsed so nothing blocks the page until the\n * user opens it. The inline state is remembered and restored when the device\n * crosses back to a wide class (and on disposal).\n */\n deviceClass?: ReadonlySignal<DeviceClass>;\n /** Compact devices either overlay the panels (default) or hide them in favor\n * of an application-owned responsive replacement. */\n compactPresentation?: 'overlay' | 'hidden';\n /** Collapse the other panels when one opens in compact overlay mode. */\n exclusiveCompact?: boolean;\n /** Persistence store (default `globalThis.localStorage`, if present). */\n storage?: SidebarStorage;\n}\n\nconst FOCUSABLE =\n 'a[href],area[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex=\"-1\"])';\n\nfunction focusables(panel: HTMLElement): HTMLElement[] {\n // Focus only ever targets an OPEN panel, so the selector (which already drops\n // disabled controls and tabindex=\"-1\") is sufficient without a layout-based\n // visibility check that a headless DOM can't answer.\n return [...panel.querySelectorAll<HTMLElement>(FOCUSABLE)];\n}\n\nfunction defaultStorage(): SidebarStorage | undefined {\n try {\n return globalThis.localStorage ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * The reusable sidebar-semantics layer for {@link CollapsiblePanel}s: toggle\n * delegation with focus restore, focus-into on open, an optional compact overlay\n * (backdrop + Escape + focus trap) driven by {@link deviceClass}, and an optional\n * persistence hook. The app owns each `collapsed` signal and the layout; this wire\n * owns the interaction. Returns a disposer. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.\n */\nexport function wireSidebar(\n root: HTMLElement,\n {\n panels,\n deviceClass,\n compactPresentation = 'overlay',\n exclusiveCompact = true,\n storage = defaultStorage(),\n }: WireSidebarOptions,\n): () => void {\n const ownerDocument = root.ownerDocument;\n const byAction = new Map(panels.map((panel) => [panel.toggleAction, panel]));\n const returnFocus = new Map<string, HTMLElement>();\n const disposers: Array<() => void> = [];\n // Panels whose next collapsed change is presentation-driven, not a user\n // action, so it must not move focus the way a toggle does. A set rather than\n // a flag: writes made inside an effect are batched, so the focus effects run\n // after the writer returns.\n const adapting = new Set<WireSidebarPanel>();\n const overlayActive = (): boolean =>\n Boolean(deviceClass?.value.compact) && compactPresentation === 'overlay';\n\n // Initial-state contract: an overlay is transient and only ever opens on a\n // user action. Entering the overlay presentation (at wire-up or on a wide →\n // compact crossing) remembers each panel's inline state and collapses it;\n // leaving it (compact → wide, or disposal) restores the remembered state.\n let inlineState: Map<WireSidebarPanel, boolean> | undefined;\n const setAll = (value: (panel: WireSidebarPanel) => boolean): void => {\n for (const panel of panels) {\n const next = value(panel);\n if (panel.collapsed.peek() === next) continue;\n adapting.add(panel);\n panel.collapsed.value = next;\n }\n };\n const restoreInline = (): void => {\n const remembered = inlineState;\n if (!remembered) return;\n inlineState = undefined;\n setAll((panel) => remembered.get(panel)!);\n };\n\n // Seed each panel's inline state from storage or `inlineCollapsed`. On a\n // compact overlay device the seed is only remembered: the panel starts\n // collapsed, synchronously and before any effect exists, so the first render\n // after wire-up already has no overlay open.\n if (overlayActive()) inlineState = new Map();\n for (const panel of panels) {\n const stored =\n panel.storageKey && storage ? storage.getItem(panel.storageKey) : null;\n const seed =\n stored === 'true' || stored === 'false'\n ? stored === 'true'\n : panel.inlineCollapsed;\n if (inlineState) {\n inlineState.set(panel, seed ?? panel.collapsed.peek());\n panel.collapsed.value = true;\n } else if (seed !== undefined) {\n panel.collapsed.value = seed;\n }\n }\n\n // Persistence mirrors inline changes only. An overlay's open/closed state is\n // transient, so it is never written.\n for (const panel of panels) {\n if (!panel.storageKey || !storage) continue;\n disposers.push(\n effect(() => {\n const collapsed = panel.collapsed.value;\n if (overlayActive()) return;\n storage.setItem(panel.storageKey!, String(collapsed));\n }),\n );\n }\n\n const panelElement = (id: string): HTMLElement | null =>\n root.querySelector<HTMLElement>(`[data-collapsible-panel=\"${id}\"]`);\n\n const collapse = (panel: WireSidebarPanel): void => {\n if (panel.collapsed.value) return;\n panel.collapsed.value = true;\n };\n\n // Toggle delegation. The trigger is remembered so focus restores to it on close.\n disposers.push(\n delegate(root, 'click', '[data-action]', (_event, element) => {\n const trigger = element as HTMLElement;\n const panel = byAction.get(trigger.dataset.action ?? '');\n if (!panel) return;\n returnFocus.set(panel.id, trigger);\n const next = !panel.collapsed.value;\n panel.collapsed.value = next;\n if (!next && exclusiveCompact && overlayActive()) {\n for (const other of panels)\n if (other !== panel) other.collapsed.value = true;\n }\n }),\n );\n\n // Where focus goes when a panel closes: the trigger that toggled it, unless\n // that trigger sits inside the now-hidden panel (the documented\n // collapse-inside placement) or was re-rendered away. Then it goes to the\n // panel's toggle outside it — the always-visible expand toggle, which an app\n // may render only while the panel is collapsed. Returns whether it moved.\n const restoreFocus = (panel: WireSidebarPanel): boolean => {\n const element = panelElement(panel.id);\n const trigger = returnFocus.get(panel.id);\n const target =\n trigger?.isConnected && !element?.contains(trigger)\n ? trigger\n : [...root.querySelectorAll<HTMLElement>('[data-action]')].find(\n (candidate) =>\n candidate.dataset.action === panel.toggleAction &&\n !element?.contains(candidate),\n );\n target?.focus();\n return target !== undefined;\n };\n\n // Focus: move into the panel when it opens; restore it when it closes.\n for (const panel of panels) {\n let previous = panel.collapsed.value;\n disposers.push(\n effect(() => {\n const collapsed = panel.collapsed.value;\n if (collapsed === previous) return;\n previous = collapsed;\n const element = panelElement(panel.id);\n if (adapting.delete(panel)) {\n // A presentation change, not a user action: only rescue focus that\n // the collapse would strand inside the now-hidden panel.\n if (collapsed && element?.contains(ownerDocument.activeElement))\n restoreFocus(panel);\n return;\n }\n const replaced =\n deviceClass?.value.compact && compactPresentation === 'hidden';\n if (!collapsed && element && !replaced) {\n // Without preventScroll the browser scrolls the panel's clipped,\n // still-sliding content to reveal the focus target, which then\n // unwinds as the slide finishes: the content jumps and drifts back.\n (focusables(element)[0] ?? element).focus({ preventScroll: true });\n } else if (collapsed && !restoreFocus(panel)) {\n // An app that renders after this effect has not produced its\n // expand toggle (or relocated it into its work-area toolbar) yet;\n // look again once the batch settles, then for a few frames.\n const retry = (frames: number): void => {\n if (!panel.collapsed.peek() || restoreFocus(panel) || frames === 0)\n return;\n globalThis.requestAnimationFrame(() => retry(frames - 1));\n };\n globalThis.queueMicrotask(() => retry(3));\n }\n }),\n );\n }\n\n // Compact overlay: a dismissable backdrop + Escape + focus trap while compact\n // and a panel is open.\n if (deviceClass) {\n let backdrop: HTMLButtonElement | undefined;\n // The host state this wire owns, recorded so it can be re-applied: the\n // app re-renders (and morphs) the root for reasons that never touch a\n // panel signal (a nav selection, say), and a morph strips attributes and\n // nodes the template doesn't emit.\n let hostResponsive: string | undefined;\n let hostOverlay: string | undefined;\n let backdropFor: string | undefined;\n const openPanel = (): WireSidebarPanel | undefined =>\n panels.find((panel) => !panel.collapsed.value);\n const removeBackdrop = (): void => {\n backdrop?.remove();\n backdrop = undefined;\n backdropFor = undefined;\n };\n const setHostData = (\n name: 'collapsibleResponsive' | 'collapsibleOverlay',\n value: string | undefined,\n ): void => {\n if (root.dataset[name] === value) return;\n if (value === undefined) delete root.dataset[name];\n else root.dataset[name] = value;\n };\n // Idempotent, so the observer below settles after one corrective write.\n const syncHost = (): void => {\n setHostData('collapsibleResponsive', hostResponsive);\n setHostData('collapsibleOverlay', hostOverlay);\n if (!backdrop || backdropFor === undefined) return;\n const element = panelElement(backdropFor);\n if (element && backdrop.nextElementSibling !== element)\n element.parentElement?.insertBefore(backdrop, element);\n };\n disposers.push(\n effect(() => {\n const compact = deviceClass.value.compact;\n const overlay = compact && compactPresentation === 'overlay';\n // A crossing adapts the panels here, in the same effect that owns the\n // host state. Every panel's state is read so an open or close moves\n // the backdrop; re-renders that touch no panel are covered by the\n // observer below.\n for (const panel of panels) void panel.collapsed.value;\n if (overlay && !inlineState) {\n inlineState = new Map(\n panels.map((panel) => [panel, panel.collapsed.peek()]),\n );\n setAll(() => true);\n } else if (!overlay) {\n restoreInline();\n }\n const open = overlay\n ? panels.find((panel) => !panel.collapsed.peek())\n : undefined;\n hostResponsive = compact ? compactPresentation : 'inline';\n hostOverlay = compact ? String(overlay) : undefined;\n if (open) {\n if (!backdrop) {\n backdrop = ownerDocument.createElement('button');\n backdrop.type = 'button';\n backdrop.className = 'kui-collapsible-panel__backdrop';\n backdrop.setAttribute('aria-label', 'Close');\n // Injected after render: the morph's removal pass must skip it.\n backdrop.dataset.morphPreserve = '';\n backdrop.addEventListener('click', () => {\n const current = openPanel();\n if (current) collapse(current);\n });\n }\n backdropFor = open.id;\n } else {\n removeBackdrop();\n }\n syncHost();\n }),\n );\n const observer = new MutationObserver(syncHost);\n observer.observe(root, {\n attributes: true,\n attributeFilter: [\n 'data-collapsible-responsive',\n 'data-collapsible-overlay',\n ],\n childList: true,\n subtree: true,\n });\n disposers.push(() => observer.disconnect());\n\n const onKeydown = (event: KeyboardEvent): void => {\n if (!deviceClass.value.compact || compactPresentation !== 'overlay')\n return;\n const open = openPanel();\n if (!open) return;\n if (event.key === 'Escape') {\n event.preventDefault();\n collapse(open);\n return;\n }\n if (event.key !== 'Tab') return;\n const element = panelElement(open.id);\n if (!element) return;\n const items = focusables(element);\n if (items.length === 0) return;\n const first = items[0]!;\n const last = items[items.length - 1]!;\n const active = ownerDocument.activeElement;\n if (event.shiftKey && active === first) {\n event.preventDefault();\n last.focus();\n } else if (!event.shiftKey && active === last) {\n event.preventDefault();\n first.focus();\n }\n };\n ownerDocument.addEventListener('keydown', onKeydown);\n disposers.push(() =>\n ownerDocument.removeEventListener('keydown', onKeydown),\n );\n disposers.push(removeBackdrop);\n }\n\n return () => {\n for (const dispose of disposers.splice(0)) dispose();\n // After every effect is gone, so handing the inline state back cannot\n // re-create overlay chrome or persist anything.\n restoreInline();\n delete root.dataset.collapsibleOverlay;\n delete root.dataset.collapsibleResponsive;\n };\n}\n"]}
|
package/dist/wire-tab-bars.d.ts
CHANGED
package/dist/wire-tab-bars.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface WireTabNavigatorOptions {
|
|
2
|
+
/** Invoked with the selected tab id when a bottom-bar tab is activated. */
|
|
3
|
+
onSelect: (tabId: string) => void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Wire a `TabNavigator`'s bottom tab bar: clicking a tab calls `onSelect` with its
|
|
7
|
+
* id (the app then updates its controlled `active`). With
|
|
8
|
+
* `barPresentation="overlay"` it also measures the live bar and lays it over
|
|
9
|
+
* the scenes (see `TabNavigatorProps.barPresentation`). Returns a disposer.
|
|
10
|
+
*/
|
|
11
|
+
declare function wireTabNavigator(root: Element, options: WireTabNavigatorOptions): () => void;
|
|
12
|
+
|
|
13
|
+
export { type WireTabNavigatorOptions, wireTabNavigator };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { delegate } from 'kerfjs';
|
|
2
|
+
|
|
3
|
+
// src/components/navigation/tab-navigator/wiring/wire-tab-navigator.ts
|
|
4
|
+
var BAR_OVERLAY = "data-bar-overlay";
|
|
5
|
+
var BAR_BLOCK_SIZE = "--_kui-tab-scaffold-bar-block-size";
|
|
6
|
+
var BAR_SCROLLBAR_INLINE_SIZE = "--_kui-tab-scaffold-bar-scrollbar-inline-size";
|
|
7
|
+
var NESTED_LAYOUT = ["nav-stack", "split-view", "workbench", "tab-scaffold"].map((name) => `[data-component="${name}"]`).join(", ");
|
|
8
|
+
function paneScroller(pane) {
|
|
9
|
+
if (pane.querySelector(":scope > .kui-pane__footer")) return void 0;
|
|
10
|
+
return pane.querySelector(":scope > .kui-pane__content") ?? void 0;
|
|
11
|
+
}
|
|
12
|
+
function activeScroller(section) {
|
|
13
|
+
const scene = section.querySelector(
|
|
14
|
+
':scope > .kui-tab-scaffold__scenes > .kui-tab-scaffold__scene[data-active="true"]'
|
|
15
|
+
);
|
|
16
|
+
if (!scene) return void 0;
|
|
17
|
+
const only = scene.children.length === 1 ? scene.children[0] : void 0;
|
|
18
|
+
if (!only?.matches(`[data-component="pane"], ${NESTED_LAYOUT}`)) return scene;
|
|
19
|
+
if (only.matches('[data-component="pane"]')) return paneScroller(only);
|
|
20
|
+
if (!only.matches('[data-component="nav-stack"]')) return void 0;
|
|
21
|
+
if (only.querySelector(":scope > [data-nav-stack-bottom]") && only.getAttribute("data-bottom-toolbar-presentation") !== "overlay")
|
|
22
|
+
return void 0;
|
|
23
|
+
const views = [
|
|
24
|
+
...only.querySelectorAll(
|
|
25
|
+
':scope > [data-nav-stack-viewport] > [data-nav-active="true"]:not([data-nav-exiting="true"])'
|
|
26
|
+
)
|
|
27
|
+
];
|
|
28
|
+
const view = views.at(-1);
|
|
29
|
+
if (!view) return void 0;
|
|
30
|
+
const child = view.children.length === 1 ? view.children[0] : void 0;
|
|
31
|
+
if (child?.matches('[data-component="pane"]')) return paneScroller(child);
|
|
32
|
+
return child?.matches(NESTED_LAYOUT) ? void 0 : view;
|
|
33
|
+
}
|
|
34
|
+
function wireBarOverlay(section) {
|
|
35
|
+
const view = section.ownerDocument.defaultView ?? window;
|
|
36
|
+
let bar;
|
|
37
|
+
let size;
|
|
38
|
+
let scroller;
|
|
39
|
+
let scrollbarSize = 0;
|
|
40
|
+
const writeProperty = (name, value) => {
|
|
41
|
+
if (section.style.getPropertyValue(name) === value) return;
|
|
42
|
+
if (value) section.style.setProperty(name, value);
|
|
43
|
+
else section.style.removeProperty(name);
|
|
44
|
+
};
|
|
45
|
+
const publish = () => {
|
|
46
|
+
const measured = bar !== void 0 && size !== void 0;
|
|
47
|
+
writeProperty(BAR_BLOCK_SIZE, measured ? `${size}px` : "");
|
|
48
|
+
writeProperty(
|
|
49
|
+
BAR_SCROLLBAR_INLINE_SIZE,
|
|
50
|
+
measured && scrollbarSize > 0 ? `${scrollbarSize}px` : ""
|
|
51
|
+
);
|
|
52
|
+
if (section.getAttribute("style") === "") section.removeAttribute("style");
|
|
53
|
+
if (measured && section.getAttribute(BAR_OVERLAY) !== "measured")
|
|
54
|
+
section.setAttribute(BAR_OVERLAY, "measured");
|
|
55
|
+
else if (!measured && section.hasAttribute(BAR_OVERLAY))
|
|
56
|
+
section.removeAttribute(BAR_OVERLAY);
|
|
57
|
+
};
|
|
58
|
+
const measureScrollbar = () => {
|
|
59
|
+
if (!scroller) {
|
|
60
|
+
scrollbarSize = 0;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const style = view.getComputedStyle(scroller);
|
|
64
|
+
scrollbarSize = Math.max(
|
|
65
|
+
0,
|
|
66
|
+
scroller.offsetWidth - scroller.clientWidth - (Number.parseFloat(style.borderLeftWidth) || 0) - (Number.parseFloat(style.borderRightWidth) || 0)
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
const resizeObserver = view.ResizeObserver ? new view.ResizeObserver((entries) => {
|
|
70
|
+
for (const entry of entries)
|
|
71
|
+
if (entry.target === bar)
|
|
72
|
+
size = entry.borderBoxSize?.[0]?.blockSize ?? entry.target.getBoundingClientRect().height;
|
|
73
|
+
else if (entry.target === scroller) measureScrollbar();
|
|
74
|
+
publish();
|
|
75
|
+
}) : void 0;
|
|
76
|
+
const sync = () => {
|
|
77
|
+
const next = section.getAttribute("data-bar-presentation") === "overlay" ? section.querySelector(
|
|
78
|
+
":scope > .kui-tab-scaffold__bar"
|
|
79
|
+
) ?? void 0 : void 0;
|
|
80
|
+
if (next !== bar) {
|
|
81
|
+
if (bar) resizeObserver?.unobserve(bar);
|
|
82
|
+
bar = next;
|
|
83
|
+
if (!bar) size = void 0;
|
|
84
|
+
else {
|
|
85
|
+
if (size === void 0 || !resizeObserver)
|
|
86
|
+
size = bar.getBoundingClientRect().height;
|
|
87
|
+
resizeObserver?.observe(bar, { box: "border-box" });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const covered = bar ? activeScroller(section) : void 0;
|
|
91
|
+
if (covered !== scroller) {
|
|
92
|
+
if (scroller) resizeObserver?.unobserve(scroller);
|
|
93
|
+
scroller = covered;
|
|
94
|
+
measureScrollbar();
|
|
95
|
+
if (scroller) resizeObserver?.observe(scroller);
|
|
96
|
+
}
|
|
97
|
+
publish();
|
|
98
|
+
};
|
|
99
|
+
const mutationObserver = new MutationObserver(sync);
|
|
100
|
+
mutationObserver.observe(section, {
|
|
101
|
+
childList: true,
|
|
102
|
+
attributes: true,
|
|
103
|
+
attributeFilter: ["data-bar-presentation", BAR_OVERLAY, "style"]
|
|
104
|
+
});
|
|
105
|
+
const sceneObserver = new MutationObserver(sync);
|
|
106
|
+
const scenes = section.querySelector(":scope > .kui-tab-scaffold__scenes");
|
|
107
|
+
if (scenes)
|
|
108
|
+
sceneObserver.observe(scenes, {
|
|
109
|
+
childList: true,
|
|
110
|
+
subtree: true,
|
|
111
|
+
attributes: true,
|
|
112
|
+
attributeFilter: [
|
|
113
|
+
"data-active",
|
|
114
|
+
"data-nav-active",
|
|
115
|
+
"data-nav-exiting",
|
|
116
|
+
"data-bottom-toolbar-presentation"
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
sync();
|
|
120
|
+
return () => {
|
|
121
|
+
mutationObserver.disconnect();
|
|
122
|
+
sceneObserver.disconnect();
|
|
123
|
+
resizeObserver?.disconnect();
|
|
124
|
+
bar = void 0;
|
|
125
|
+
size = void 0;
|
|
126
|
+
scroller = void 0;
|
|
127
|
+
scrollbarSize = 0;
|
|
128
|
+
publish();
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function wireTabNavigator(root, options) {
|
|
132
|
+
const section = root.matches('[data-component="tab-scaffold"]') ? root : root.querySelector('[data-component="tab-scaffold"]');
|
|
133
|
+
if (!(section instanceof HTMLElement)) return () => {
|
|
134
|
+
};
|
|
135
|
+
const stopClicks = delegate(
|
|
136
|
+
section,
|
|
137
|
+
"click",
|
|
138
|
+
"[data-tab-scaffold-tab]",
|
|
139
|
+
(_event, target) => {
|
|
140
|
+
const tabId = target.getAttribute("data-tab-scaffold-tab");
|
|
141
|
+
if (tabId) options.onSelect(tabId);
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
const stopOverlay = wireBarOverlay(section);
|
|
145
|
+
return () => {
|
|
146
|
+
stopClicks();
|
|
147
|
+
stopOverlay();
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export { wireTabNavigator };
|
|
152
|
+
|
|
153
|
+
//# sourceMappingURL=wire-tab-navigator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/navigation/tab-navigator/wiring/wire-tab-navigator.ts"],"names":[],"mappings":"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","file":"wire-tab-navigator.js","sourcesContent":["import { delegate } from 'kerfjs';\n\n/** On an overlay-bar TabNavigator: the wiring has measured its live bar. */\nconst BAR_OVERLAY = 'data-bar-overlay';\n/** The measured bar's border-box block size, published on the root. */\nconst BAR_BLOCK_SIZE = '--_kui-tab-scaffold-bar-block-size';\n/**\n * The inline size of the active scene's classic (space-taking) vertical\n * scrollbar running beneath the bar, which the bar leaves uncovered. Unset for\n * an overlay scrollbar, which takes no space.\n */\nconst BAR_SCROLLBAR_INLINE_SIZE =\n '--_kui-tab-scaffold-bar-scrollbar-inline-size';\n/** A layout that, as a scene's (or view's) only child, owns its scroller. */\nconst NESTED_LAYOUT = ['nav-stack', 'split-view', 'workbench', 'tab-scaffold']\n .map((name) => `[data-component=\"${name}\"]`)\n .join(', ');\n\n/**\n * A sole Pane's scroller when it reaches the bottom edge: its content, unless\n * a footer sits between the content and the bar.\n */\nfunction paneScroller(pane: Element): HTMLElement | undefined {\n if (pane.querySelector(':scope > .kui-pane__footer')) return undefined;\n return (\n pane.querySelector<HTMLElement>(':scope > .kui-pane__content') ?? undefined\n );\n}\n\n/**\n * The element whose vertical scrollbar runs beneath the bar in the active\n * scene: the scene itself; a sole Pane's content; or, in a sole NavStack\n * without a docked bottom toolbar, its active view (or that view's sole Pane's\n * content). Undefined when chrome (a Pane footer, a docked stack toolbar) or a\n * nested layout's own scroller ends above the bar.\n */\nfunction activeScroller(section: Element): HTMLElement | undefined {\n const scene = section.querySelector<HTMLElement>(\n ':scope > .kui-tab-scaffold__scenes > .kui-tab-scaffold__scene[data-active=\"true\"]',\n );\n if (!scene) return undefined;\n const only = scene.children.length === 1 ? scene.children[0]! : undefined;\n if (!only?.matches(`[data-component=\"pane\"], ${NESTED_LAYOUT}`)) return scene;\n if (only.matches('[data-component=\"pane\"]')) return paneScroller(only);\n if (!only.matches('[data-component=\"nav-stack\"]')) return undefined;\n if (\n only.querySelector(':scope > [data-nav-stack-bottom]') &&\n only.getAttribute('data-bottom-toolbar-presentation') !== 'overlay'\n )\n return undefined;\n const views = [\n ...only.querySelectorAll<HTMLElement>(\n ':scope > [data-nav-stack-viewport] > [data-nav-active=\"true\"]:not([data-nav-exiting=\"true\"])',\n ),\n ];\n const view = views.at(-1);\n if (!view) return undefined;\n const child = view.children.length === 1 ? view.children[0]! : undefined;\n if (child?.matches('[data-component=\"pane\"]')) return paneScroller(child);\n return child?.matches(NESTED_LAYOUT) ? undefined : view;\n}\n\n/**\n * `barPresentation=\"overlay\"`: measure the live tab bar's border box (bottom\n * safe area and its 1px top edge included) and publish it on the root with\n * the gate that lays the bar over the scenes. The size follows the bar as\n * labels wrap, text zooms, or the safe area changes, and a re-render that\n * replaces the bar or strips the published state gets it back before paint.\n */\nfunction wireBarOverlay(section: HTMLElement): () => void {\n const view = section.ownerDocument.defaultView ?? window;\n let bar: HTMLElement | undefined;\n let size: number | undefined;\n let scroller: HTMLElement | undefined;\n let scrollbarSize = 0;\n const writeProperty = (name: string, value: string): void => {\n if (section.style.getPropertyValue(name) === value) return;\n if (value) section.style.setProperty(name, value);\n else section.style.removeProperty(name);\n };\n const publish = (): void => {\n const measured = bar !== undefined && size !== undefined;\n writeProperty(BAR_BLOCK_SIZE, measured ? `${size}px` : '');\n writeProperty(\n BAR_SCROLLBAR_INLINE_SIZE,\n measured && scrollbarSize > 0 ? `${scrollbarSize}px` : '',\n );\n if (section.getAttribute('style') === '') section.removeAttribute('style');\n // The gate changes only when it must, so the observer below settles.\n if (measured && section.getAttribute(BAR_OVERLAY) !== 'measured')\n section.setAttribute(BAR_OVERLAY, 'measured');\n else if (!measured && section.hasAttribute(BAR_OVERLAY))\n section.removeAttribute(BAR_OVERLAY);\n };\n const measureScrollbar = (): void => {\n if (!scroller) {\n scrollbarSize = 0;\n return;\n }\n const style = view.getComputedStyle(scroller);\n scrollbarSize = Math.max(\n 0,\n scroller.offsetWidth -\n scroller.clientWidth -\n (Number.parseFloat(style.borderLeftWidth) || 0) -\n (Number.parseFloat(style.borderRightWidth) || 0),\n );\n };\n const resizeObserver = view.ResizeObserver\n ? new view.ResizeObserver((entries) => {\n for (const entry of entries)\n if (entry.target === bar)\n size =\n entry.borderBoxSize?.[0]?.blockSize ??\n entry.target.getBoundingClientRect().height;\n // A scrollbar appearing or leaving resizes the content box.\n else if (entry.target === scroller) measureScrollbar();\n publish();\n })\n : undefined;\n const sync = (): void => {\n const next =\n section.getAttribute('data-bar-presentation') === 'overlay'\n ? (section.querySelector<HTMLElement>(\n ':scope > .kui-tab-scaffold__bar',\n ) ?? undefined)\n : undefined;\n if (next !== bar) {\n if (bar) resizeObserver?.unobserve(bar);\n bar = next;\n if (!bar) size = undefined;\n else {\n // A replacement keeps the last size until the observer reports it\n // after layout; a first bar (or one with no observer) is measured now.\n if (size === undefined || !resizeObserver)\n size = bar.getBoundingClientRect().height;\n // The border box: a forced-colors edge changes no content box.\n resizeObserver?.observe(bar, { box: 'border-box' });\n }\n }\n // The active scroller changes with the active tab, a stack's push or pop,\n // or a re-render of the scene.\n const covered = bar ? activeScroller(section) : undefined;\n if (covered !== scroller) {\n if (scroller) resizeObserver?.unobserve(scroller);\n scroller = covered;\n measureScrollbar();\n if (scroller) resizeObserver?.observe(scroller);\n }\n publish();\n };\n const mutationObserver = new MutationObserver(sync);\n mutationObserver.observe(section, {\n childList: true,\n attributes: true,\n attributeFilter: ['data-bar-presentation', BAR_OVERLAY, 'style'],\n });\n // Scene switches and nested stack transitions below the root.\n const sceneObserver = new MutationObserver(sync);\n const scenes = section.querySelector(':scope > .kui-tab-scaffold__scenes');\n if (scenes)\n sceneObserver.observe(scenes, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\n 'data-active',\n 'data-nav-active',\n 'data-nav-exiting',\n 'data-bottom-toolbar-presentation',\n ],\n });\n sync();\n return () => {\n mutationObserver.disconnect();\n sceneObserver.disconnect();\n resizeObserver?.disconnect();\n bar = undefined;\n size = undefined;\n scroller = undefined;\n scrollbarSize = 0;\n publish();\n };\n}\n\nexport interface WireTabNavigatorOptions {\n /** Invoked with the selected tab id when a bottom-bar tab is activated. */\n onSelect: (tabId: string) => void;\n}\n\n/**\n * Wire a `TabNavigator`'s bottom tab bar: clicking a tab calls `onSelect` with its\n * id (the app then updates its controlled `active`). With\n * `barPresentation=\"overlay\"` it also measures the live bar and lays it over\n * the scenes (see `TabNavigatorProps.barPresentation`). Returns a disposer.\n */\nexport function wireTabNavigator(\n root: Element,\n options: WireTabNavigatorOptions,\n): () => void {\n const section = root.matches('[data-component=\"tab-scaffold\"]')\n ? root\n : root.querySelector('[data-component=\"tab-scaffold\"]');\n if (!(section instanceof HTMLElement)) return () => {};\n const stopClicks = delegate(\n section,\n 'click',\n '[data-tab-scaffold-tab]',\n (_event, target) => {\n const tabId = target.getAttribute('data-tab-scaffold-tab');\n if (tabId) options.onSelect(tabId);\n },\n );\n const stopOverlay = wireBarOverlay(section);\n return () => {\n stopClicks();\n stopOverlay();\n };\n}\n"]}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Signal } from 'kerfjs';
|
|
2
|
+
import { d as TokenSearchModel } from './token-search-model-aYR0YAei.js';
|
|
3
|
+
import './semantic-content-BbzjvSu9.js';
|
|
2
4
|
|
|
3
5
|
interface TokenSearchSubmit {
|
|
4
6
|
id: string;
|
|
@@ -76,6 +78,8 @@ interface TokenSearchCollapsibleOptions {
|
|
|
76
78
|
signals?: Readonly<Record<string, Signal<boolean>>>;
|
|
77
79
|
}
|
|
78
80
|
interface WireTokenSearchFieldsOptions {
|
|
81
|
+
/** Optional automatic grammar/suggestion models, keyed by TokenSearchField id. */
|
|
82
|
+
models?: Readonly<Record<string, TokenSearchModel>>;
|
|
79
83
|
onSubmit?: (submission: TokenSearchSubmit) => void;
|
|
80
84
|
/** Fired on every editor `input`, after the browser mutates it, so a caller can drop its own `input` listener. */
|
|
81
85
|
onEdit?: (edit: TokenSearchEdit) => void;
|
|
@@ -106,6 +110,6 @@ interface TokenSearchFieldsHandle {
|
|
|
106
110
|
* expand/collapse/focus. Returns a {@link TokenSearchFieldsHandle} — a disposer that also
|
|
107
111
|
* exposes the managed `expanded` state per field id.
|
|
108
112
|
*/
|
|
109
|
-
declare function wireTokenSearchFields(root: HTMLElement, { onSubmit, onEdit, collapsible, keyboard, }?: WireTokenSearchFieldsOptions): TokenSearchFieldsHandle;
|
|
113
|
+
declare function wireTokenSearchFields(root: HTMLElement, { models, onSubmit, onEdit, collapsible, keyboard, }?: WireTokenSearchFieldsOptions): TokenSearchFieldsHandle;
|
|
110
114
|
|
|
111
115
|
export { type TokenSearchCollapsibleOptions, type TokenSearchEdit, type TokenSearchFieldsHandle, type TokenSearchKeyboardOptions, type TokenSearchSubmit, type TokenSearchTokenRemoval, type WireTokenSearchFieldsOptions, wireTokenSearchFields };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Root = HTMLElement | Document;
|
|
2
|
+
/**
|
|
3
|
+
* Wire ToolbarText and ToolbarControlGroup width thresholds below root.
|
|
4
|
+
* Below is strict: hideBelow hides at width < threshold; showBelow hides at
|
|
5
|
+
* width >= threshold. Percentages use the closest Toolbar's content box;
|
|
6
|
+
* em and custom properties use the item's own inherited context. Invalid,
|
|
7
|
+
* negative, unresolved, or contradictory thresholds leave the item visible.
|
|
8
|
+
* This helper changes only a component-owned visibility marker. Existing
|
|
9
|
+
* CSS visibility policies still apply. Dispose with the owning application.
|
|
10
|
+
*/
|
|
11
|
+
declare function wireToolbarVisibility(root: Root): () => void;
|
|
12
|
+
|
|
13
|
+
export { wireToolbarVisibility };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"wire-toolbar-visibility.js"}
|