@kerfjs/ui 5.0.0-beta.97 → 5.0.0-beta.99
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 +42 -1
- package/ai/application-ui-diagnostic-ids-v1.json +1 -0
- package/ai/component-catalog.json +487 -66
- package/ai/component-catalog.schema.json +1 -1
- package/ai/component-composition-rules.json +22 -2
- package/ai/component-composition.json +360 -33
- package/ai/component-composition.schema.json +1 -1
- package/ai/components/README.md +18 -17
- package/ai/components/anchored-surface.md +13 -0
- package/ai/components/application-tabs.md +1 -1
- package/ai/components/chip.md +9 -5
- package/ai/components/choice-chips.md +15 -8
- package/ai/components/collapsible-panel.md +3 -2
- package/ai/components/composer.md +83 -0
- package/ai/components/content-item.md +2 -2
- package/ai/components/corner-status.md +1 -1
- package/ai/components/document-baseline.md +3 -3
- package/ai/components/foundation.md +2 -2
- package/ai/components/layout.md +1 -1
- package/ai/components/list-action-row.md +5 -1
- package/ai/components/list-item.md +5 -1
- package/ai/components/list.md +19 -3
- package/ai/components/nav-stack.md +11 -2
- package/ai/components/pane.md +13 -4
- package/ai/components/popup-menu.md +4 -4
- package/ai/components/recipe-app-shell.md +3 -3
- package/ai/components/recipe-collapsible-sidebar.md +3 -3
- package/ai/components/recipe-compact-toolbar.md +1 -1
- package/ai/components/recipe-composer-form.md +3 -3
- package/ai/components/recipe-list-detail-dialog.md +2 -2
- package/ai/components/recipe-list-workspace-states.md +3 -3
- package/ai/components/recipe-loading-inspector.md +1 -1
- package/ai/components/recipe-navigation-sidebar.md +3 -3
- package/ai/components/recipe-navigation-stack.md +3 -3
- package/ai/components/recipe-workspace-header.md +3 -3
- package/ai/components/resize.md +2 -2
- package/ai/components/split-view.md +4 -2
- package/ai/components/sunken-panel.md +2 -2
- package/ai/components/surface-scaffold.md +15 -3
- package/ai/components/tab-bar.md +1 -0
- package/ai/components/tab-navigator.md +4 -0
- package/ai/components/toolbar-control-group.md +2 -0
- package/ai/components/toolbar-text.md +1 -0
- package/ai/components/toolbar.md +1 -0
- package/ai/components/workbench.md +1 -0
- package/ai/public-api-signatures-v1.md +504 -80
- package/ai/skill.md +41 -14
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/component-ownership.mjs +1 -1
- package/analyzer/index.mjs +41 -14
- package/dist/anchored-surface.d.ts +30 -2
- package/dist/anchored-surface.js +1 -1
- package/dist/app-tab.js +1 -1
- package/dist/browser/composer.js +4 -0
- package/dist/catalog-resources.d.ts +3 -2
- package/dist/catalog-resources.js +4 -4
- package/dist/catalog-resources.js.map +1 -1
- package/dist/catalog.d.ts +39 -8
- package/dist/catalog.js +55 -32
- package/dist/catalog.js.map +1 -1
- package/dist/chip.d.ts +41 -9
- package/dist/chip.js +1 -1
- package/dist/choice-chips.d.ts +40 -16
- package/dist/choice-chips.js +1 -1
- package/dist/chunk-34U4ANDJ.js +119 -0
- package/dist/chunk-34U4ANDJ.js.map +1 -0
- package/dist/{chunk-36TL6BCR.js → chunk-3GLYIIFR.js} +34 -6
- package/dist/chunk-3GLYIIFR.js.map +1 -0
- package/dist/{chunk-HWY4BSLS.js → chunk-3VXDSIBJ.js} +2 -2
- package/dist/{chunk-HWY4BSLS.js.map → chunk-3VXDSIBJ.js.map} +1 -1
- package/dist/chunk-3WYREXW4.js +120 -0
- package/dist/chunk-3WYREXW4.js.map +1 -0
- package/dist/chunk-AV7CPAPT.js +82 -0
- package/dist/chunk-AV7CPAPT.js.map +1 -0
- package/dist/{chunk-XK4E225T.js → chunk-B53PS2LE.js} +2 -2
- package/dist/{chunk-XK4E225T.js.map → chunk-B53PS2LE.js.map} +1 -1
- package/dist/{chunk-R42D2BAO.js → chunk-CA7LNX3J.js} +2 -2
- package/dist/{chunk-R42D2BAO.js.map → chunk-CA7LNX3J.js.map} +1 -1
- package/dist/{chunk-AYHC62OZ.js → chunk-CMETHPKR.js} +26 -29
- package/dist/chunk-CMETHPKR.js.map +1 -0
- package/dist/{chunk-Y43B6DS3.js → chunk-CVD5IZGB.js} +2 -2
- package/dist/{chunk-Y43B6DS3.js.map → chunk-CVD5IZGB.js.map} +1 -1
- package/dist/{chunk-6STQXRT4.js → chunk-CXZXHZTR.js} +121 -12
- package/dist/chunk-CXZXHZTR.js.map +1 -0
- package/dist/{chunk-GZE2XVKC.js → chunk-DZJ4GBSP.js} +3 -3
- package/dist/{chunk-GZE2XVKC.js.map → chunk-DZJ4GBSP.js.map} +1 -1
- package/dist/chunk-ELCMSQNJ.js +49 -0
- package/dist/chunk-ELCMSQNJ.js.map +1 -0
- package/dist/{chunk-P74VXMB6.js → chunk-EOO6PYGF.js} +7 -14
- package/dist/chunk-EOO6PYGF.js.map +1 -0
- package/dist/{chunk-PRG4CL3Q.js → chunk-FR76ZJQC.js} +21 -19
- package/dist/chunk-FR76ZJQC.js.map +1 -0
- package/dist/{chunk-QQ3TTWFH.js → chunk-G3J7JDP6.js} +1 -1
- package/dist/{chunk-QQ3TTWFH.js.map → chunk-G3J7JDP6.js.map} +1 -1
- package/dist/{chunk-IGTWXPTN.js → chunk-HGV7J4T6.js} +3 -3
- package/dist/{chunk-IGTWXPTN.js.map → chunk-HGV7J4T6.js.map} +1 -1
- package/dist/{chunk-YWQGSUF2.js → chunk-HLDRH23D.js} +3 -3
- package/dist/{chunk-YWQGSUF2.js.map → chunk-HLDRH23D.js.map} +1 -1
- package/dist/{chunk-PBT3CPPY.js → chunk-HQZYKJ56.js} +24 -4
- package/dist/chunk-HQZYKJ56.js.map +1 -0
- package/dist/{chunk-V6W56V3N.js → chunk-HZPHCSCS.js} +16 -3
- package/dist/chunk-HZPHCSCS.js.map +1 -0
- package/dist/{chunk-GJYQ27C2.js → chunk-INI4WDWC.js} +8 -1
- package/dist/chunk-INI4WDWC.js.map +1 -0
- package/dist/{chunk-U657IHFB.js → chunk-IQSRHXZR.js} +10 -4
- package/dist/chunk-IQSRHXZR.js.map +1 -0
- package/dist/{chunk-KQDU7Z7P.js → chunk-K4AT3V3J.js} +2 -1
- package/dist/chunk-K4AT3V3J.js.map +1 -0
- package/dist/{chunk-QIAPOWHH.js → chunk-KCS6NJ3O.js} +2 -2
- package/dist/{chunk-QIAPOWHH.js.map → chunk-KCS6NJ3O.js.map} +1 -1
- package/dist/{chunk-UKKRPP56.js → chunk-LOSRXZAH.js} +2 -2
- package/dist/{chunk-UKKRPP56.js.map → chunk-LOSRXZAH.js.map} +1 -1
- package/dist/{chunk-ROZLJULF.js → chunk-MF6ZUUJZ.js} +8 -3
- package/dist/chunk-MF6ZUUJZ.js.map +1 -0
- package/dist/{chunk-6IVNMC6R.js → chunk-MHMWQ7RB.js} +2 -2
- package/dist/{chunk-6IVNMC6R.js.map → chunk-MHMWQ7RB.js.map} +1 -1
- package/dist/{chunk-JYD7G4RG.js → chunk-PIVY32AE.js} +15 -5
- package/dist/chunk-PIVY32AE.js.map +1 -0
- package/dist/{chunk-BU23Z5HZ.js → chunk-PYBBYSZ3.js} +13 -18
- 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-YXOMI7ES.js → chunk-QIG4IGUP.js} +2 -2
- package/dist/{chunk-YXOMI7ES.js.map → chunk-QIG4IGUP.js.map} +1 -1
- package/dist/{chunk-6BRRUPJY.js → chunk-QROYYGWU.js} +3 -3
- package/dist/chunk-QROYYGWU.js.map +1 -0
- package/dist/{chunk-FOQK4F3L.js → chunk-RHD7RKGI.js} +28 -7
- package/dist/chunk-RHD7RKGI.js.map +1 -0
- package/dist/{chunk-BBU2SPRE.js → chunk-T4WJ5VGP.js} +4 -4
- package/dist/{chunk-BBU2SPRE.js.map → chunk-T4WJ5VGP.js.map} +1 -1
- package/dist/{chunk-6NOLL5KG.js → chunk-TGLUDQP2.js} +3 -3
- package/dist/{chunk-6NOLL5KG.js.map → chunk-TGLUDQP2.js.map} +1 -1
- package/dist/{chunk-HO6FU3G7.js → chunk-TLMMFQWM.js} +4 -4
- package/dist/{chunk-HO6FU3G7.js.map → chunk-TLMMFQWM.js.map} +1 -1
- package/dist/chunk-UMKV7YVQ.js +20 -0
- package/dist/chunk-UMKV7YVQ.js.map +1 -0
- package/dist/{chunk-M2NRCFRO.js → chunk-VFYO3UGZ.js} +2 -2
- package/dist/{chunk-M2NRCFRO.js.map → chunk-VFYO3UGZ.js.map} +1 -1
- package/dist/{chunk-YOKEL75M.js → chunk-WVS6CUCT.js} +2 -2
- package/dist/{chunk-YOKEL75M.js.map → chunk-WVS6CUCT.js.map} +1 -1
- package/dist/{chunk-MN3POJFN.js → chunk-YMUIQRWK.js} +2 -2
- package/dist/{chunk-MN3POJFN.js.map → chunk-YMUIQRWK.js.map} +1 -1
- package/dist/{chunk-Y3LC7JQO.js → chunk-YOA5W5ZH.js} +2 -2
- package/dist/{chunk-Y3LC7JQO.js.map → chunk-YOA5W5ZH.js.map} +1 -1
- package/dist/{chunk-44A6LP54.js → chunk-YQ2AC4E2.js} +2 -2
- package/dist/{chunk-44A6LP54.js.map → chunk-YQ2AC4E2.js.map} +1 -1
- package/dist/chunk-ZNROKDSZ.js +54 -0
- package/dist/chunk-ZNROKDSZ.js.map +1 -0
- package/dist/collapsible-panel.d.ts +3 -2
- package/dist/collapsible-panel.js +4 -3
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/composer.d.ts +62 -0
- package/dist/composer.js +5 -0
- package/dist/composer.js.map +1 -0
- package/dist/corner-status.d.ts +1 -1
- package/dist/corner-status.js +1 -1
- package/dist/css-values.d.ts +9 -1
- package/dist/css-values.js +1 -1
- package/dist/disclosure-arrow.js +1 -1
- package/dist/empty-state.js +1 -1
- package/dist/grid.js +1 -1
- package/dist/icon-button.js +1 -1
- package/dist/icon-toggle-button.js +1 -1
- package/dist/index.d.ts +10 -5
- package/dist/index.js +40 -37
- package/dist/list-action-row.d.ts +10 -2
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.js +1 -1
- package/dist/list-icon-tile-B8dr97OW.d.ts +18 -0
- package/dist/list-item.d.ts +10 -3
- package/dist/list-item.js +1 -1
- package/dist/list.d.ts +36 -4
- package/dist/list.js +1 -1
- package/dist/loading-spinner.js +1 -1
- package/dist/lucide-icon.js +1 -1
- package/dist/{nav-stack-BvSKY448.d.ts → nav-stack-VXTumzKa.d.ts} +53 -4
- package/dist/nav-stack.d.ts +3 -2
- package/dist/nav-stack.js +2 -1
- package/dist/pane.d.ts +40 -3
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-CL9tYOkh.d.ts → panel-toolbar-vg6Ir5Dy.d.ts} +6 -1
- package/dist/popup-menu-register.d.ts +2 -1
- package/dist/popup-menu-register.js +97 -22
- package/dist/popup-menu-register.js.map +1 -1
- package/dist/popup-menu.js +1 -1
- package/dist/row.js +1 -1
- package/dist/scroll-clearance-BikHljTc.d.ts +14 -0
- package/dist/select-register.js +11 -0
- package/dist/select-register.js.map +1 -1
- package/dist/select.js +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/spacer.js +1 -1
- package/dist/split-button.js +1 -1
- package/dist/split-view.d.ts +7 -5
- package/dist/split-view.js +6 -3
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +6 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/anchored-surface.css +27 -1
- package/dist/styles/catalog/components/catalog-example-stack.css +5 -0
- package/dist/styles/catalog/components/catalog-example.css +33 -0
- package/dist/styles/catalog/components/catalog-stage.css +7 -0
- package/dist/styles/chip.css +70 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +21 -4
- package/dist/styles/components/actions/toolbar/toolbar.css +19 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +75 -1
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +75 -0
- package/dist/styles/components/collections/list/list.css +77 -7
- package/dist/styles/components/collections/list-action-row/list-action-row.css +177 -22
- package/dist/styles/components/collections/list-item/list-item.css +158 -11
- package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +27 -1
- package/dist/styles/components/feedback/chip/chip.css +70 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +24 -13
- package/dist/styles/components/forms/composer/composer.css +100 -0
- package/dist/styles/components/forms/select/select.css +1 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +13 -2
- package/dist/styles/components/layout/pane/pane.css +81 -2
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +84 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +15 -4
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +79 -4
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +195 -0
- package/dist/styles/composer.css +100 -0
- package/dist/styles/foundation.css +66 -0
- package/dist/styles/list-action-row.css +177 -22
- package/dist/styles/list-item.css +158 -11
- package/dist/styles/list.css +77 -7
- package/dist/styles/nav-stack.css +84 -0
- package/dist/styles/pane.css +81 -2
- package/dist/styles/popup-menu.css +21 -4
- package/dist/styles/select.css +1 -0
- package/dist/styles/state-banner.css +24 -13
- package/dist/styles/styles.css +1 -0
- package/dist/styles/surface-scaffold.css +195 -0
- package/dist/styles/tab-bar.css +15 -4
- package/dist/styles/tab-navigator.css +79 -4
- package/dist/styles/token-search-field.css +13 -2
- package/dist/styles/toolbar-control-group.css +75 -1
- package/dist/styles/toolbar-text.css +75 -0
- package/dist/styles/toolbar.css +19 -0
- package/dist/styles/webawesome.css +18 -0
- package/dist/surface-scaffold-register.d.ts +6 -1
- package/dist/surface-scaffold-register.js +89 -3
- package/dist/surface-scaffold-register.js.map +1 -1
- package/dist/surface-scaffold.d.ts +66 -7
- package/dist/surface-scaffold.js +1 -1
- package/dist/tab-navigator.d.ts +23 -2
- package/dist/tab-navigator.js +2 -0
- package/dist/tab-navigator.js.map +1 -1
- package/dist/token-search-field.d.ts +1 -1
- package/dist/token-search-field.js +1 -1
- package/dist/{token-search-model-DTcTXWMS.d.ts → token-search-model-aYR0YAei.d.ts} +32 -2
- package/dist/token-search-model.d.ts +1 -1
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +1 -0
- package/dist/value-table.js +1 -1
- package/dist/wire-catalog.d.ts +3 -2
- package/dist/wire-catalog.js +2 -2
- 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-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-nav-stack.js +135 -0
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-scroll-dividers.d.ts +9 -0
- package/dist/wire-scroll-dividers.js +1 -1
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-navigator.d.ts +3 -1
- package/dist/wire-tab-navigator.js +133 -1
- package/dist/wire-tab-navigator.js.map +1 -1
- package/dist/wire-token-search-fields.d.ts +1 -1
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/workbench.d.ts +8 -3
- package/dist/workbench.js +2 -1
- package/docs/accessibility.md +132 -3
- package/docs/anchored-surface.md +46 -4
- package/docs/app-layouts.md +23 -2
- package/docs/apple-hig.md +1 -0
- package/docs/catalog.md +61 -9
- package/docs/collapsible-panel.md +9 -6
- package/docs/component-contract.md +46 -13
- package/docs/component-selection.md +147 -20
- package/docs/composer.md +143 -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 -1
- package/docs/design/templates/choice-chips.svg +1 -1
- 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-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 -1
- package/docs/design/templates/list-action-row/trailing-menu.svg +1 -1
- 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/size-l-dark.svg +1 -1
- package/docs/design/templates/list-header/size-l.svg +1 -1
- package/docs/design/templates/list-header/size-m-dark.svg +1 -1
- package/docs/design/templates/list-header/size-m.svg +1 -1
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -1
- package/docs/design/templates/list-header/size-xl.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/icon-tile-dark.svg +1 -0
- package/docs/design/templates/list-item/icon-tile.svg +1 -0
- 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-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-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 -1
- package/docs/design/templates/state-banner/strip.svg +1 -1
- 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-dark.svg +1 -1
- package/docs/design/templates/tab-bar.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-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/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-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-philosophy.md +9 -1
- package/docs/examples/command-palette-adapter.tsx +3 -3
- package/docs/layout.md +147 -14
- package/docs/nav-stack.md +132 -8
- package/docs/recipes.md +9 -9
- package/docs/split-view.md +3 -3
- package/docs/sunken-panel.md +2 -2
- package/docs/surface-scaffold.md +138 -7
- package/docs/tab-navigator.md +38 -1
- package/docs/type-contracts.md +16 -16
- package/docs/ui-analyzer.md +3 -1
- package/docs/ui-doctor.md +71 -0
- package/docs/ux-demo.md +6 -6
- package/docs/webawesome-theme.md +7 -0
- package/docs/workbench.md +10 -6
- package/docs/writing.md +152 -0
- package/doctor/copy-capitalization-checks.mjs +591 -0
- package/doctor/index.mjs +17 -8
- package/llms.txt +105 -11
- package/package.json +15 -1
- package/ux-demo/recipes/app-shell.tsx +11 -11
- package/ux-demo/recipes/collapsible-sidebar.tsx +12 -11
- package/ux-demo/recipes/compact-toolbar.tsx +10 -10
- package/ux-demo/recipes/composer-form.tsx +8 -8
- package/ux-demo/recipes/list-detail-dialog.tsx +13 -13
- package/ux-demo/recipes/list-workspace-states.tsx +13 -13
- package/ux-demo/recipes/loading-inspector.tsx +10 -10
- package/ux-demo/recipes/navigation-sidebar.tsx +7 -7
- package/ux-demo/recipes/navigation-stack.tsx +5 -5
- package/ux-demo/recipes/workspace-header.tsx +5 -5
- package/dist/chunk-36TL6BCR.js.map +0 -1
- package/dist/chunk-4LOK4634.js +0 -21
- package/dist/chunk-4LOK4634.js.map +0 -1
- package/dist/chunk-6BRRUPJY.js.map +0 -1
- package/dist/chunk-6STQXRT4.js.map +0 -1
- package/dist/chunk-76PWEN5Y.js +0 -64
- package/dist/chunk-76PWEN5Y.js.map +0 -1
- package/dist/chunk-AYHC62OZ.js.map +0 -1
- package/dist/chunk-BU23Z5HZ.js.map +0 -1
- package/dist/chunk-DQDTZE4W.js +0 -70
- package/dist/chunk-DQDTZE4W.js.map +0 -1
- package/dist/chunk-FOQK4F3L.js.map +0 -1
- package/dist/chunk-GJYQ27C2.js.map +0 -1
- package/dist/chunk-JYD7G4RG.js.map +0 -1
- package/dist/chunk-KQDU7Z7P.js.map +0 -1
- package/dist/chunk-P74VXMB6.js.map +0 -1
- package/dist/chunk-PBT3CPPY.js.map +0 -1
- package/dist/chunk-PRG4CL3Q.js.map +0 -1
- package/dist/chunk-ROZLJULF.js.map +0 -1
- package/dist/chunk-U657IHFB.js.map +0 -1
- package/dist/chunk-V6W56V3N.js.map +0 -1
package/docs/anchored-surface.md
CHANGED
|
@@ -23,10 +23,15 @@ focusable anchor on close (or the previously focused element for a nonfocusable
|
|
|
23
23
|
anchor). Pass `initialFocus: false` for read-only
|
|
24
24
|
help that leaves focus on its trigger. Escape and an outside press dismiss it;
|
|
25
25
|
`dismiss`, `onDismiss`, and `outsideIgnore` can customize that behavior.
|
|
26
|
-
`placement` (`bottom` or `top`), `align` (`start` or `end`),
|
|
27
|
-
shared `kerfjs/overlay` positioning core: it flips
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
`placement` (`bottom` or `top`), `align` (`start` or `end`), `gap`, and
|
|
27
|
+
`viewportMargin` feed the shared `kerfjs/overlay` positioning core: it flips
|
|
28
|
+
vertically when the other side fits, keeps the surface `viewportMargin` (default
|
|
29
|
+
8px) inside the viewport edges, and follows scroll and resize. The surface fits
|
|
30
|
+
its height to the room beside the anchor: when neither side holds it, it opens
|
|
31
|
+
on the roomier side, caps its height to that room, and scrolls its content.
|
|
32
|
+
The room is exposed to the content as `--kui-anchored-surface-available-height`
|
|
33
|
+
and refreshed on every reposition, so a tall help surface fits beside a field on
|
|
34
|
+
a phone without application media queries or `max-height` overrides.
|
|
30
35
|
|
|
31
36
|
```tsx
|
|
32
37
|
openAnchoredSurfaceAt(
|
|
@@ -52,6 +57,43 @@ Closing the anchor's modal dialog also closes the surface. Escape closes only
|
|
|
52
57
|
the surface; the dialog beneath stays open. The temporary pointer anchor is
|
|
53
58
|
removed when the surface closes.
|
|
54
59
|
|
|
60
|
+
## Dark tone for media chrome
|
|
61
|
+
|
|
62
|
+
A popup anchored to dark media chrome (a volume control in a
|
|
63
|
+
`ToolbarControlGroup tone="dark"` over a video or image preview) passes
|
|
64
|
+
`tone: 'dark'`:
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
openAnchoredSurface(volumeButton, () => <VolumeControls />, {
|
|
68
|
+
label: 'Volume',
|
|
69
|
+
tone: 'dark',
|
|
70
|
+
placement: 'top',
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The tone is the same loud, inverse tone as a dark `ToolbarControlGroup` or
|
|
75
|
+
`ToolbarText`: dark beside a light page and light beside a dark one, so the
|
|
76
|
+
popup matches the group that opened it. When the surface opens it takes the
|
|
77
|
+
opposite of the anchor's color scheme (an explicit `color-scheme` on the anchor
|
|
78
|
+
or an ancestor wins; `light dark` follows the user's preference), and the
|
|
79
|
+
surface is marked `data-tone="dark"`. Nothing else changes. Every semantic
|
|
80
|
+
color token is a `light-dark()` pair, so the surface fill, border, and shadow,
|
|
81
|
+
and the text, borders, and focus rings of the Kerf UI and Web Awesome
|
|
82
|
+
components inside it (a `ListItem` mute row, a `wa-slider`), resolve to the
|
|
83
|
+
other side by inheritance. The content needs no tone props and no overrides.
|
|
84
|
+
Text and focus rings keep WCAG AA in both page schemes. A theme that replaces a
|
|
85
|
+
semantic token with a single color instead of a `light-dark()` pair opts that
|
|
86
|
+
token out of the flip. While the surface is open it follows a live switch: an
|
|
87
|
+
OS preference change, or a theme class, attribute, or inline `color-scheme`
|
|
88
|
+
changed on the anchor or one of its ancestors, flips it to the new opposite
|
|
89
|
+
(the content's own color transitions run, as the page's do). A scheme changed
|
|
90
|
+
only by swapping a stylesheet is not observed. `openAnchoredSurfaceAt` reads the
|
|
91
|
+
scheme from its `context` (the element under the pointer), so a region with its
|
|
92
|
+
own `color-scheme` is honored; without a connected `context` it reads the modal
|
|
93
|
+
scope's (or the page's).
|
|
94
|
+
|
|
95
|
+
## Theming
|
|
96
|
+
|
|
55
97
|
Override `--kui-anchored-surface-inset` and
|
|
56
98
|
`--kui-anchored-surface-radius` for a theme; content can compose any Kerf UI
|
|
57
99
|
components without the surface applying action policy. Prefer `PopupMenu` for
|
package/docs/app-layouts.md
CHANGED
|
@@ -41,8 +41,19 @@ the layouts handle the insets for you. There is nothing to configure:
|
|
|
41
41
|
status bar or home indicator but its first and last items can always be
|
|
42
42
|
scrolled clear.
|
|
43
43
|
- **Interior edges get nothing.** A `Workbench` center next to an expanded rail,
|
|
44
|
-
a `SplitView` detail beside its list, or a `NavStack` view under its
|
|
45
|
-
not inset on that edge. Collapse the rail and the center picks up
|
|
44
|
+
a `SplitView` detail beside its list, or a `NavStack` view under its docked
|
|
45
|
+
chrome is not inset on that edge. Collapse the rail and the center picks up
|
|
46
|
+
the edge. A `NavStack` with `chromePresentation="overlay"` is the exception
|
|
47
|
+
by design: its views reach under the translucent chrome, and the measured
|
|
48
|
+
chrome height (top safe area included) becomes their block-start inset, so
|
|
49
|
+
content scrolls beneath the bar yet rests clear of it (see
|
|
50
|
+
[Navigation stack › Overlay chrome](nav-stack.md#overlay-chrome)). Its
|
|
51
|
+
`bottomToolbarPresentation="overlay"` does the same at the bottom: the
|
|
52
|
+
measured toolbar height (bottom safe area included) becomes the views'
|
|
53
|
+
block-end inset, so the last item rests just above the toolbar. A
|
|
54
|
+
`TabNavigator` with `barPresentation="overlay"` does the same for its tab
|
|
55
|
+
bar: the measured bar height (bottom safe area included) becomes the
|
|
56
|
+
scenes' block-end inset.
|
|
46
57
|
- **No double inset.** Whichever region applies an inset clears it for its
|
|
47
58
|
descendants. A layout region whose only child is a `Pane` or another layout
|
|
48
59
|
lets that child own the insets. That child fills the region — a `Workbench`
|
|
@@ -130,6 +141,16 @@ single scrolling slot; the negative margins change only its inline reach. The
|
|
|
130
141
|
[`Pane` UX catalog example](../ux-demo/demos/pane.tsx) shows both `deepInset`
|
|
131
142
|
states with the same table component.
|
|
132
143
|
|
|
144
|
+
### Scrolling beneath overlaying chrome
|
|
145
|
+
|
|
146
|
+
`Pane.scrollClearance` (`"block-start"`, `"block-end"`, or `"both"`) lets the
|
|
147
|
+
scrolling slot pass beneath chrome laid over the pane's edge, such as a
|
|
148
|
+
`DialogSurface` floating footer over a filling Pane. The slot adds the
|
|
149
|
+
inherited `--kui-scroll-clearance-block-*` context that the chrome publishes to
|
|
150
|
+
its block padding and `scroll-padding`, alongside the safe-area and
|
|
151
|
+
`deepInset` insets, so its first and last items still rest clear of the
|
|
152
|
+
chrome. See `docs/layout.md` "Scroll clearance".
|
|
153
|
+
|
|
133
154
|
## Decision matrix
|
|
134
155
|
|
|
135
156
|
| Situation | Layout | Device threshold |
|
package/docs/apple-hig.md
CHANGED
|
@@ -12,6 +12,7 @@ Native Apple applications should use native platform controls and follow the Hum
|
|
|
12
12
|
- Use one icon family and one metaphor per action. Directional icons may mirror in RTL; checkmarks, logos, and real-world objects do not.
|
|
13
13
|
- Motion is brief, causal, and optional. Honor reduced-motion and reduced-transparency preferences; repeating indicators stop moving under reduced motion.
|
|
14
14
|
- Writing is concise, specific, and action-led. Labels describe the result, not implementation details.
|
|
15
|
+
- Capitalize by element type, consistently: names of commands, controls, views, and fields use title style; descriptions, messages, tooltips, and option text use sentence style. See [Writing interface copy](./writing.md#capitalization).
|
|
15
16
|
|
|
16
17
|
## Interaction
|
|
17
18
|
|
package/docs/catalog.md
CHANGED
|
@@ -85,7 +85,7 @@ action. Filtering does not change the selected
|
|
|
85
85
|
entry or its preview.
|
|
86
86
|
|
|
87
87
|
Per-entry `resources` render as "open in new tab" links in the footer, and
|
|
88
|
-
`related` renders a "Related
|
|
88
|
+
`related` renders a "Related Entries" `PopupMenu` in a `single`
|
|
89
89
|
`ToolbarControlGroup` (grouped by each entry's `group`), so register its elements
|
|
90
90
|
with `@kerfjs/ui/popup-menu/register` when you use it.
|
|
91
91
|
|
|
@@ -132,22 +132,74 @@ entry's `tags` array.
|
|
|
132
132
|
Pass `label` when the stack needs an accessible name: the rendered `section`
|
|
133
133
|
is then exposed as a named region. An unlabeled stack remains an ordinary
|
|
134
134
|
grouping rather than adding an unnecessary landmark.
|
|
135
|
+
A stack holds a 736px reading measure by default; pass `width="full"` for
|
|
136
|
+
application-width compositions (boards, app shells, drawers, split views) so
|
|
137
|
+
the stack spans the stage like a `viewport.width: "full"` row instead of
|
|
138
|
+
clipping them.
|
|
135
139
|
- `CatalogExample` is one row: optional generated `ListHeader` label, optional
|
|
136
140
|
generated note, then one specimen or one intentionally coupled specimen
|
|
137
141
|
cluster. Use one row per variant/state; do not hand-author the helper's private
|
|
138
|
-
classes.
|
|
142
|
+
classes. A supplied `label` also names the row's `section`, so each specimen
|
|
143
|
+
is a named region that assistive technology and
|
|
144
|
+
`getByRole("region", { name })` can address.
|
|
145
|
+
- Example and stack labels are headings, so they use title style ("Heading
|
|
146
|
+
Identity Stays Whole", "Icon Trigger in a Toolbar Group"); the `note` that
|
|
147
|
+
explains a specimen stays sentence style. Write a label as a name, not a
|
|
148
|
+
sentence. See [Writing interface copy](./writing.md#capitalization);
|
|
149
|
+
`kerf-ui-doctor` reports a sentence-case label as `KUI-D040`.
|
|
139
150
|
- Focused demos do not import local stylesheets, use inline `style`, or invent
|
|
140
151
|
styling-only `demo-*` classes. Prefer a public Kerf component, then a Web
|
|
141
152
|
Awesome surface when Kerf has no equivalent, then ordinary semantic HTML.
|
|
142
153
|
Use `CatalogExample.viewport` for bounded specimen width, height, frame,
|
|
143
154
|
surface, overflow, responsive visibility, and public custom-property values;
|
|
144
155
|
keep those constraints catalog-owned instead of recreating a demo stylesheet.
|
|
156
|
+
Widths run `sidebar` (272px, a production rail, for sidebar-pane content),
|
|
157
|
+
`compact` (440px), `medium` (640px), and `wide` (864px), each capped at the
|
|
158
|
+
stage, plus `full`; `text` and `control` size a single label or control.
|
|
145
159
|
Component heights run `short` (220px) through `tall` (360px); frame an app
|
|
146
160
|
shell, whole-screen layout, or other application-sized recipe with
|
|
147
161
|
`height: "app"` (592px), and give its root `fill` rather than a frame `Pane`.
|
|
148
162
|
An app frame stands in for the screen: it is the containing block for
|
|
149
163
|
screen-fixed chrome, so a compact `CollapsiblePanel` overlay, its backdrop,
|
|
150
164
|
and restore controls dock to the frame's edges rather than the page's.
|
|
165
|
+
`minHeight` (`short`, `medium`, or `app` at 592px) is a floor the frame
|
|
166
|
+
may grow past rather than a definite height.
|
|
167
|
+
- A top-layer specimen (a `popover`, a modal) that production anchors to a
|
|
168
|
+
named region with CSS anchor positioning anchors to the frame instead when
|
|
169
|
+
the frame takes that name: `viewport.anchorName` is a CSS dashed-ident
|
|
170
|
+
(`"--app-shell-main"`, validated; anything else throws) that becomes the
|
|
171
|
+
frame's `anchor-name`, so the specimen's own `position-anchor` rule resolves
|
|
172
|
+
to the frame. Do not wrap the specimen in a stage element to name it. Anchor
|
|
173
|
+
names are document-wide, so give each frame on a page its own. The frame
|
|
174
|
+
only names the anchor: the specimen keeps owning its placement, and as a
|
|
175
|
+
top-layer element it is not clipped by the frame or the stage. Chromium,
|
|
176
|
+
Firefox, and WebKit with CSS anchor positioning place it against the frame;
|
|
177
|
+
an engine without anchor positioning ignores the name, and the specimen
|
|
178
|
+
falls back to whatever placement its own CSS gives it there.
|
|
179
|
+
- For a centered reading column inside a wider frame, set
|
|
180
|
+
`viewport.contentWidth` (`compact` 440px, `medium` 640px, or `wide` 864px,
|
|
181
|
+
each capped at the frame) and `contentAlign: "center"` (the default is
|
|
182
|
+
`start`). Each in-flow child fills that column; `[popover]` children keep
|
|
183
|
+
their own geometry. The column applies to block, `grid`, and `flex-column`
|
|
184
|
+
frames, and `contentAlign` does nothing without `contentWidth`.
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
<CatalogExample
|
|
188
|
+
label="Request Docked to the Main Column"
|
|
189
|
+
viewport={{
|
|
190
|
+
layout: "flex-column",
|
|
191
|
+
width: "full",
|
|
192
|
+
minHeight: "app",
|
|
193
|
+
anchorName: "--app-shell-main",
|
|
194
|
+
contentWidth: "medium",
|
|
195
|
+
contentAlign: "center",
|
|
196
|
+
}}
|
|
197
|
+
>
|
|
198
|
+
<Transcript />
|
|
199
|
+
<PermissionRequestPopup /> {/* its CSS: position-anchor: --app-shell-main */}
|
|
200
|
+
</CatalogExample>
|
|
201
|
+
```
|
|
202
|
+
|
|
151
203
|
- The specimen is an immediate child of `CatalogExample`. A focused component
|
|
152
204
|
row should place the component root there, without a decorative card or
|
|
153
205
|
spacing wrapper. A composition row may place the composition root there.
|
|
@@ -165,7 +217,7 @@ import { CatalogExample, CatalogExampleStack } from "@kerfjs/ui/catalog";
|
|
|
165
217
|
|
|
166
218
|
const buttonPreview = (
|
|
167
219
|
<CatalogExampleStack
|
|
168
|
-
label="Button
|
|
220
|
+
label="Button Variants"
|
|
169
221
|
rootAttributes={{ "data-demo": "button" }}
|
|
170
222
|
>
|
|
171
223
|
<CatalogExample label="Icon" note="A bare glyph." align="glyph">
|
|
@@ -174,7 +226,7 @@ const buttonPreview = (
|
|
|
174
226
|
<CatalogExample label="Control" align="inline-control">
|
|
175
227
|
<SegmentedControl id="view" label="View" value="list" choices={choices} />
|
|
176
228
|
</CatalogExample>
|
|
177
|
-
<CatalogExample label="Authoring
|
|
229
|
+
<CatalogExample label="Authoring Note" note="Explain the specimen below.">
|
|
178
230
|
<p>Use the public helper contract.</p>
|
|
179
231
|
</CatalogExample>
|
|
180
232
|
</CatalogExampleStack>
|
|
@@ -361,23 +413,23 @@ const sections: CatalogSection[] = [
|
|
|
361
413
|
const renderers: Record<string, () => SafeHtml> = {
|
|
362
414
|
button: () => (
|
|
363
415
|
<CatalogExampleStack
|
|
364
|
-
label="Button
|
|
416
|
+
label="Button States"
|
|
365
417
|
rootAttributes={{ "data-demo": "button" }}
|
|
366
418
|
>
|
|
367
419
|
<CatalogExample label="Default" align="inline-control">
|
|
368
420
|
<Button label="Save" />
|
|
369
421
|
</CatalogExample>
|
|
370
|
-
<CatalogExample label="Authoring
|
|
422
|
+
<CatalogExample label="Authoring Note" note="Explain the specimen below.">
|
|
371
423
|
<p>The application owns product copy and actions.</p>
|
|
372
424
|
</CatalogExample>
|
|
373
425
|
</CatalogExampleStack>
|
|
374
426
|
),
|
|
375
427
|
"profile-form": () => (
|
|
376
428
|
<CatalogExampleStack
|
|
377
|
-
label="Profile
|
|
429
|
+
label="Profile Form Composition"
|
|
378
430
|
rootAttributes={{ "data-demo": "profile-form" }}
|
|
379
431
|
>
|
|
380
|
-
<CatalogExample label="Complete
|
|
432
|
+
<CatalogExample label="Complete Composition">
|
|
381
433
|
<ProfileForm />
|
|
382
434
|
</CatalogExample>
|
|
383
435
|
</CatalogExampleStack>
|
|
@@ -493,7 +545,7 @@ revealCatalogEntry(app, initial, { block: "center" });
|
|
|
493
545
|
|
|
494
546
|
## UX Review capture
|
|
495
547
|
|
|
496
|
-
On a local Vite dev or preview server the catalog can offer a **Capture
|
|
548
|
+
On a local Vite dev or preview server the catalog can offer a **Capture Region**
|
|
497
549
|
header link that starts a UX Review region screenshot, preset with the project
|
|
498
550
|
and the active entry. Static hosting has no local project, so the link never
|
|
499
551
|
appears there. Three pieces wire it:
|
|
@@ -147,7 +147,9 @@ top toolbar over a `Pane`:
|
|
|
147
147
|
place groups wherever the open panel needs them;
|
|
148
148
|
- a `ToolbarControlGroup` marked `relocateOnCollapse` stays available in the
|
|
149
149
|
work area when the panel closes; the standard `toggle: { action, name,
|
|
150
|
-
showLabel?, hideLabel? }` is always the final group.
|
|
150
|
+
showLabel?, hideLabel? }` is always the final group. Give `name` as the
|
|
151
|
+
panel's title-style name ("Navigator"), which labels the toggle group and
|
|
152
|
+
completes "Show Navigator" / "Hide Navigator".
|
|
151
153
|
|
|
152
154
|
Busy groups keep their inert control, spinner, and adjacent live status together
|
|
153
155
|
when relocated. Clearing `busy` restores the same action in its current toolbar;
|
|
@@ -166,7 +168,8 @@ divider of its own unless `dividerSides` says so. The `Pane` under it draws
|
|
|
166
168
|
the line under the toolbar only while its content is scrolled (see
|
|
167
169
|
[Scroll dividers](./layout.md#scroll-dividers)), and takes the panel's `pane`
|
|
168
170
|
(`PaneConfig`: `contentElement`, `contentLabel`, `separators`,
|
|
169
|
-
`safeAreaEdges`, `chromeDividers`
|
|
171
|
+
`safeAreaEdges`, `chromeDividers`, `appearance`, `deepInset`,
|
|
172
|
+
`scrollClearance`, `headerPresentation`, `tabIndex`, `outlined`) — for example `{ contentElement: "nav",
|
|
170
173
|
contentLabel: "Sections" }` for a navigation rail. An omitted or `undefined`
|
|
171
174
|
field keeps the `Pane` default; without a `toolbar` there is no `Pane`, so
|
|
172
175
|
`pane` is ignored.
|
|
@@ -187,8 +190,8 @@ inert; avoid duplicate `id` attributes on marked groups.
|
|
|
187
190
|
const toolbar: CollapsiblePanelToolbar = {
|
|
188
191
|
label: "Navigator",
|
|
189
192
|
leading: <NewFileGroup />,
|
|
190
|
-
trailing: <ToolbarControlGroup relocateOnCollapse label="Search
|
|
191
|
-
toggle: { action: "toggle-nav", name: "
|
|
193
|
+
trailing: <ToolbarControlGroup relocateOnCollapse label="Search Files"><SearchButton /></ToolbarControlGroup>,
|
|
194
|
+
toggle: { action: "toggle-nav", name: "Navigator" },
|
|
192
195
|
};
|
|
193
196
|
|
|
194
197
|
<Row fill gap="none">
|
|
@@ -307,7 +310,7 @@ mount(app, () => (
|
|
|
307
310
|
side="left"
|
|
308
311
|
collapsed
|
|
309
312
|
action="toggle-nav"
|
|
310
|
-
label="Show
|
|
313
|
+
label="Show Navigator"
|
|
311
314
|
/>
|
|
312
315
|
)}
|
|
313
316
|
{/* content */}
|
|
@@ -362,7 +365,7 @@ sizes, content, and any per-project persistence — exactly as with the other la
|
|
|
362
365
|
|
|
363
366
|
## Recipe and coverage
|
|
364
367
|
|
|
365
|
-
The catalog ships a runnable **Collapsible
|
|
368
|
+
The catalog ships a runnable **Collapsible Sidebar** recipe — a left rail and a
|
|
366
369
|
bottom drawer with the standard toggles, the compact overlay, and per-panel
|
|
367
370
|
persistence: [open it](../ux-demo/?component=recipe-collapsible-sidebar) or read
|
|
368
371
|
[`recipes.md`](recipes.md#collapsible-sidebar) · [TSX source](../ux-demo/recipes/collapsible-sidebar.tsx).
|
|
@@ -89,8 +89,12 @@ only cataloged `descendantElements` and composed JSX evidence.
|
|
|
89
89
|
An entry's optional `cssValueProps` makes CSS-adjacent prop grammar equally
|
|
90
90
|
machine-evaluable. Each path records the property grammar, finite shorthands,
|
|
91
91
|
canonical versus exceptional spacing choices, standalone and expression-only
|
|
92
|
-
helpers, raw/unsafe policy, and serialization examples. Nested paths
|
|
93
|
-
|
|
92
|
+
helpers, raw/unsafe policy, and serialization examples. Nested paths are
|
|
93
|
+
dot-separated object members, each optionally suffixed with `[]` to visit
|
|
94
|
+
every array element: `items[].property` for a value inside each array item,
|
|
95
|
+
`iconTile.color` for a member of an object-valued prop. A member that is not a
|
|
96
|
+
literal object or array (a tone string such as `iconTile="brand"`, a variable)
|
|
97
|
+
is skipped rather than guessed. Consumer catalogs can publish the same facts;
|
|
94
98
|
ESLint, `kerf-ui-analyze`, and `kerf-ui-doctor` then issue the same stable
|
|
95
99
|
`KUI-L013`–`KUI-L017` feedback for application and third-party components.
|
|
96
100
|
|
|
@@ -246,10 +250,10 @@ product that genuinely needs one of these elements records a narrow `KUI-L301`
|
|
|
246
250
|
profile exception for the file that renders it.
|
|
247
251
|
|
|
248
252
|
Catalog detail footers use one standard resource vocabulary and order. Build
|
|
249
|
-
them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo
|
|
250
|
-
first, optional `Component
|
|
253
|
+
them with `catalogResources()` from `@kerfjs/ui/catalog-resources`: `Demo Source`
|
|
254
|
+
first, optional `Component Source` and `Design Template`, then `Guidance`.
|
|
251
255
|
Third-party entries use the typed `integrationGuidance` kind, which renders
|
|
252
|
-
`Integration
|
|
256
|
+
`Integration Guidance`, and omit `Component Source` when the implementation is
|
|
253
257
|
not owned by the catalog's project. Prefer these semantic kinds over local labels
|
|
254
258
|
such as “View source” or “Read UI guidance”; the helper makes that convention a
|
|
255
259
|
compile-time choice while still returning ordinary `CatalogResource[]` values.
|
|
@@ -333,6 +337,8 @@ visual anchor.
|
|
|
333
337
|
|
|
334
338
|
`ToolbarControlGroup.tileTone` selects `neutral`, `brand`, `success`, `warning`, or `danger` quiet fill, matching quiet border, and on-quiet foreground for a non-interactive icon tile. Compose a contained `single` group whose only child is a direct decorative LucideIcon (`aria-hidden="true"`). Omission preserves the normal group palette. The prop does not recolor interactive, mixed, multi-control, or borderless groups; keep real actions in controls with their existing focus/hover/pressed treatments.
|
|
335
339
|
|
|
340
|
+
`ListItem`, `ListItemLink`, and `ListActionRow` take `iconTile` to present their leading `icon` in a filled 32px rounded tile holding an 18px glyph, for settings or command rows that identify each entry by color. Pass a tone (`neutral`, `brand`, `success`, `warning`, or `danger`) for the same quiet fill, matching quiet border, and on-quiet foreground as `ToolbarControlGroup.tileTone`, or `{ color, foreground? }` for an application color: `color` is a `CssColor` (`uiColor()`, `colorVar()`, or `fillColor('#e5484d')`) and `foreground` a `CssForegroundColor`; without one, the glyph is black or white, whichever contrasts with the fill. The tile sits 6px clear of a standard 44px row (a compact row is at least 42px tall), moves the label to the tile's edge, and keeps its colors when the row is hovered or selected. Never wrap the icon in your own tile or resize the row's icon slot.
|
|
341
|
+
|
|
336
342
|
### Public CSS anatomy
|
|
337
343
|
|
|
338
344
|
The `publicClasses` array on each entry in
|
|
@@ -396,7 +402,12 @@ The documented exceptions live with their reasons in
|
|
|
396
402
|
check, so the list only shrinks. The layout regions' inherited edge-inset
|
|
397
403
|
context (`--kui-edge-inset-*` handed to a sole Pane or layout child and cleared
|
|
398
404
|
for any other content, and a Toolbar clearing it for its zones) is the one
|
|
399
|
-
design exception; the others name the open fix ticket.
|
|
405
|
+
design exception; the others name the open fix ticket. The scroll-clearance
|
|
406
|
+
context (`--kui-scroll-clearance-block-*`) needs no exception: overlaying
|
|
407
|
+
chrome publishes it on its own element (a `DialogSurface` on its dialog body,
|
|
408
|
+
a `Pane` overlay header, through `wireScrollDividers`, on its own Pane root).
|
|
409
|
+
A scroll owner reads it only through its own `scrollClearance` prop, or, for an
|
|
410
|
+
overlay-header Pane's content, through its own `headerPresentation`.
|
|
400
411
|
|
|
401
412
|
Applications and component packages built on the package follow the same
|
|
402
413
|
rules, and the downstream tools enforce them against the composition catalog
|
|
@@ -623,11 +634,19 @@ own inset (8px for a raw `wa-dropdown`, the Select listbox's 4px for a
|
|
|
623
634
|
`PopupMenu`), while `compact` and `list-zero` apply to every nested menu. A
|
|
624
635
|
`PopupMenu` and a `Select` draw one popup: the same caret that turns to face the
|
|
625
636
|
open popup, fade-in surface, surface inset, row height and padding, current-row
|
|
626
|
-
fill,
|
|
627
|
-
`foundation.css`.
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
637
|
+
fill, group titles, and scroll cue, all read from one private popup-choice
|
|
638
|
+
contract in `foundation.css`. A capped popup that scrolls (a long listbox, a
|
|
639
|
+
menu, or a phone submenu) shows a soft shadow along each edge with more
|
|
640
|
+
choices beyond it, so overlay scrollbars never leave it looking complete; the
|
|
641
|
+
cue is CSS-only, appears only toward hidden rows, and a popup whose choices
|
|
642
|
+
all fit draws none. Checkbox items reserve a check column, and so does every
|
|
643
|
+
plain command in a level (the top menu or one submenu) that holds a checkbox
|
|
644
|
+
item, through an `aria-hidden` icon-slot spacer, so check, icon, and label
|
|
645
|
+
columns align across the level. A level without a checkbox item keeps the
|
|
646
|
+
compact start: plain commands begin at the checkmark's leading edge, beside the
|
|
647
|
+
group title rather than the farther-in Select option label. Checked submenu
|
|
648
|
+
items keep their checkmark inside the submenu surface with the same check-column
|
|
649
|
+
advance as the top level. Compact mixed controls retain the standard
|
|
631
650
|
item padding, omit an internal separator, and let the raised selected item paint
|
|
632
651
|
over the outer border instead of shrinking to an inset highlight. The Web
|
|
633
652
|
Awesome trigger's shadow base owns max-content sizing, so icons, localized text,
|
|
@@ -739,7 +758,12 @@ propagating before the window, or a press without a click, collapses in the
|
|
|
739
758
|
next task instead.
|
|
740
759
|
`TokenSearchField.trailingAction` supplies an icon, accessible `label`, delegated
|
|
741
760
|
`action`, and optional `id`; the field renders a 24px wide button that fills its
|
|
742
|
-
34px line slot, including the hit target, disabled
|
|
761
|
+
34px line slot (32px in `toolbar-group`), including the hit target, disabled
|
|
762
|
+
state, hover, focus ring, and the clear button's radius in each presentation.
|
|
763
|
+
`expanded` renders `aria-expanded` and `pressed` renders `aria-pressed` (one or
|
|
764
|
+
the other, never both); either `true` state keeps the hover fill at full text
|
|
765
|
+
strength. `controls` and `haspopup` render `aria-controls` and `aria-haspopup`,
|
|
766
|
+
and `attributes` carries domain `data-*` metadata but never `data-action`.
|
|
743
767
|
Use `trailing` for passive content. The two props are mutually exclusive.
|
|
744
768
|
For a collapsible search in a stretched Toolbar center, `fill` lets the expanded
|
|
745
769
|
field and its enclosing search `ToolbarControlGroup` consume the available width;
|
|
@@ -782,7 +806,16 @@ When a leading AppTab is pinned, the leading scroll divider appears at that
|
|
|
782
806
|
tab's trailing edge while peer tabs scroll beneath it, including in RTL.
|
|
783
807
|
With `snapTabs`, `wireTabBars` measures the pinned tab and settles peers at
|
|
784
808
|
whole-tab starts after scroll and selection changes, reserving end room so the
|
|
785
|
-
last peer can align there.
|
|
809
|
+
last peer can align there. That room is scrollable content after the last tab,
|
|
810
|
+
inside the strip, so it lengthens the scroll range without widening the strip:
|
|
811
|
+
the strip still shrinks to its allocation, and `trailing` and `end` stay inside
|
|
812
|
+
the bar. The room is still in-flow content, so it counts toward the strip's
|
|
813
|
+
content-based flex basis: when another zone also shrinks (a trailing zone
|
|
814
|
+
given `--kui-tab-bar-trailing-flex: 0 1 auto` with shrinkable content), the
|
|
815
|
+
strip keeps a proportionally larger share. The share converges within a few
|
|
816
|
+
frames and never pushes `trailing` or `end` out of the bar; keep the trailing
|
|
817
|
+
zone non-shrinking with `snapTabs` to avoid it. The application still owns
|
|
818
|
+
selection and tab order.
|
|
786
819
|
ResizeObserver notifications coalesce snap measurements into the next animation
|
|
787
820
|
frame, so inset writes cannot resize the observed strip during observer delivery.
|
|
788
821
|
`wireTabBars` watches the whole root it is given, but a mutation re-measures only
|