@kerfjs/ui 5.0.0-beta.8 → 5.0.0-beta.81
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +546 -139
- package/ai/application-ui-diagnostic-ids-v1.json +113 -0
- package/ai/application-ui-profile-sync.cjs +548 -0
- package/ai/application-ui-profile.d.mts +1 -0
- package/ai/application-ui-profile.d.ts +106 -0
- package/ai/application-ui-profile.defaults.json +96 -0
- package/ai/application-ui-profile.mjs +653 -0
- package/ai/application-ui-profile.schema.json +140 -0
- package/ai/catalog-authoring.json +36 -0
- package/ai/catalog-authoring.schema.json +109 -0
- package/ai/compile-time-contracts-v1.json +149 -0
- package/ai/compile-time-contracts-v1.schema.json +52 -0
- package/ai/component-catalog-extension.schema.json +104 -0
- package/ai/component-catalog.json +4280 -457
- package/ai/component-catalog.schema.json +94 -1
- package/ai/component-class-owners.cjs +83 -0
- package/ai/component-composition-extension.d.ts +7 -0
- package/ai/component-composition-extension.schema.json +7 -0
- package/ai/component-composition-rules.json +520 -0
- package/ai/component-composition.d.ts +129 -0
- package/ai/component-composition.json +7401 -0
- package/ai/component-composition.schema.json +408 -0
- package/ai/components/README.md +171 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/chip.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +96 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +75 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/floating-toolbar.md +82 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +100 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +91 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +94 -0
- package/ai/components/list.md +106 -0
- package/ai/components/loading-spinner.md +73 -0
- package/ai/components/lucide-icon.md +97 -0
- package/ai/components/nav-stack.md +105 -0
- package/ai/components/pane.md +104 -0
- package/ai/components/popup-menu.md +171 -0
- package/ai/components/recipe-app-shell.md +57 -0
- package/ai/components/recipe-collapsible-sidebar.md +57 -0
- package/ai/components/recipe-compact-toolbar.md +57 -0
- package/ai/components/recipe-composer-form.md +57 -0
- package/ai/components/recipe-list-detail-dialog.md +57 -0
- package/ai/components/recipe-list-workspace-states.md +57 -0
- package/ai/components/recipe-loading-inspector.md +57 -0
- package/ai/components/recipe-navigation-sidebar.md +57 -0
- package/ai/components/recipe-navigation-stack.md +57 -0
- package/ai/components/recipe-workspace-header.md +57 -0
- package/ai/components/resize.md +106 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +115 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +103 -0
- package/ai/components/state-banner.md +94 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +87 -0
- package/ai/components/tab-bar.md +113 -0
- package/ai/components/tab-navigator.md +95 -0
- package/ai/components/tabs.md +95 -0
- package/ai/components/text.md +87 -0
- package/ai/components/token-search-field.md +107 -0
- package/ai/components/toolbar-control-group.md +121 -0
- package/ai/components/toolbar-text.md +98 -0
- package/ai/components/toolbar.md +101 -0
- package/ai/components/value-table.md +73 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +59 -0
- package/ai/components/wa-button.md +55 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +119 -0
- package/ai/public-api-signatures-v1.md +2821 -250
- package/ai/skill.md +354 -66
- package/ai/webawesome-jsx-signatures-v1.md +9 -2
- package/analyzer/cli.mjs +49 -0
- package/analyzer/component-ownership.d.mts +72 -0
- package/analyzer/component-ownership.mjs +429 -0
- package/analyzer/index.d.mts +53 -0
- package/analyzer/index.mjs +2346 -0
- package/analyzer/loud-pairs.d.mts +49 -0
- package/analyzer/loud-pairs.mjs +357 -0
- package/analyzer/report.schema.json +66 -0
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/catalog-projection-cli.mjs +96 -0
- package/catalog-projection.d.mts +55 -0
- package/catalog-projection.mjs +62 -0
- package/dist/app-tab.d.ts +39 -4
- package/dist/app-tab.js +2 -1
- package/dist/badge.d.ts +54 -0
- package/dist/badge.js +3 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/catalog.js +26 -0
- package/dist/browser/chip.js +3 -0
- package/dist/browser/collapsible-panel.js +9 -0
- package/dist/browser/content-item.js +3 -0
- package/dist/browser/floating-toolbar.js +3 -0
- package/dist/browser/grid.js +3 -0
- package/dist/browser/list-action-row.js +5 -0
- package/dist/browser/{menu-header.js → list-header.js} +5 -3
- package/dist/browser/list-inset-control.js +3 -0
- package/dist/browser/list-inset-text.js +3 -0
- package/dist/browser/list-item.js +5 -0
- package/dist/browser/list.js +3 -0
- package/dist/browser/nav-stack.js +11 -0
- package/dist/browser/pane.js +3 -0
- package/dist/browser/popup-menu.js +3 -0
- package/dist/browser/row.js +3 -0
- package/dist/browser/segmented-control.js +0 -1
- package/dist/browser/select.js +2 -1
- package/dist/browser/spacer.js +3 -0
- package/dist/browser/split-view.js +13 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/browser/sunken-panel.js +3 -0
- package/dist/browser/surface-scaffold.js +3 -0
- package/dist/browser/tab-navigator.js +4 -0
- package/dist/browser/text.js +3 -0
- package/dist/browser/toolbar-control-group.js +1 -0
- package/dist/browser/workbench.js +14 -0
- package/dist/catalog-resources.d.ts +48 -0
- package/dist/catalog-resources.js +22 -0
- package/dist/catalog-resources.js.map +1 -0
- package/dist/catalog.d.ts +92 -0
- package/dist/catalog.js +541 -0
- package/dist/catalog.js.map +1 -0
- package/dist/chip.d.ts +36 -0
- package/dist/chip.js +3 -0
- package/dist/chip.js.map +1 -0
- package/dist/chunk-2GOCOLQL.js +270 -0
- package/dist/chunk-2GOCOLQL.js.map +1 -0
- package/dist/chunk-3CXRQAYT.js +288 -0
- package/dist/chunk-3CXRQAYT.js.map +1 -0
- package/dist/chunk-3RE2JMZU.js +48 -0
- package/dist/chunk-3RE2JMZU.js.map +1 -0
- package/dist/chunk-3SXWV2IR.js +295 -0
- package/dist/chunk-3SXWV2IR.js.map +1 -0
- package/dist/chunk-3XPGJUUQ.js +37 -0
- package/dist/chunk-3XPGJUUQ.js.map +1 -0
- package/dist/chunk-4Y4L5YEI.js +66 -0
- package/dist/chunk-4Y4L5YEI.js.map +1 -0
- package/dist/chunk-5BZBIRQG.js +452 -0
- package/dist/chunk-5BZBIRQG.js.map +1 -0
- package/dist/chunk-5D3WDMIK.js +71 -0
- package/dist/chunk-5D3WDMIK.js.map +1 -0
- package/dist/chunk-62VMNBV2.js +779 -0
- package/dist/chunk-62VMNBV2.js.map +1 -0
- package/dist/chunk-75I3SNUJ.js +44 -0
- package/dist/chunk-75I3SNUJ.js.map +1 -0
- package/dist/chunk-7QQ3HE47.js +17 -0
- package/dist/chunk-7QQ3HE47.js.map +1 -0
- package/dist/chunk-7TE6XDFI.js +91 -0
- package/dist/chunk-7TE6XDFI.js.map +1 -0
- package/dist/chunk-A7DYEERU.js +59 -0
- package/dist/chunk-A7DYEERU.js.map +1 -0
- package/dist/chunk-AN5IWMTM.js +24 -0
- package/dist/chunk-AN5IWMTM.js.map +1 -0
- package/dist/chunk-ARZ4RSQO.js +48 -0
- package/dist/chunk-ARZ4RSQO.js.map +1 -0
- package/dist/chunk-BJLXE56E.js +135 -0
- package/dist/chunk-BJLXE56E.js.map +1 -0
- package/dist/chunk-BYHGRKC3.js +44 -0
- package/dist/chunk-BYHGRKC3.js.map +1 -0
- package/dist/chunk-CEJ5FK6G.js +288 -0
- package/dist/chunk-CEJ5FK6G.js.map +1 -0
- package/dist/chunk-CVKIADIS.js +172 -0
- package/dist/chunk-CVKIADIS.js.map +1 -0
- package/dist/chunk-DQDTZE4W.js +70 -0
- package/dist/chunk-DQDTZE4W.js.map +1 -0
- package/dist/chunk-EFDCALR3.js +66 -0
- package/dist/chunk-EFDCALR3.js.map +1 -0
- package/dist/chunk-FL6J644M.js +116 -0
- package/dist/chunk-FL6J644M.js.map +1 -0
- package/dist/chunk-GS2QD3N7.js +14 -0
- package/dist/chunk-GS2QD3N7.js.map +1 -0
- package/dist/chunk-H45DAZBL.js +491 -0
- package/dist/chunk-H45DAZBL.js.map +1 -0
- package/dist/chunk-H7ZJEI3H.js +52 -0
- package/dist/chunk-H7ZJEI3H.js.map +1 -0
- package/dist/chunk-HFLGWMG3.js +138 -0
- package/dist/chunk-HFLGWMG3.js.map +1 -0
- package/dist/chunk-HFQDSSED.js +188 -0
- package/dist/chunk-HFQDSSED.js.map +1 -0
- package/dist/{chunk-56RJXPHG.js → chunk-I4SDIMFA.js} +7 -4
- package/dist/chunk-I4SDIMFA.js.map +1 -0
- package/dist/chunk-IM3GKYOG.js +202 -0
- package/dist/chunk-IM3GKYOG.js.map +1 -0
- package/dist/chunk-J3AWE5I4.js +50 -0
- package/dist/chunk-J3AWE5I4.js.map +1 -0
- package/dist/chunk-JOR5LGYE.js +55 -0
- package/dist/chunk-JOR5LGYE.js.map +1 -0
- package/dist/chunk-JZM3G6RT.js +149 -0
- package/dist/chunk-JZM3G6RT.js.map +1 -0
- package/dist/{chunk-7BR3DO2A.js → chunk-LAZLBC2Q.js} +14 -5
- package/dist/chunk-LAZLBC2Q.js.map +1 -0
- package/dist/chunk-LQKY5S4F.js +506 -0
- package/dist/chunk-LQKY5S4F.js.map +1 -0
- package/dist/chunk-LRAIS3YB.js +158 -0
- package/dist/chunk-LRAIS3YB.js.map +1 -0
- package/dist/chunk-MXNIVEVL.js +48 -0
- package/dist/chunk-MXNIVEVL.js.map +1 -0
- package/dist/chunk-NJZMR7HM.js +135 -0
- package/dist/chunk-NJZMR7HM.js.map +1 -0
- package/dist/chunk-NMWDHZVM.js +35 -0
- package/dist/chunk-NMWDHZVM.js.map +1 -0
- package/dist/{chunk-YGN7OMLT.js → chunk-NS2TBYM4.js} +8 -5
- package/dist/chunk-NS2TBYM4.js.map +1 -0
- package/dist/chunk-NVKRZ5DI.js +222 -0
- package/dist/chunk-NVKRZ5DI.js.map +1 -0
- package/dist/chunk-NVRJ7C3W.js +83 -0
- package/dist/chunk-NVRJ7C3W.js.map +1 -0
- package/dist/chunk-O27D24CA.js +250 -0
- package/dist/chunk-O27D24CA.js.map +1 -0
- package/dist/chunk-PQQQXJGV.js +58 -0
- package/dist/chunk-PQQQXJGV.js.map +1 -0
- package/dist/chunk-RRCD3A6G.js +139 -0
- package/dist/chunk-RRCD3A6G.js.map +1 -0
- package/dist/chunk-S3ECMF23.js +33 -0
- package/dist/chunk-S3ECMF23.js.map +1 -0
- package/dist/chunk-S4ZGTDSG.js +18 -0
- package/dist/chunk-S4ZGTDSG.js.map +1 -0
- package/dist/chunk-VHXHLZ6R.js +69 -0
- package/dist/chunk-VHXHLZ6R.js.map +1 -0
- package/dist/chunk-VIGVNDXZ.js +165 -0
- package/dist/chunk-VIGVNDXZ.js.map +1 -0
- package/dist/chunk-VR7MWD2X.js +91 -0
- package/dist/chunk-VR7MWD2X.js.map +1 -0
- package/dist/chunk-Y6KT7ZTR.js +109 -0
- package/dist/chunk-Y6KT7ZTR.js.map +1 -0
- package/dist/chunk-YLJ6X3AC.js +34 -0
- package/dist/chunk-YLJ6X3AC.js.map +1 -0
- package/dist/collapsible-panel.d.ts +137 -0
- package/dist/collapsible-panel.js +135 -0
- package/dist/collapsible-panel.js.map +1 -0
- package/dist/content-item.d.ts +99 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/css-values.d.ts +112 -0
- package/dist/css-values.js +3 -0
- package/dist/css-values.js.map +1 -0
- package/dist/device-class.js +34 -6
- package/dist/device-class.js.map +1 -1
- package/dist/disclosure-arrow.d.ts +6 -1
- package/dist/disclosure-arrow.js +2 -1
- package/dist/empty-state.d.ts +5 -2
- package/dist/empty-state.js +2 -1
- package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
- package/dist/floating-toolbar.d.ts +51 -0
- package/dist/floating-toolbar.js +3 -0
- package/dist/floating-toolbar.js.map +1 -0
- package/dist/grid.d.ts +57 -0
- package/dist/grid.js +5 -0
- package/dist/grid.js.map +1 -0
- package/dist/help-tags-register.d.ts +13 -0
- package/dist/help-tags-register.js +9 -0
- package/dist/help-tags-register.js.map +1 -0
- package/dist/index.d.ts +40 -18
- package/dist/index.js +44 -23
- package/dist/{menu-action-row.d.ts → list-action-row.d.ts} +21 -9
- package/dist/list-action-row.js +8 -0
- package/dist/list-action-row.js.map +1 -0
- package/dist/list-header.d.ts +98 -0
- package/dist/list-header.js +10 -0
- package/dist/list-header.js.map +1 -0
- package/dist/list-inset-control.d.ts +22 -0
- package/dist/list-inset-control.js +3 -0
- package/dist/list-inset-control.js.map +1 -0
- package/dist/list-inset-text.d.ts +30 -0
- package/dist/list-inset-text.js +4 -0
- package/dist/list-inset-text.js.map +1 -0
- package/dist/list-item.d.ts +62 -0
- package/dist/list-item.js +8 -0
- package/dist/list-item.js.map +1 -0
- package/dist/list.d.ts +63 -0
- package/dist/list.js +6 -0
- package/dist/list.js.map +1 -0
- package/dist/loading-spinner.d.ts +12 -2
- package/dist/loading-spinner.js +2 -1
- package/dist/lucide-icon.d.ts +14 -2
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack-B1Qc2e5q.d.ts +101 -0
- package/dist/nav-stack.d.ts +13 -38
- package/dist/nav-stack.js +10 -1
- package/dist/pane.d.ts +116 -0
- package/dist/pane.js +4 -0
- package/dist/pane.js.map +1 -0
- package/dist/panel-toolbar-CL9tYOkh.d.ts +72 -0
- package/dist/popup-menu-register.d.ts +9 -0
- package/dist/popup-menu-register.js +244 -0
- package/dist/popup-menu-register.js.map +1 -0
- package/dist/popup-menu.d.ts +100 -0
- package/dist/popup-menu.js +3 -0
- package/dist/popup-menu.js.map +1 -0
- package/dist/resizable-region.d.ts +32 -3
- package/dist/resizable-region.js +1 -1
- package/dist/row.d.ts +48 -0
- package/dist/row.js +6 -0
- package/dist/row.js.map +1 -0
- package/dist/segmented-control.d.ts +12 -9
- package/dist/segmented-control.js +1 -2
- package/dist/select-register.d.ts +5 -1
- package/dist/select-register.js +247 -3
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +103 -8
- package/dist/select.js +3 -1
- package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
- package/dist/semantic-tone-CdW013KF.d.ts +4 -0
- package/dist/sides-BPSWde0A.d.ts +4 -0
- package/dist/skeleton.d.ts +14 -7
- package/dist/skeleton.js +2 -1
- package/dist/spacer.d.ts +18 -0
- package/dist/spacer.js +4 -0
- package/dist/spacer.js.map +1 -0
- package/dist/split-view.d.ts +44 -7
- package/dist/split-view.js +124 -10
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +21 -7
- package/dist/state-banner.js +3 -1
- package/dist/styles/app-tab.css +224 -0
- package/dist/styles/badge.css +118 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +9 -0
- package/dist/styles/catalog/components/catalog-example.css +168 -0
- package/dist/styles/catalog/components/catalog-stage.css +55 -0
- package/dist/styles/catalog/components/catalog.css +50 -0
- package/dist/styles/catalog.css +5 -0
- package/dist/styles/chip.css +138 -0
- package/dist/styles/collapsible-panel.css +580 -0
- package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +285 -0
- package/dist/styles/components/actions/toolbar/toolbar.css +417 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +891 -0
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +171 -0
- package/dist/styles/components/collections/list/list.css +133 -0
- package/dist/styles/components/collections/list-action-row/list-action-row.css +258 -0
- package/dist/styles/components/collections/list-header/list-header.css +229 -0
- package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
- package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
- package/dist/styles/components/collections/list-item/list-item.css +255 -0
- package/dist/styles/components/data-display/value-table/value-table.css +105 -0
- package/dist/styles/components/feedback/badge/badge.css +118 -0
- package/dist/styles/components/feedback/chip/chip.css +138 -0
- package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
- package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
- package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +248 -0
- package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
- package/dist/styles/components/forms/select/select.css +454 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +392 -0
- package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
- package/dist/styles/components/layout/grid/grid.css +85 -0
- package/dist/styles/components/layout/pane/pane.css +294 -0
- package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
- package/dist/styles/components/layout/row/row.css +111 -0
- package/dist/styles/components/layout/spacer/spacer.css +11 -0
- package/dist/styles/components/layout/split-view/split-view.css +146 -0
- package/dist/styles/components/layout/workbench/workbench.css +1075 -0
- package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
- package/dist/styles/components/navigation/app-tab/app-tab.css +376 -0
- package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +242 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +183 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +237 -0
- package/dist/styles/components/surfaces/content-item/content-item.css +120 -0
- package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +34 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +111 -0
- package/dist/styles/components/typography/text/text.css +158 -0
- package/dist/styles/content-item.css +120 -0
- package/dist/styles/document.css +33 -0
- package/dist/styles/floating-toolbar.css +119 -0
- package/dist/styles/foundation.css +187 -45
- package/dist/styles/grid.css +85 -0
- package/dist/styles/layout.css +3 -41
- package/dist/styles/list-action-row.css +258 -0
- package/dist/styles/list-header.css +229 -0
- package/dist/styles/list-inset-control.css +30 -0
- package/dist/styles/list-inset-text.css +29 -0
- package/dist/styles/list-item.css +255 -0
- package/dist/styles/list.css +133 -0
- package/dist/styles/loading-spinner.css +4 -0
- package/dist/styles/lucide-icon.css +9 -0
- package/dist/styles/nav-stack.css +180 -50
- package/dist/styles/pane.css +294 -0
- package/dist/styles/popup-menu.css +285 -0
- package/dist/styles/resizable-region.css +438 -4
- package/dist/styles/row.css +111 -0
- package/dist/styles/segmented-control.css +36 -9
- package/dist/styles/select.css +337 -21
- package/dist/styles/skeleton.css +64 -3
- package/dist/styles/spacer.css +11 -0
- package/dist/styles/split-view.css +114 -3
- package/dist/styles/state-banner.css +94 -19
- package/dist/styles/styles.css +13 -4
- package/dist/styles/sunken-panel.css +34 -0
- package/dist/styles/surface-scaffold.css +111 -0
- package/dist/styles/tab-bar.css +147 -9
- package/dist/styles/tab-navigator.css +237 -0
- package/dist/styles/text.css +158 -0
- package/dist/styles/token-search-field.css +167 -56
- package/dist/styles/toolbar-control-group.css +710 -30
- package/dist/styles/toolbar-text.css +139 -8
- package/dist/styles/toolbar.css +367 -11
- package/dist/styles/value-table.css +34 -4
- package/dist/styles/webawesome.css +388 -16
- package/dist/styles/workbench.css +988 -7
- package/dist/sunken-panel.d.ts +31 -0
- package/dist/sunken-panel.js +3 -0
- package/dist/sunken-panel.js.map +1 -0
- package/dist/surface-scaffold-register.d.ts +4 -0
- package/dist/surface-scaffold-register.js +59 -0
- package/dist/surface-scaffold-register.js.map +1 -0
- package/dist/surface-scaffold.d.ts +38 -0
- package/dist/surface-scaffold.js +3 -0
- package/dist/surface-scaffold.js.map +1 -0
- package/dist/tab-bar.d.ts +39 -6
- package/dist/tab-bar.js +1 -1
- package/dist/tab-navigator.d.ts +86 -0
- package/dist/tab-navigator.js +95 -0
- package/dist/tab-navigator.js.map +1 -0
- package/dist/text.d.ts +63 -0
- package/dist/text.js +3 -0
- package/dist/text.js.map +1 -0
- package/dist/token-search-field.d.ts +3 -43
- package/dist/token-search-field.js +2 -1
- package/dist/token-search-model-DTcTXWMS.d.ts +154 -0
- package/dist/token-search-model.d.ts +3 -0
- package/dist/token-search-model.js +3 -0
- package/dist/token-search-model.js.map +1 -0
- package/dist/toolbar-control-group.d.ts +89 -7
- package/dist/toolbar-control-group.js +3 -1
- package/dist/toolbar-text.d.ts +45 -9
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +59 -7
- package/dist/toolbar.js +1 -1
- package/dist/types-C9BubXfz.d.ts +117 -0
- package/dist/value-table.d.ts +11 -3
- package/dist/value-table.js +2 -1
- package/dist/webawesome.d.ts +8 -1
- package/dist/wire-catalog.d.ts +82 -0
- package/dist/wire-catalog.js +407 -0
- package/dist/wire-catalog.js.map +1 -0
- package/dist/wire-content-items.d.ts +11 -0
- package/dist/wire-content-items.js +114 -0
- package/dist/wire-content-items.js.map +1 -0
- package/dist/wire-nav-stack.d.ts +4 -1
- package/dist/wire-nav-stack.js +191 -15
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-resizable-regions.d.ts +2 -1
- package/dist/wire-resizable-regions.js +2 -1
- package/dist/wire-scroll-dividers.d.ts +72 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/wire-sidebar.d.ts +63 -0
- package/dist/wire-sidebar.js +231 -0
- package/dist/wire-sidebar.js.map +1 -0
- package/dist/wire-tab-bars.d.ts +19 -2
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-navigator.d.ts +11 -0
- package/dist/wire-tab-navigator.js +21 -0
- package/dist/wire-tab-navigator.js.map +1 -0
- package/dist/wire-token-search-fields.d.ts +65 -3
- package/dist/wire-token-search-fields.js +2 -1
- package/dist/wire-toolbar-visibility.d.ts +13 -0
- package/dist/wire-toolbar-visibility.js +3 -0
- package/dist/wire-toolbar-visibility.js.map +1 -0
- package/dist/wire-workbench.d.ts +116 -0
- package/dist/wire-workbench.js +6 -0
- package/dist/wire-workbench.js.map +1 -0
- package/dist/workbench.d.ts +246 -9
- package/dist/workbench.js +17 -15
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +497 -26
- package/docs/app-layouts.md +141 -10
- package/docs/apple-hig.md +1 -0
- package/docs/catalog.md +493 -0
- package/docs/collapsible-panel.md +382 -0
- package/docs/component-contract.md +736 -61
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +619 -97
- package/docs/design/templates/empty-state/filtered-dark.svg +1 -0
- package/docs/design/templates/empty-state/filtered.svg +1 -0
- package/docs/design/templates/empty-state/with-action-dark.svg +1 -0
- package/docs/design/templates/empty-state/with-action.svg +1 -0
- package/docs/design/templates/empty-state-dark.svg +1 -0
- package/docs/design/templates/empty-state.svg +1 -0
- package/docs/design/templates/list/compact-dark.svg +1 -0
- package/docs/design/templates/list/compact.svg +1 -0
- package/docs/design/templates/list/stack-dark.svg +1 -0
- package/docs/design/templates/list/stack.svg +1 -0
- package/docs/design/templates/list-action-row/default-dark.svg +1 -0
- package/docs/design/templates/list-action-row/default.svg +1 -0
- package/docs/design/templates/list-action-row/selected-dark.svg +1 -0
- package/docs/design/templates/list-action-row/selected.svg +1 -0
- package/docs/design/templates/list-action-row-dark.svg +1 -0
- package/docs/design/templates/list-action-row.svg +1 -0
- package/docs/design/templates/list-dark.svg +1 -0
- package/docs/design/templates/list-header/action-dark.svg +1 -0
- package/docs/design/templates/list-header/action.svg +1 -0
- package/docs/design/templates/list-header/count-dark.svg +1 -0
- package/docs/design/templates/list-header/count.svg +1 -0
- package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
- package/docs/design/templates/list-header/inline-action.svg +1 -0
- package/docs/design/templates/list-header/size-l-dark.svg +1 -0
- package/docs/design/templates/list-header/size-l.svg +1 -0
- package/docs/design/templates/list-header/size-m-dark.svg +1 -0
- package/docs/design/templates/list-header/size-m.svg +1 -0
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xl.svg +1 -0
- package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xs.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed.svg +1 -0
- package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -0
- package/docs/design/templates/list-header/toggle-expanded.svg +1 -0
- package/docs/design/templates/list-header-dark.svg +1 -0
- package/docs/design/templates/list-header.svg +1 -0
- package/docs/design/templates/list-item/default-dark.svg +1 -0
- package/docs/design/templates/list-item/default.svg +1 -0
- package/docs/design/templates/list-item/multiline-dark.svg +1 -0
- package/docs/design/templates/list-item/multiline.svg +1 -0
- package/docs/design/templates/list-item/selected-dark.svg +1 -0
- package/docs/design/templates/list-item/selected.svg +1 -0
- package/docs/design/templates/list-item/trailing-dark.svg +1 -0
- package/docs/design/templates/list-item/trailing.svg +1 -0
- package/docs/design/templates/list-item-dark.svg +1 -0
- package/docs/design/templates/list-item.svg +1 -0
- package/docs/design/templates/list.svg +1 -0
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -0
- package/docs/design/templates/segmented-control/equal.svg +1 -0
- package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -0
- package/docs/design/templates/segmented-control/pill-small.svg +1 -0
- package/docs/design/templates/segmented-control-dark.svg +1 -0
- package/docs/design/templates/segmented-control.svg +1 -0
- package/docs/design/templates/skeleton/avatar-dark.svg +1 -0
- package/docs/design/templates/skeleton/avatar.svg +1 -0
- package/docs/design/templates/skeleton/block-dark.svg +1 -0
- package/docs/design/templates/skeleton/block.svg +1 -0
- package/docs/design/templates/skeleton/lines-dark.svg +1 -0
- package/docs/design/templates/skeleton/lines.svg +1 -0
- package/docs/design/templates/skeleton-dark.svg +1 -0
- package/docs/design/templates/skeleton.svg +1 -0
- package/docs/design/templates/state-banner/danger-dark.svg +1 -0
- package/docs/design/templates/state-banner/danger.svg +1 -0
- package/docs/design/templates/state-banner/info-badge-dark.svg +1 -0
- package/docs/design/templates/state-banner/info-badge.svg +1 -0
- package/docs/design/templates/state-banner/info-dark.svg +1 -0
- package/docs/design/templates/state-banner/info.svg +1 -0
- package/docs/design/templates/state-banner/success-dark.svg +1 -0
- package/docs/design/templates/state-banner/success.svg +1 -0
- package/docs/design/templates/state-banner/warning-dark.svg +1 -0
- package/docs/design/templates/state-banner/warning.svg +1 -0
- package/docs/design/templates/state-banner-dark.svg +1 -0
- package/docs/design/templates/state-banner.svg +1 -0
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -0
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -0
- package/docs/design/templates/tab-bar-dark.svg +1 -0
- package/docs/design/templates/tab-bar.svg +1 -0
- package/docs/design/templates/token-search-field/empty-dark.svg +1 -0
- package/docs/design/templates/token-search-field/empty.svg +1 -0
- package/docs/design/templates/token-search-field/tokens-dark.svg +1 -0
- package/docs/design/templates/token-search-field/tokens.svg +1 -0
- package/docs/design/templates/token-search-field-dark.svg +1 -0
- package/docs/design/templates/token-search-field.svg +1 -0
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -0
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-brand-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -0
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group.svg +1 -0
- package/docs/design/templates/toolbar-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/dark-tone-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/dark-tone.svg +1 -0
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/default.svg +1 -0
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/large.svg +1 -0
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/small.svg +1 -0
- package/docs/design/templates/toolbar-text-dark.svg +1 -0
- package/docs/design/templates/toolbar-text.svg +1 -0
- package/docs/design/templates/toolbar.svg +1 -0
- package/docs/design/templates/value-table/details-dark.svg +1 -0
- package/docs/design/templates/value-table/details.svg +1 -0
- package/docs/design/templates/value-table-dark.svg +1 -0
- package/docs/design/templates/value-table.svg +1 -0
- package/docs/design/templates.md +140 -0
- package/docs/design-philosophy.md +48 -20
- package/docs/device-class.md +10 -9
- package/docs/document-baseline.md +42 -0
- package/docs/examples/application-ui-profile.json +60 -0
- package/docs/examples/command-palette-adapter.tsx +69 -17
- package/docs/examples/component-catalog-extension.json +52 -0
- package/docs/examples/component-composition-extension.json +80 -0
- package/docs/layout.md +601 -59
- package/docs/nav-stack.md +154 -14
- package/docs/recipes.md +142 -55
- package/docs/split-view.md +77 -6
- package/docs/sunken-panel.md +93 -0
- package/docs/surface-scaffold.md +74 -0
- package/docs/tab-navigator.md +210 -0
- package/docs/type-contracts.md +135 -0
- package/docs/ui-analyzer.md +404 -0
- package/docs/ui-doctor.md +202 -0
- package/docs/ui-evaluator.md +139 -0
- package/docs/ux-demo.md +46 -16
- package/docs/webawesome-theme.md +188 -16
- package/docs/workbench.md +621 -12
- package/doctor/cli.mjs +120 -0
- package/doctor/component-style-checks.mjs +457 -0
- package/doctor/config.schema.json +94 -0
- package/doctor/eslint-diagnostics.d.mts +24 -0
- package/doctor/eslint-diagnostics.mjs +24 -0
- package/doctor/index.d.mts +122 -0
- package/doctor/index.mjs +1403 -0
- package/doctor/report.schema.json +118 -0
- package/evaluator/cli.mjs +89 -0
- package/evaluator/index.d.mts +90 -0
- package/evaluator/index.mjs +1203 -0
- package/evaluator/report.schema.json +152 -0
- package/llms.txt +510 -49
- package/package.json +266 -44
- package/scripts/component-catalog-extension-validation.mjs +28 -0
- package/traversal-exclusions.mjs +27 -0
- package/ux-demo/recipes/app-shell.tsx +205 -17
- package/ux-demo/recipes/collapsible-sidebar.tsx +260 -0
- package/ux-demo/recipes/compact-toolbar.tsx +135 -14
- package/ux-demo/recipes/composer-form.tsx +133 -21
- package/ux-demo/recipes/list-detail-dialog.tsx +286 -0
- package/ux-demo/recipes/list-workspace-states.tsx +183 -11
- package/ux-demo/recipes/loaders.ts +15 -5
- package/ux-demo/recipes/loading-inspector.tsx +204 -0
- package/ux-demo/recipes/mount-recipe.ts +28 -10
- package/ux-demo/recipes/navigation-sidebar.tsx +139 -13
- package/ux-demo/recipes/navigation-stack.tsx +81 -26
- package/ux-demo/recipes/types.ts +23 -2
- package/ux-demo/recipes/workspace-header.tsx +86 -5
- package/dist/browser/menu-action-row.js +0 -4
- package/dist/browser/menu-item.js +0 -4
- package/dist/browser/panel-header.js +0 -7
- package/dist/chunk-2RJBFNB6.js +0 -172
- package/dist/chunk-2RJBFNB6.js.map +0 -1
- package/dist/chunk-2Z5TWHKQ.js +0 -34
- package/dist/chunk-2Z5TWHKQ.js.map +0 -1
- package/dist/chunk-3YD6ZNRA.js +0 -34
- package/dist/chunk-3YD6ZNRA.js.map +0 -1
- package/dist/chunk-55DATV3A.js +0 -10
- package/dist/chunk-55DATV3A.js.map +0 -1
- package/dist/chunk-56RJXPHG.js.map +0 -1
- package/dist/chunk-7BR3DO2A.js.map +0 -1
- package/dist/chunk-7LDCTU7D.js +0 -134
- package/dist/chunk-7LDCTU7D.js.map +0 -1
- package/dist/chunk-AQNKJRFH.js +0 -79
- package/dist/chunk-AQNKJRFH.js.map +0 -1
- package/dist/chunk-B24C4A6T.js +0 -22
- package/dist/chunk-B24C4A6T.js.map +0 -1
- package/dist/chunk-BLK3UEEI.js +0 -23
- package/dist/chunk-BLK3UEEI.js.map +0 -1
- package/dist/chunk-BNQ2YDV4.js +0 -20
- package/dist/chunk-BNQ2YDV4.js.map +0 -1
- package/dist/chunk-DAFFDO33.js +0 -14
- package/dist/chunk-DAFFDO33.js.map +0 -1
- package/dist/chunk-H6URQGJI.js +0 -42
- package/dist/chunk-H6URQGJI.js.map +0 -1
- package/dist/chunk-I7INRJO4.js +0 -17
- package/dist/chunk-I7INRJO4.js.map +0 -1
- package/dist/chunk-LC3YSAZC.js +0 -39
- package/dist/chunk-LC3YSAZC.js.map +0 -1
- package/dist/chunk-M5JRI6MN.js +0 -27
- package/dist/chunk-M5JRI6MN.js.map +0 -1
- package/dist/chunk-MBR3TYNL.js +0 -14
- package/dist/chunk-MBR3TYNL.js.map +0 -1
- package/dist/chunk-MFKMHK5W.js +0 -10
- package/dist/chunk-MFKMHK5W.js.map +0 -1
- package/dist/chunk-MQIZAD4A.js +0 -227
- package/dist/chunk-MQIZAD4A.js.map +0 -1
- package/dist/chunk-PONXLV5U.js +0 -19
- package/dist/chunk-PONXLV5U.js.map +0 -1
- package/dist/chunk-RUNWEPR4.js +0 -10
- package/dist/chunk-RUNWEPR4.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js +0 -26
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-WVPYVDXY.js +0 -15
- package/dist/chunk-WVPYVDXY.js.map +0 -1
- package/dist/chunk-YGN7OMLT.js.map +0 -1
- package/dist/chunk-YKUUZPED.js +0 -24
- package/dist/chunk-YKUUZPED.js.map +0 -1
- package/dist/menu-action-row.js +0 -5
- package/dist/menu-action-row.js.map +0 -1
- package/dist/menu-header.d.ts +0 -43
- package/dist/menu-header.js +0 -7
- package/dist/menu-header.js.map +0 -1
- package/dist/menu-item.d.ts +0 -33
- package/dist/menu-item.js +0 -5
- package/dist/menu-item.js.map +0 -1
- package/dist/panel-header.d.ts +0 -36
- package/dist/panel-header.js +0 -7
- package/dist/panel-header.js.map +0 -1
- package/dist/styles/menu-action-row.css +0 -160
- package/dist/styles/menu-header.css +0 -160
- package/dist/styles/menu-item.css +0 -123
- package/dist/styles/panel-header.css +0 -64
- package/dist/styles/tab-scaffold.css +0 -84
- package/dist/tab-scaffold.d.ts +0 -30
- package/dist/tab-scaffold.js +0 -16
- package/dist/tab-scaffold.js.map +0 -1
- package/dist/wire-tab-scaffold.d.ts +0 -11
- package/dist/wire-tab-scaffold.js +0 -16
- package/dist/wire-tab-scaffold.js.map +0 -1
- package/docs/tab-scaffold.md +0 -41
- package/ux-demo/recipes/master-detail-dialog.tsx +0 -45
- package/ux-demo/recipes/recipes.css +0 -355
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# CollapsiblePanel + wireSidebar — reusable sidebar / drawer support
|
|
2
|
+
|
|
3
|
+
`@kerfjs/ui/collapsible-panel` and `@kerfjs/ui/wire-sidebar` are the standalone,
|
|
4
|
+
reusable pieces for an app's own **side rails** and **bottom drawers** — the same
|
|
5
|
+
collapse semantics the `Workbench` shell and the catalog sidebar use, but outside
|
|
6
|
+
a full shell so you can dock one panel wherever your layout needs it. They are
|
|
7
|
+
subpath-only, tree-shakeable modules that add nothing to the main barrel.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @kerfjs/ui # kerfjs is a peer
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
A browser bundler that honors the `browser` export condition loads the panel's CSS
|
|
14
|
+
and that of the components it renders (`Pane`, `Toolbar`, `ToolbarControlGroup`,
|
|
15
|
+
`LucideIcon`) with `@kerfjs/ui/collapsible-panel`. Without that condition, import
|
|
16
|
+
`@kerfjs/ui/collapsible-panel.css` plus those stylesheets alongside `foundation.css`.
|
|
17
|
+
|
|
18
|
+
## The pieces
|
|
19
|
+
|
|
20
|
+
- **`CollapsiblePanel({ id, side, collapsed?, size?, label?, tabIndex?, outlined?, children })`** — the
|
|
21
|
+
docked panel: a `'left'` / `'right'` rail or a `'bottom'` drawer. It owns only
|
|
22
|
+
presentation. Collapsing snaps the panel's own size to zero in one reflow while
|
|
23
|
+
the fixed-size content slides out via `transform` (composited, clipped) — never
|
|
24
|
+
a per-frame width/height animation. A bottom drawer anchors that fixed-size
|
|
25
|
+
content to its stable bottom edge, so opening and closing move monotonically
|
|
26
|
+
through the transform alone instead of transitioning from a changing layout
|
|
27
|
+
origin and snapping at the end. The app owns the `collapsed` signal; `size`
|
|
28
|
+
overrides the CSS default width/height.
|
|
29
|
+
Set `tabIndex={0}` to place the labeled outer region in the Tab order, or
|
|
30
|
+
`tabIndex={-1}` for programmatic focus. `outlined` keeps its focus ring visible
|
|
31
|
+
while open, such as for a drop target. A toolbar panel can instead pass these
|
|
32
|
+
options through `pane` to focus its inner `Pane`. A collapsed or
|
|
33
|
+
`presentation="hidden"` region drops the persistent outline and changes an
|
|
34
|
+
explicit tab index to `-1`; expanding restores the requested value. An open
|
|
35
|
+
overlay can still be focused. Omitting both options adds no Tab stop.
|
|
36
|
+
A collapsed panel renders `inert` together with `aria-hidden="true"`, straight
|
|
37
|
+
from `collapsed`, so neither Tab, a pointer, nor assistive technology reaches
|
|
38
|
+
content that has slid out of view, and focusing a control can never scroll
|
|
39
|
+
the clipped content back into view. `inert` does not affect rendering, so the
|
|
40
|
+
slide-out still animates; expanding removes both attributes in the same
|
|
41
|
+
render. `aria-hidden` alone had left the panel's controls focusable inside a
|
|
42
|
+
hidden subtree; it stays beside `inert` so the emptied landmark is hidden
|
|
43
|
+
even from tooling that does not prune inert subtrees. Do not add your own
|
|
44
|
+
`inert`, `aria-hidden`, or `tabindex` to hide the content. The
|
|
45
|
+
`restoreControl` renders outside the panel and stays reachable.
|
|
46
|
+
Reusable shell policies are typed props: `separator`, `collapseMotion`,
|
|
47
|
+
`contentOverflow`, and `presentation`. A collapsed panel may also receive a
|
|
48
|
+
`restoreControl`, which Kerf places at the safe-area-aware `restorePosition`
|
|
49
|
+
corner of the panel's own container (the element holding the panel), never
|
|
50
|
+
of the viewport, so an embedded panel's control stays inside it and scrolls
|
|
51
|
+
with it. While the control shows, that container becomes its containing block
|
|
52
|
+
and isolates its stacking (an app's own `position` on the container still
|
|
53
|
+
wins). The corner is inset by `--kui-collapsible-panel-restore-inset` plus the
|
|
54
|
+
container's edge insets, and it owns that inset, so a `FloatingToolbar` hosting
|
|
55
|
+
the control floats from the corner without adding its own. When the same
|
|
56
|
+
container also holds an expanded inline bottom drawer — a bottom
|
|
57
|
+
`CollapsiblePanel` or a bottom `ResizableRegion` (`axis="vertical"`,
|
|
58
|
+
`edge="start"`) — as a direct child, or inside one of its direct children
|
|
59
|
+
(the app's work-area column), the corner floats that inset above the
|
|
60
|
+
drawer's top edge instead of over the drawer, and returns to the container's
|
|
61
|
+
bottom when the drawer collapses. It follows the drawer through CSS anchor
|
|
62
|
+
positioning, so a drag-resize moves it too; an engine without anchor
|
|
63
|
+
positioning keeps the container's bottom corner. A drawer nested deeper,
|
|
64
|
+
inside the work area's own content, belongs to that content and does not move
|
|
65
|
+
the corner. The corner stacks beneath open overlays: an open overlay is the
|
|
66
|
+
page's top layer, so it covers another panel's restore control as it covers
|
|
67
|
+
the rest of the page, including under the compact overlay's backdrop. The
|
|
68
|
+
control takes `--kui-collapsible-panel-restore-z`, which defaults to two less
|
|
69
|
+
than `--kui-collapsible-panel-overlay-z` (38); the backdrop defaults to one
|
|
70
|
+
less (39), so moving the overlay z-index moves both. While a left or right
|
|
71
|
+
overlay is open (the `wireSidebar` compact overlay, or
|
|
72
|
+
`presentation="overlay"`), the content's floating controls — restore
|
|
73
|
+
corners and any `FloatingToolbar` — are also hidden outright (out of the
|
|
74
|
+
tab order and the accessibility tree), so they never paint over the overlay
|
|
75
|
+
whatever stacking context the app creates; they return as it closes. The
|
|
76
|
+
overlay's own floating controls stay, and a bottom overlay hides nothing. A
|
|
77
|
+
horizontal `presentation="overlay"` `ResizableRegion` does the same for its
|
|
78
|
+
siblings. Escape, a backdrop
|
|
79
|
+
press, or the panel's own close control reveals the control again, and a
|
|
80
|
+
collapsed overlay leaves it clickable. `ResizableRegion`'s `restoreControl`
|
|
81
|
+
follows the same rules, two below `--kui-resizable-region-overlay-z` (39).
|
|
82
|
+
A collapsed `ResizableRegion` likewise renders `inert` and `aria-hidden` on
|
|
83
|
+
the region itself (and `inert` on its `.kui-resizable-region__content`
|
|
84
|
+
wrapper), so its label leaves the accessibility tree with its content; its
|
|
85
|
+
separator is already hidden while collapsed, and the restore control stays
|
|
86
|
+
outside the region. Its `restorePosition` accepts top or bottom start/end
|
|
87
|
+
corners, with typed `restoreInset` for the corner distance. Set
|
|
88
|
+
`restorePlacement="inline"` when the container should place the control in
|
|
89
|
+
normal flow. An inline region's surface uses
|
|
90
|
+
`--kui-resizable-region-background`; an open descendant `PopupMenu` or Web
|
|
91
|
+
Awesome dropdown releases clipping and raises the popup layer for its
|
|
92
|
+
lifecycle. Set `contentOverflow="visible"` for other anchored content that
|
|
93
|
+
must escape the region's content box.
|
|
94
|
+
Overlay presentation also clamps fixed-size animated content to the configured
|
|
95
|
+
responsive overlay maximum, so a remembered desktop size cannot escape a narrow
|
|
96
|
+
viewport.
|
|
97
|
+
- **`CollapsiblePanelToggle({ side, collapsed, action, panelId?, label? })`** and
|
|
98
|
+
**`collapsiblePanelToggleIcon(side, collapsed)`** — the standard toggle
|
|
99
|
+
affordance and its icon convention, so every sidebar reads the same: `PanelLeft*`
|
|
100
|
+
for a left rail, `PanelRight*` for a right rail, `PanelBottom*` for a bottom
|
|
101
|
+
drawer — the `Close` glyph while open, the `Open` glyph while collapsed. Placement
|
|
102
|
+
is the app's: put a collapse toggle in the panel's own header and an expand toggle
|
|
103
|
+
somewhere always-visible (a toolbar) so it is reachable while collapsed.
|
|
104
|
+
- **`wireSidebar(root, { panels, deviceClass?, storage? })`** — the interaction
|
|
105
|
+
semantics. Each `panels` entry is
|
|
106
|
+
`{ id, collapsed, toggleAction, storageKey?, inlineCollapsed? }`. It:
|
|
107
|
+
- **toggles** the panel's `collapsed` signal when any `[data-action=toggleAction]`
|
|
108
|
+
button is clicked, and remembers the trigger;
|
|
109
|
+
- **manages focus** — moves focus into the panel when it opens (without
|
|
110
|
+
scrolling, so the sliding content doesn't jump), and restores it
|
|
111
|
+
to the trigger when it closes. When that trigger is the collapse toggle inside
|
|
112
|
+
the now-hidden panel, focus goes to the panel's toggle outside it instead, so
|
|
113
|
+
an app may render its expand toggle only while the panel is collapsed (one
|
|
114
|
+
control per action, as the recipe does);
|
|
115
|
+
- **presents a compact overlay** when `deviceClass.compact` is true (pass a
|
|
116
|
+
`deviceClass()` signal): the open panel floats over the content with a
|
|
117
|
+
dismissable backdrop, Escape and backdrop-click collapse it, and Tab is trapped
|
|
118
|
+
within the panel (the ARIA dialog pattern). The overlay and its backdrop are
|
|
119
|
+
fixed to the screen; an ancestor that establishes a containing block for
|
|
120
|
+
fixed descendants (such as the catalog's `height: "app"` frame) docks them to
|
|
121
|
+
its edges instead;
|
|
122
|
+
- accepts `compactPresentation: "hidden"` when a compact application replaces
|
|
123
|
+
the panel with different navigation instead of overlaying it;
|
|
124
|
+
- **starts every compact overlay closed** (see
|
|
125
|
+
[Compact initial state](#compact-initial-state));
|
|
126
|
+
- keeps compact overlays exclusive by default, collapsing another open panel
|
|
127
|
+
when a new one opens (`exclusiveCompact: false` opts out);
|
|
128
|
+
- **persists** the inline collapsed state to `storage` (default
|
|
129
|
+
`localStorage`) under `storageKey`, seeding the signal on wire-up. An
|
|
130
|
+
overlay's open/closed state is never persisted;
|
|
131
|
+
- **owns the root's `data-collapsible-responsive` / `data-collapsible-overlay`
|
|
132
|
+
attributes and the injected backdrop.** Your app may re-render (and morph)
|
|
133
|
+
the wired root for reasons that never touch a panel signal — a nav
|
|
134
|
+
selection, say — and the morph drops attributes and nodes its template
|
|
135
|
+
doesn't emit. The wire observes the root and re-applies them before the
|
|
136
|
+
next paint, so don't render these attributes yourself.
|
|
137
|
+
|
|
138
|
+
Returns a disposer. Retain it and call it on teardown.
|
|
139
|
+
|
|
140
|
+
## Panel toolbars and relocated controls
|
|
141
|
+
|
|
142
|
+
Give a panel a `toolbar` (the same roles as a
|
|
143
|
+
[Workbench panel toolbar](workbench.md#panel-toolbars)) and it composes its own
|
|
144
|
+
top toolbar over a `Pane`:
|
|
145
|
+
|
|
146
|
+
- `title` precedes the `leading` zone; `leading`, `center`, and `trailing`
|
|
147
|
+
place groups wherever the open panel needs them;
|
|
148
|
+
- a `ToolbarControlGroup` marked `relocateOnCollapse` stays available in the
|
|
149
|
+
work area when the panel closes; the standard `toggle: { action, name,
|
|
150
|
+
showLabel?, hideLabel? }` is always the final group.
|
|
151
|
+
|
|
152
|
+
Busy groups keep their inert control, spinner, and adjacent live status together
|
|
153
|
+
when relocated. Clearing `busy` restores the same action in its current toolbar;
|
|
154
|
+
expanding the panel returns both control and status to the panel toolbar.
|
|
155
|
+
|
|
156
|
+
The panel can also take `header` under its toolbar, `footer` below its content,
|
|
157
|
+
`bottomToolbar` below that, `headerList` / `footerList` for those fixed content
|
|
158
|
+
stacks, and `headerPlacement` / `footerPlacement` (`fixed`, `scroll`, or `auto`).
|
|
159
|
+
These slots share the panel's one `Pane` scroll owner; the bottom toolbar uses
|
|
160
|
+
footer semantics. With no `toolbar`, the panel renders its children directly
|
|
161
|
+
and ignores the chrome slots.
|
|
162
|
+
|
|
163
|
+
The toolbar also takes the `Toolbar`'s configuration (`dividerSides`,
|
|
164
|
+
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`); it draws no
|
|
165
|
+
divider of its own unless `dividerSides` says so. The `Pane` under it draws
|
|
166
|
+
the line under the toolbar only while its content is scrolled (see
|
|
167
|
+
[Scroll dividers](./layout.md#scroll-dividers)), and takes the panel's `pane`
|
|
168
|
+
(`PaneConfig`: `contentElement`, `contentLabel`, `separators`,
|
|
169
|
+
`safeAreaEdges`, `chromeDividers`) — for example `{ contentElement: "nav",
|
|
170
|
+
contentLabel: "Sections" }` for a navigation rail. An omitted or `undefined`
|
|
171
|
+
field keeps the `Pane` default; without a `toolbar` there is no `Pane`, so
|
|
172
|
+
`pane` is ignored.
|
|
173
|
+
|
|
174
|
+
A standalone panel does not own the rest of the screen, so the app places a
|
|
175
|
+
`CollapsiblePanelRelocated` in its own work-area toolbar: it renders the panel's
|
|
176
|
+
marked groups and toggle while the panel is collapsed, and nothing while it
|
|
177
|
+
is open. Put it first in the leading zone for a left rail, last in the trailing
|
|
178
|
+
zone for a right rail, and last in a bottom toolbar for a bottom drawer. With no
|
|
179
|
+
bottom toolbar, pass it inside a `FloatingToolbar` as the drawer's
|
|
180
|
+
`restoreControl`.
|
|
181
|
+
Marked groups move in `leading`, `center`, `trailing` order. Pass each marked
|
|
182
|
+
group directly or in an array rather than wrapping it in a JSX fragment, so
|
|
183
|
+
the panel can read its render-time annotation. Its copy in the closed panel is
|
|
184
|
+
inert; avoid duplicate `id` attributes on marked groups.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
const toolbar: CollapsiblePanelToolbar = {
|
|
188
|
+
label: "Navigator",
|
|
189
|
+
leading: <NewFileGroup />,
|
|
190
|
+
trailing: <ToolbarControlGroup relocateOnCollapse label="Search files"><SearchButton /></ToolbarControlGroup>,
|
|
191
|
+
toggle: { action: "toggle-nav", name: "navigator" },
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
<Row fill gap="none">
|
|
195
|
+
<CollapsiblePanel id="nav" side="left" collapsed={navCollapsed.value} toolbar={toolbar}>
|
|
196
|
+
<Files />
|
|
197
|
+
</CollapsiblePanel>
|
|
198
|
+
<List flex>
|
|
199
|
+
<Pane
|
|
200
|
+
header={
|
|
201
|
+
<Toolbar
|
|
202
|
+
label="Editor"
|
|
203
|
+
leading={
|
|
204
|
+
<>
|
|
205
|
+
<CollapsiblePanelRelocated panelId="nav" side="left" collapsed={navCollapsed.value} toolbar={toolbar} />
|
|
206
|
+
<ToolbarText text="Editor" size="xlarge" />
|
|
207
|
+
</>
|
|
208
|
+
}
|
|
209
|
+
/>
|
|
210
|
+
}
|
|
211
|
+
>
|
|
212
|
+
<Editor />
|
|
213
|
+
</Pane>
|
|
214
|
+
</List>
|
|
215
|
+
</Row>;
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Wire it with `wireSidebar` (`toggleAction` is the toggle's `action`): closing the
|
|
219
|
+
panel from its own toggle hands focus to the relocated toggle, even when the app
|
|
220
|
+
renders it a frame later, and opening it moves focus into the panel. Each toggle
|
|
221
|
+
carries a stable `data-key`, so the morph never reuses a focused toggle's button
|
|
222
|
+
for another control as it moves.
|
|
223
|
+
|
|
224
|
+
## Compact initial state
|
|
225
|
+
|
|
226
|
+
A compact overlay is transient chrome the user summons, like a slide-over
|
|
227
|
+
sidebar on a phone: it covers the content, traps focus, and must be dismissed.
|
|
228
|
+
It therefore opens **only on a user action** (a toggle, or the app setting the
|
|
229
|
+
signal in response to one), never by itself:
|
|
230
|
+
|
|
231
|
+
- **Wire-up on a compact device.** Every panel starts collapsed, whatever its
|
|
232
|
+
signal, `inlineCollapsed`, or stored choice says. No backdrop, focus trap, or
|
|
233
|
+
Escape handling is active until the user opens a panel.
|
|
234
|
+
- **Wide → compact crossing.** Open panels collapse; nothing covers the page.
|
|
235
|
+
- **Compact → wide crossing.** Each panel returns to its remembered inline state
|
|
236
|
+
(open or collapsed), whatever the user did with the overlay meanwhile.
|
|
237
|
+
- **Disposal** hands the inline state back to the signals.
|
|
238
|
+
- **Persistence** records only the inline choice. A stored "open" rail restores
|
|
239
|
+
inline on a wide screen and is remembered, not opened, on a compact one.
|
|
240
|
+
|
|
241
|
+
These presentation changes never move focus, except to rescue focus that a
|
|
242
|
+
collapse would strand inside the hidden panel (it returns to the panel's last
|
|
243
|
+
trigger). `compactPresentation: "hidden"` leaves the signals alone.
|
|
244
|
+
|
|
245
|
+
`wireSidebar` runs after the first render, so an app that seeds an open inline
|
|
246
|
+
default would render the rail open for that first frame on a compact device.
|
|
247
|
+
Seed the signal from the device class instead, and declare the inline default
|
|
248
|
+
with `inlineCollapsed` so a later wide crossing still opens it:
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
const device = deviceClass();
|
|
252
|
+
const navCollapsed = signal(device.value.compact);
|
|
253
|
+
// …
|
|
254
|
+
wireSidebar(app, {
|
|
255
|
+
panels: [
|
|
256
|
+
{
|
|
257
|
+
id: "nav",
|
|
258
|
+
collapsed: navCollapsed,
|
|
259
|
+
toggleAction: "toggle-nav",
|
|
260
|
+
inlineCollapsed: false,
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
deviceClass: device,
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
A stored inline choice takes precedence over `inlineCollapsed`.
|
|
268
|
+
|
|
269
|
+
## Example
|
|
270
|
+
|
|
271
|
+
```tsx
|
|
272
|
+
import { signal, mount } from "kerfjs";
|
|
273
|
+
import { deviceClass } from "@kerfjs/ui/device-class";
|
|
274
|
+
import {
|
|
275
|
+
CollapsiblePanel,
|
|
276
|
+
CollapsiblePanelToggle,
|
|
277
|
+
} from "@kerfjs/ui/collapsible-panel";
|
|
278
|
+
import { wireSidebar } from "@kerfjs/ui/wire-sidebar";
|
|
279
|
+
|
|
280
|
+
const device = deviceClass();
|
|
281
|
+
// Start collapsed on a compact device; `inlineCollapsed` keeps the open inline
|
|
282
|
+
// default for wide screens.
|
|
283
|
+
const navCollapsed = signal(device.value.compact);
|
|
284
|
+
|
|
285
|
+
const app = document.querySelector("#app")!;
|
|
286
|
+
mount(app, () => (
|
|
287
|
+
<div class="layout">
|
|
288
|
+
<CollapsiblePanel
|
|
289
|
+
id="nav"
|
|
290
|
+
side="left"
|
|
291
|
+
collapsed={navCollapsed.value}
|
|
292
|
+
label="Navigator"
|
|
293
|
+
>
|
|
294
|
+
<header>
|
|
295
|
+
<CollapsiblePanelToggle
|
|
296
|
+
side="left"
|
|
297
|
+
collapsed={navCollapsed.value}
|
|
298
|
+
action="toggle-nav"
|
|
299
|
+
panelId="nav"
|
|
300
|
+
/>
|
|
301
|
+
</header>
|
|
302
|
+
{/* nav items */}
|
|
303
|
+
</CollapsiblePanel>
|
|
304
|
+
<main>
|
|
305
|
+
{navCollapsed.value && (
|
|
306
|
+
<CollapsiblePanelToggle
|
|
307
|
+
side="left"
|
|
308
|
+
collapsed
|
|
309
|
+
action="toggle-nav"
|
|
310
|
+
label="Show navigator"
|
|
311
|
+
/>
|
|
312
|
+
)}
|
|
313
|
+
{/* content */}
|
|
314
|
+
</main>
|
|
315
|
+
</div>
|
|
316
|
+
));
|
|
317
|
+
|
|
318
|
+
const stop = wireSidebar(app, {
|
|
319
|
+
panels: [
|
|
320
|
+
{
|
|
321
|
+
id: "nav",
|
|
322
|
+
collapsed: navCollapsed,
|
|
323
|
+
toggleAction: "toggle-nav",
|
|
324
|
+
storageKey: "app.nav-collapsed",
|
|
325
|
+
inlineCollapsed: false,
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
deviceClass: device,
|
|
329
|
+
});
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## Sizing in a flex layout
|
|
333
|
+
|
|
334
|
+
An expanded panel holds its `size` in a flex row or column (`flex-shrink: 0`):
|
|
335
|
+
its content keeps that fixed size so collapsing slides it out instead of
|
|
336
|
+
squeezing it, and a shrunk track would only clip the content's trailing edge.
|
|
337
|
+
Give the sibling work area `min-width: 0` / `min-height: 0` (a `Pane` or
|
|
338
|
+
`List flex` already has it) so it is the region that gives way, and switch the
|
|
339
|
+
panel to the compact overlay (`wireSidebar`) where the viewport cannot hold it.
|
|
340
|
+
|
|
341
|
+
## Safe areas
|
|
342
|
+
|
|
343
|
+
A panel grows by the unsafe inset of the edge it docks to and pads its content
|
|
344
|
+
for every edge it touches except its interior edge. While expanded inline, it
|
|
345
|
+
also clears that edge for every other direct child of its container, so a
|
|
346
|
+
neighboring pane gains the inset when the panel collapses. When you wrap the panel in your own grid
|
|
347
|
+
cell, pass each sibling `Pane` a `safeAreaEdges` that omits the edge the panel
|
|
348
|
+
covers. See [Choosing an app layout › Safe areas](app-layouts.md#safe-areas).
|
|
349
|
+
|
|
350
|
+
## When to use which
|
|
351
|
+
|
|
352
|
+
- One or two independent rails / a drawer you place yourself → **`CollapsiblePanel` +
|
|
353
|
+
`wireSidebar`**.
|
|
354
|
+
- A whole Xcode-like workspace (left rail + right rail + bottom drawer + work area
|
|
355
|
+
in one shell) → **[`Workbench`](workbench.md)**, which owns the layout and the same
|
|
356
|
+
collapse animation.
|
|
357
|
+
- Drag-to-resize a panel → compose **[`ResizableRegion`](../src/components/layout/resizable-region/resizable-region.tsx)**
|
|
358
|
+
/ `wireResizableRegions`; the app owns the size signal.
|
|
359
|
+
|
|
360
|
+
The app still owns everything domain-specific — which panels exist, their order,
|
|
361
|
+
sizes, content, and any per-project persistence — exactly as with the other layouts.
|
|
362
|
+
|
|
363
|
+
## Recipe and coverage
|
|
364
|
+
|
|
365
|
+
The catalog ships a runnable **Collapsible sidebar** recipe — a left rail and a
|
|
366
|
+
bottom drawer with the standard toggles, the compact overlay, and per-panel
|
|
367
|
+
persistence: [open it](../ux-demo/?component=recipe-collapsible-sidebar) or read
|
|
368
|
+
[`recipes.md`](recipes.md#collapsible-sidebar) · [TSX source](../ux-demo/recipes/collapsible-sidebar.tsx).
|
|
369
|
+
It is covered end-to-end across Chromium, Firefox, and WebKit by
|
|
370
|
+
`tests/browser/collapsible-sidebar-recipe.spec.ts` (collapse/expand, focus
|
|
371
|
+
move/restore, the compact overlay + Escape/backdrop dismiss, the Tab trap, and
|
|
372
|
+
the compact initial state across first load and wide/compact crossings),
|
|
373
|
+
alongside the component/wire unit tests.
|
|
374
|
+
|
|
375
|
+
The focused [CollapsiblePanel route](../ux-demo/?component=collapsible-panel)
|
|
376
|
+
([TSX source](../ux-demo/demos/collapsible-panel.tsx)) also has a **Restore
|
|
377
|
+
control** example: a bottom drawer that starts collapsed, with a
|
|
378
|
+
`FloatingToolbar` `restoreControl` in its frame's bottom-end corner and its
|
|
379
|
+
own hide toggle in the drawer header. Both toggles share one `data-action`,
|
|
380
|
+
and the catalog wires them with `wireSidebar`, so the corner control really
|
|
381
|
+
restores the drawer and focus moves between the two. It is covered by
|
|
382
|
+
`tests/browser/app-layout-catalog.spec.ts` at wide and compact widths.
|