@kerfjs/ui 4.5.0-beta.1 → 5.0.0-beta.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +461 -116
- package/ai/application-ui-diagnostic-ids-v1.json +23 -1
- package/ai/application-ui-profile-sync.cjs +21 -2
- package/ai/application-ui-profile.d.ts +4 -0
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +28 -1
- package/ai/application-ui-profile.schema.json +10 -0
- package/ai/catalog-authoring.json +13 -4
- package/ai/catalog-authoring.schema.json +52 -8
- package/ai/compile-time-contracts-v1.json +63 -16
- package/ai/compile-time-contracts-v1.schema.json +4 -1
- package/ai/component-catalog-extension.schema.json +25 -0
- package/ai/component-catalog.json +5585 -1175
- package/ai/component-catalog.schema.json +78 -1
- package/ai/component-class-owners.cjs +83 -0
- package/ai/component-composition-extension.d.ts +7 -0
- package/ai/component-composition-extension.schema.json +7 -0
- package/ai/{component-catalog-v2-overrides.json → component-composition-rules.json} +281 -49
- package/ai/component-composition.d.ts +132 -0
- package/ai/component-composition.json +8729 -0
- package/ai/component-composition.schema.json +412 -0
- package/ai/components/README.md +185 -0
- package/ai/components/anchored-surface.md +99 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +76 -0
- package/ai/components/chip.md +76 -0
- package/ai/components/choice-chips.md +87 -0
- package/ai/components/collapsible-panel.md +103 -0
- package/ai/components/column-track.md +78 -0
- package/ai/components/combobox.md +88 -0
- package/ai/components/composer.md +83 -0
- package/ai/components/content-item.md +98 -0
- package/ai/components/content-swap.md +78 -0
- package/ai/components/corner-status.md +88 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +77 -0
- package/ai/components/edge-activity-indicator.md +81 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/file-picker.md +88 -0
- package/ai/components/floating-toolbar.md +82 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/framed-list.md +80 -0
- package/ai/components/grid.md +101 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/icon-button.md +82 -0
- package/ai/components/icon-toggle-button.md +80 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +108 -0
- package/ai/components/list-header.md +91 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +108 -0
- package/ai/components/list.md +125 -0
- package/ai/components/loading-spinner.md +73 -0
- package/ai/components/lucide-icon.md +97 -0
- package/ai/components/nav-stack.md +115 -0
- package/ai/components/pane.md +115 -0
- package/ai/components/popup-menu.md +171 -0
- package/ai/components/recipe-app-shell.md +57 -0
- package/ai/components/recipe-collapsible-sidebar.md +57 -0
- package/ai/components/recipe-compact-toolbar.md +57 -0
- package/ai/components/recipe-composer-form.md +57 -0
- package/ai/components/recipe-list-detail-dialog.md +57 -0
- package/ai/components/recipe-list-workspace-states.md +57 -0
- package/ai/components/recipe-loading-inspector.md +57 -0
- package/ai/components/recipe-navigation-sidebar.md +57 -0
- package/ai/components/recipe-navigation-stack.md +57 -0
- package/ai/components/recipe-workspace-header.md +57 -0
- package/ai/components/resize.md +106 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +116 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-button.md +80 -0
- package/ai/components/split-view.md +105 -0
- package/ai/components/state-banner.md +96 -0
- package/ai/components/summary-row.md +85 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +105 -0
- package/ai/components/tab-bar.md +114 -0
- package/ai/components/tab-navigator.md +100 -0
- package/ai/components/tabs.md +95 -0
- package/ai/components/text.md +90 -0
- package/ai/components/token-search-field.md +107 -0
- package/ai/components/toolbar-control-group.md +125 -0
- package/ai/components/toolbar-text.md +100 -0
- package/ai/components/toolbar.md +103 -0
- package/ai/components/value-table.md +80 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +60 -0
- package/ai/components/wa-button.md +59 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +120 -0
- package/ai/public-api-signatures-v1.md +3851 -441
- package/ai/skill.md +402 -70
- package/ai/webawesome-jsx-signatures-v1.md +9 -2
- package/analyzer/cli.mjs +5 -2
- package/analyzer/component-ownership.d.mts +72 -0
- package/analyzer/component-ownership.mjs +429 -0
- package/analyzer/index.d.mts +8 -0
- package/analyzer/index.mjs +1687 -49
- package/analyzer/loud-pairs.d.mts +49 -0
- package/analyzer/loud-pairs.mjs +357 -0
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/catalog-projection-cli.mjs +96 -0
- package/catalog-projection.d.mts +55 -0
- package/catalog-projection.mjs +62 -0
- package/dist/anchored-surface.d.ts +69 -0
- package/dist/anchored-surface.js +3 -0
- package/dist/anchored-surface.js.map +1 -0
- package/dist/app-tab.d.ts +39 -4
- package/dist/app-tab.js +2 -1
- package/dist/badge.d.ts +83 -0
- package/dist/badge.js +4 -0
- package/dist/badge.js.map +1 -0
- package/dist/browser/anchored-surface.js +3 -0
- package/dist/browser/badge.js +3 -0
- package/dist/browser/catalog.js +28 -0
- package/dist/browser/chip.js +3 -0
- package/dist/browser/choice-chips.js +3 -0
- package/dist/browser/collapsible-panel.js +9 -0
- package/dist/browser/column-track.js +3 -0
- package/dist/browser/combobox.js +3 -0
- package/dist/browser/composer.js +4 -0
- package/dist/browser/content-item.js +3 -0
- package/dist/browser/content-swap.js +3 -0
- package/dist/browser/corner-status.js +3 -0
- package/dist/browser/edge-activity-indicator.js +3 -0
- package/dist/browser/file-picker.js +3 -0
- package/dist/browser/framed-list.js +3 -0
- package/dist/browser/grid.js +3 -0
- package/dist/browser/icon-button.js +4 -0
- package/dist/browser/icon-toggle-button.js +4 -0
- package/dist/browser/list-action-row.js +2 -0
- package/dist/browser/list-header.js +3 -1
- package/dist/browser/list-item.js +1 -0
- package/dist/browser/nav-stack.js +11 -0
- package/dist/browser/popup-menu.js +3 -0
- package/dist/browser/row.js +3 -0
- package/dist/browser/segmented-control.js +0 -1
- package/dist/browser/select.js +2 -1
- package/dist/browser/spacer.js +3 -0
- package/dist/browser/split-button.js +5 -0
- package/dist/browser/split-view.js +13 -0
- package/dist/browser/state-banner.js +1 -0
- package/dist/browser/summary-row.js +3 -0
- package/dist/browser/surface-scaffold.js +3 -0
- package/dist/browser/tab-navigator.js +4 -0
- package/dist/browser/text.js +3 -0
- package/dist/browser/toolbar-control-group.js +1 -0
- package/dist/browser/workbench.js +14 -0
- package/dist/catalog-resources.d.ts +17 -1
- package/dist/catalog-resources.js +5 -5
- package/dist/catalog-resources.js.map +1 -1
- package/dist/catalog.d.ts +123 -121
- package/dist/catalog.js +598 -269
- package/dist/catalog.js.map +1 -1
- package/dist/chip.d.ts +69 -0
- package/dist/chip.js +3 -0
- package/dist/chip.js.map +1 -0
- package/dist/choice-chips.d.ts +82 -0
- package/dist/choice-chips.js +3 -0
- package/dist/choice-chips.js.map +1 -0
- package/dist/chunk-2GOCOLQL.js +270 -0
- package/dist/chunk-2GOCOLQL.js.map +1 -0
- package/dist/chunk-2MSPNRWJ.js +82 -0
- package/dist/chunk-2MSPNRWJ.js.map +1 -0
- package/dist/chunk-34U4ANDJ.js +119 -0
- package/dist/chunk-34U4ANDJ.js.map +1 -0
- package/dist/chunk-3GLYIIFR.js +230 -0
- package/dist/chunk-3GLYIIFR.js.map +1 -0
- package/dist/{chunk-Y6LYKFXY.js → chunk-3VXDSIBJ.js} +7 -4
- package/dist/chunk-3VXDSIBJ.js.map +1 -0
- package/dist/chunk-3WYREXW4.js +120 -0
- package/dist/chunk-3WYREXW4.js.map +1 -0
- package/dist/chunk-4UB5Z3ZZ.js +68 -0
- package/dist/chunk-4UB5Z3ZZ.js.map +1 -0
- package/dist/chunk-6C6DLP3W.js +31 -0
- package/dist/chunk-6C6DLP3W.js.map +1 -0
- package/dist/chunk-7IUEBNCO.js +108 -0
- package/dist/chunk-7IUEBNCO.js.map +1 -0
- package/dist/{chunk-QO55FN2Y.js → chunk-AN5IWMTM.js} +7 -3
- package/dist/chunk-AN5IWMTM.js.map +1 -0
- package/dist/chunk-AV7CPAPT.js +82 -0
- package/dist/chunk-AV7CPAPT.js.map +1 -0
- package/dist/{chunk-PX3YSS5C.js → chunk-B53PS2LE.js} +5 -3
- package/dist/chunk-B53PS2LE.js.map +1 -0
- package/dist/chunk-CA7LNX3J.js +44 -0
- package/dist/chunk-CA7LNX3J.js.map +1 -0
- package/dist/chunk-CEJ5FK6G.js +288 -0
- package/dist/chunk-CEJ5FK6G.js.map +1 -0
- package/dist/chunk-CMETHPKR.js +175 -0
- package/dist/chunk-CMETHPKR.js.map +1 -0
- package/dist/chunk-CMLPFIC5.js +46 -0
- package/dist/chunk-CMLPFIC5.js.map +1 -0
- package/dist/{chunk-RKVQEH4J.js → chunk-CVD5IZGB.js} +10 -5
- package/dist/chunk-CVD5IZGB.js.map +1 -0
- package/dist/chunk-CXZXHZTR.js +514 -0
- package/dist/chunk-CXZXHZTR.js.map +1 -0
- package/dist/chunk-D5RGM3XA.js +38 -0
- package/dist/chunk-D5RGM3XA.js.map +1 -0
- package/dist/{chunk-KWWR5VMS.js → chunk-DZJ4GBSP.js} +19 -5
- package/dist/chunk-DZJ4GBSP.js.map +1 -0
- package/dist/chunk-EIET4QLK.js +51 -0
- package/dist/chunk-EIET4QLK.js.map +1 -0
- package/dist/chunk-ELCMSQNJ.js +49 -0
- package/dist/chunk-ELCMSQNJ.js.map +1 -0
- package/dist/chunk-EOO6PYGF.js +162 -0
- package/dist/chunk-EOO6PYGF.js.map +1 -0
- package/dist/chunk-ETCWQLJV.js +85 -0
- package/dist/chunk-ETCWQLJV.js.map +1 -0
- package/dist/chunk-FDZNYD4C.js +138 -0
- package/dist/chunk-FDZNYD4C.js.map +1 -0
- package/dist/chunk-FR76ZJQC.js +90 -0
- package/dist/chunk-FR76ZJQC.js.map +1 -0
- package/dist/chunk-G3J7JDP6.js +29 -0
- package/dist/chunk-G3J7JDP6.js.map +1 -0
- package/dist/chunk-GS2QD3N7.js +14 -0
- package/dist/chunk-GS2QD3N7.js.map +1 -0
- package/dist/chunk-HGV7J4T6.js +86 -0
- package/dist/chunk-HGV7J4T6.js.map +1 -0
- package/dist/chunk-HLDRH23D.js +84 -0
- package/dist/chunk-HLDRH23D.js.map +1 -0
- package/dist/chunk-HQZYKJ56.js +302 -0
- package/dist/chunk-HQZYKJ56.js.map +1 -0
- package/dist/chunk-HZPHCSCS.js +95 -0
- package/dist/chunk-HZPHCSCS.js.map +1 -0
- package/dist/chunk-IKS72C6P.js +53 -0
- package/dist/chunk-IKS72C6P.js.map +1 -0
- package/dist/chunk-IM3GKYOG.js +202 -0
- package/dist/chunk-IM3GKYOG.js.map +1 -0
- package/dist/{chunk-JRKSK2HX.js → chunk-INI4WDWC.js} +53 -7
- package/dist/chunk-INI4WDWC.js.map +1 -0
- package/dist/chunk-IQSRHXZR.js +164 -0
- package/dist/chunk-IQSRHXZR.js.map +1 -0
- package/dist/{chunk-M7JBER5U.js → chunk-JOR5LGYE.js} +18 -4
- package/dist/chunk-JOR5LGYE.js.map +1 -0
- package/dist/chunk-K4AT3V3J.js +545 -0
- package/dist/chunk-K4AT3V3J.js.map +1 -0
- package/dist/chunk-KCS6NJ3O.js +82 -0
- package/dist/chunk-KCS6NJ3O.js.map +1 -0
- package/dist/{chunk-SRSJO5QE.js → chunk-KH4KEMSP.js} +34 -3
- package/dist/chunk-KH4KEMSP.js.map +1 -0
- package/dist/chunk-LL45C7BB.js +122 -0
- package/dist/chunk-LL45C7BB.js.map +1 -0
- package/dist/chunk-LOSRXZAH.js +100 -0
- package/dist/chunk-LOSRXZAH.js.map +1 -0
- package/dist/{chunk-7KEUJIIC.js → chunk-MF6ZUUJZ.js} +93 -11
- package/dist/chunk-MF6ZUUJZ.js.map +1 -0
- package/dist/chunk-MHMWQ7RB.js +19 -0
- package/dist/chunk-MHMWQ7RB.js.map +1 -0
- package/dist/chunk-MJ5RU6XT.js +173 -0
- package/dist/chunk-MJ5RU6XT.js.map +1 -0
- package/dist/chunk-MXNIVEVL.js +48 -0
- package/dist/chunk-MXNIVEVL.js.map +1 -0
- package/dist/{chunk-IJBSZ4NX.js → chunk-NS2TBYM4.js} +8 -5
- package/dist/chunk-NS2TBYM4.js.map +1 -0
- package/dist/chunk-PIVY32AE.js +140 -0
- package/dist/chunk-PIVY32AE.js.map +1 -0
- package/dist/chunk-PYBBYSZ3.js +526 -0
- package/dist/chunk-PYBBYSZ3.js.map +1 -0
- package/dist/chunk-QDSZTQXL.js +28 -0
- package/dist/chunk-QDSZTQXL.js.map +1 -0
- package/dist/chunk-QH5KOFNS.js +39 -0
- package/dist/chunk-QH5KOFNS.js.map +1 -0
- package/dist/chunk-QIG4IGUP.js +139 -0
- package/dist/chunk-QIG4IGUP.js.map +1 -0
- package/dist/chunk-QLA25V2K.js +493 -0
- package/dist/chunk-QLA25V2K.js.map +1 -0
- package/dist/chunk-QROYYGWU.js +52 -0
- package/dist/chunk-QROYYGWU.js.map +1 -0
- package/dist/chunk-QYMJHS4K.js +36 -0
- package/dist/chunk-QYMJHS4K.js.map +1 -0
- package/dist/chunk-RHD7RKGI.js +176 -0
- package/dist/chunk-RHD7RKGI.js.map +1 -0
- package/dist/chunk-S2XULQEK.js +52 -0
- package/dist/chunk-S2XULQEK.js.map +1 -0
- package/dist/{chunk-LPOMRC4C.js → chunk-S3ECMF23.js} +11 -3
- package/dist/chunk-S3ECMF23.js.map +1 -0
- package/dist/chunk-S4Y3YTAI.js +35 -0
- package/dist/chunk-S4Y3YTAI.js.map +1 -0
- package/dist/chunk-S4ZGTDSG.js +18 -0
- package/dist/chunk-S4ZGTDSG.js.map +1 -0
- package/dist/{chunk-PSKN344N.js → chunk-T4WJ5VGP.js} +63 -12
- package/dist/chunk-T4WJ5VGP.js.map +1 -0
- package/dist/chunk-TDMHA7C3.js +251 -0
- package/dist/chunk-TDMHA7C3.js.map +1 -0
- package/dist/{chunk-Y45PPBDV.js → chunk-TGLUDQP2.js} +47 -14
- package/dist/chunk-TGLUDQP2.js.map +1 -0
- package/dist/chunk-TLMMFQWM.js +222 -0
- package/dist/chunk-TLMMFQWM.js.map +1 -0
- package/dist/chunk-U6QYTMDB.js +85 -0
- package/dist/chunk-U6QYTMDB.js.map +1 -0
- package/dist/chunk-UMKV7YVQ.js +20 -0
- package/dist/chunk-UMKV7YVQ.js.map +1 -0
- package/dist/chunk-VFYO3UGZ.js +45 -0
- package/dist/chunk-VFYO3UGZ.js.map +1 -0
- package/dist/chunk-W4IK7AWD.js +73 -0
- package/dist/chunk-W4IK7AWD.js.map +1 -0
- package/dist/chunk-WVS6CUCT.js +48 -0
- package/dist/chunk-WVS6CUCT.js.map +1 -0
- package/dist/chunk-Y6KT7ZTR.js +109 -0
- package/dist/chunk-Y6KT7ZTR.js.map +1 -0
- package/dist/chunk-YMUIQRWK.js +44 -0
- package/dist/chunk-YMUIQRWK.js.map +1 -0
- package/dist/chunk-YOA5W5ZH.js +807 -0
- package/dist/chunk-YOA5W5ZH.js.map +1 -0
- package/dist/chunk-YQ2AC4E2.js +59 -0
- package/dist/chunk-YQ2AC4E2.js.map +1 -0
- package/dist/chunk-ZKKO4MHC.js +25 -0
- package/dist/chunk-ZKKO4MHC.js.map +1 -0
- package/dist/chunk-ZNROKDSZ.js +54 -0
- package/dist/chunk-ZNROKDSZ.js.map +1 -0
- package/dist/collapsible-panel.d.ts +96 -17
- package/dist/collapsible-panel.js +104 -27
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/column-track.d.ts +41 -0
- package/dist/column-track.js +4 -0
- package/dist/column-track.js.map +1 -0
- package/dist/combobox.d.ts +40 -0
- package/dist/combobox.js +3 -0
- package/dist/combobox.js.map +1 -0
- package/dist/composer.d.ts +62 -0
- package/dist/composer.js +5 -0
- package/dist/composer.js.map +1 -0
- package/dist/content-item.d.ts +116 -0
- package/dist/content-item.js +4 -0
- package/dist/content-item.js.map +1 -0
- package/dist/content-swap.d.ts +34 -0
- package/dist/content-swap.js +3 -0
- package/dist/content-swap.js.map +1 -0
- package/dist/corner-status.d.ts +36 -0
- package/dist/corner-status.js +3 -0
- package/dist/corner-status.js.map +1 -0
- package/dist/css-values.d.ts +127 -0
- package/dist/css-values.js +3 -0
- package/dist/css-values.js.map +1 -0
- package/dist/device-class.js +1 -1
- package/dist/device-class.js.map +1 -1
- package/dist/disclosure-arrow.d.ts +6 -1
- package/dist/disclosure-arrow.js +2 -1
- package/dist/edge-activity-indicator.d.ts +28 -0
- package/dist/edge-activity-indicator.js +3 -0
- package/dist/edge-activity-indicator.js.map +1 -0
- package/dist/empty-state.d.ts +5 -2
- package/dist/empty-state.js +2 -1
- package/dist/extension-attributes-mu8MFUl0.d.ts +13 -0
- package/dist/file-picker.d.ts +47 -0
- package/dist/file-picker.js +3 -0
- package/dist/file-picker.js.map +1 -0
- package/dist/flex-alignment-4ms8ZbV8.d.ts +5 -0
- package/dist/floating-toolbar.d.ts +29 -6
- package/dist/floating-toolbar.js +1 -1
- package/dist/framed-list.d.ts +47 -0
- package/dist/framed-list.js +4 -0
- package/dist/framed-list.js.map +1 -0
- package/dist/grid.d.ts +58 -0
- package/dist/grid.js +6 -0
- package/dist/grid.js.map +1 -0
- package/dist/help-tags-register.d.ts +13 -0
- package/dist/help-tags-register.js +9 -0
- package/dist/help-tags-register.js.map +1 -0
- package/dist/icon-button.d.ts +46 -0
- package/dist/icon-button.js +6 -0
- package/dist/icon-button.js.map +1 -0
- package/dist/icon-toggle-button.d.ts +42 -0
- package/dist/icon-toggle-button.js +6 -0
- package/dist/icon-toggle-button.js.map +1 -0
- package/dist/index.d.ts +59 -20
- package/dist/index.js +66 -29
- package/dist/list-action-row.d.ts +69 -12
- package/dist/list-action-row.js +5 -1
- package/dist/list-header.d.ts +36 -2
- package/dist/list-header.js +4 -1
- package/dist/list-icon-tile-B8dr97OW.d.ts +18 -0
- package/dist/list-inset-control.d.ts +10 -4
- package/dist/list-inset-control.js +1 -1
- package/dist/list-inset-text.d.ts +17 -12
- package/dist/list-inset-text.js +2 -1
- package/dist/list-item.d.ts +49 -5
- package/dist/list-item.js +4 -1
- package/dist/list.d.ts +121 -12
- package/dist/list.js +5 -1
- package/dist/loading-spinner.d.ts +12 -2
- package/dist/loading-spinner.js +2 -1
- package/dist/lucide-icon.d.ts +15 -3
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack-VXTumzKa.d.ts +158 -0
- package/dist/nav-stack.d.ts +15 -38
- package/dist/nav-stack.js +13 -1
- package/dist/pane.d.ts +111 -7
- package/dist/pane.js +2 -1
- package/dist/panel-toolbar-vg6Ir5Dy.d.ts +77 -0
- package/dist/popup-menu-register.d.ts +10 -0
- package/dist/popup-menu-register.js +336 -0
- package/dist/popup-menu-register.js.map +1 -0
- package/dist/popup-menu.d.ts +125 -0
- package/dist/popup-menu.js +3 -0
- package/dist/popup-menu.js.map +1 -0
- package/dist/resizable-region.d.ts +32 -3
- package/dist/resizable-region.js +1 -1
- package/dist/row.d.ts +53 -0
- package/dist/row.js +7 -0
- package/dist/row.js.map +1 -0
- package/dist/scroll-clearance-BikHljTc.d.ts +14 -0
- package/dist/segmented-control.d.ts +7 -4
- package/dist/segmented-control.js +1 -2
- package/dist/select-register.js +255 -3
- package/dist/select-register.js.map +1 -1
- package/dist/select.d.ts +95 -6
- package/dist/select.js +4 -1
- package/dist/semantic-content-BbzjvSu9.d.ts +14 -0
- package/dist/semantic-tone-CdW013KF.d.ts +4 -0
- package/dist/sides-BPSWde0A.d.ts +4 -0
- package/dist/skeleton.d.ts +14 -7
- package/dist/skeleton.js +2 -1
- package/dist/spacer.d.ts +18 -0
- package/dist/spacer.js +4 -0
- package/dist/spacer.js.map +1 -0
- package/dist/split-button.d.ts +57 -0
- package/dist/split-button.js +7 -0
- package/dist/split-button.js.map +1 -0
- package/dist/split-view.d.ts +63 -6
- package/dist/split-view.js +88 -9
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.d.ts +37 -6
- package/dist/state-banner.js +4 -1
- package/dist/styles/anchored-surface.css +41 -0
- package/dist/styles/app-tab.css +232 -0
- package/dist/styles/badge.css +145 -0
- package/dist/styles/catalog/components/catalog-example-stack.css +14 -0
- package/dist/styles/catalog/components/catalog-example.css +204 -0
- package/dist/styles/catalog/components/catalog-stage.css +61 -0
- package/dist/styles/catalog/components/catalog.css +26 -0
- package/dist/styles/catalog.css +5 -575
- package/dist/styles/chip.css +208 -0
- package/dist/styles/choice-chips.css +154 -0
- package/dist/styles/collapsible-panel.css +450 -16
- package/dist/styles/column-track.css +57 -0
- package/dist/styles/combobox.css +113 -0
- package/dist/styles/components/actions/floating-toolbar/floating-toolbar.css +119 -0
- package/dist/styles/components/actions/icon-button/icon-button.css +22 -0
- package/dist/styles/components/actions/icon-toggle-button/icon-toggle-button.css +83 -0
- package/dist/styles/components/actions/popup-menu/popup-menu.css +370 -0
- package/dist/styles/components/actions/split-button/split-button.css +95 -0
- package/dist/styles/components/actions/toolbar/toolbar.css +443 -0
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +1069 -0
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +269 -0
- package/dist/styles/components/collections/framed-list/framed-list.css +47 -0
- package/dist/styles/components/collections/list/list.css +250 -0
- package/dist/styles/components/collections/list-action-row/list-action-row.css +466 -0
- package/dist/styles/components/collections/list-header/list-header.css +229 -0
- package/dist/styles/components/collections/list-inset-control/list-inset-control.css +30 -0
- package/dist/styles/components/collections/list-inset-text/list-inset-text.css +29 -0
- package/dist/styles/components/collections/list-item/list-item.css +461 -0
- package/dist/styles/components/collections/summary-row/summary-row.css +161 -0
- package/dist/styles/components/data-display/value-table/value-table.css +183 -0
- package/dist/styles/components/feedback/anchored-surface/anchored-surface.css +41 -0
- package/dist/styles/components/feedback/badge/badge.css +145 -0
- package/dist/styles/components/feedback/chip/chip.css +208 -0
- package/dist/styles/components/feedback/corner-status/corner-status.css +60 -0
- package/dist/styles/components/feedback/edge-activity-indicator/edge-activity-indicator.css +127 -0
- package/dist/styles/components/feedback/empty-state/empty-state.css +47 -0
- package/dist/styles/components/feedback/loading-spinner/loading-spinner.css +25 -0
- package/dist/styles/components/feedback/skeleton/skeleton.css +92 -0
- package/dist/styles/components/feedback/state-banner/state-banner.css +297 -0
- package/dist/styles/components/forms/choice-chips/choice-chips.css +154 -0
- package/dist/styles/components/forms/combobox/combobox.css +113 -0
- package/dist/styles/components/forms/composer/composer.css +100 -0
- package/dist/styles/components/forms/file-picker/file-picker.css +81 -0
- package/dist/styles/components/forms/segmented-control/segmented-control.css +196 -0
- package/dist/styles/components/forms/select/select.css +455 -0
- package/dist/styles/components/forms/token-search-field/token-search-field.css +432 -0
- package/dist/styles/components/layout/collapsible-panel/collapsible-panel.css +580 -0
- package/dist/styles/components/layout/column-track/column-track.css +57 -0
- package/dist/styles/components/layout/content-swap/content-swap.css +154 -0
- package/dist/styles/components/layout/grid/grid.css +88 -0
- package/dist/styles/components/layout/pane/pane.css +382 -0
- package/dist/styles/components/layout/resizable-region/resizable-region.css +545 -0
- package/dist/styles/components/layout/row/row.css +114 -0
- package/dist/styles/components/layout/spacer/spacer.css +11 -0
- package/dist/styles/components/layout/split-view/split-view.css +146 -0
- package/dist/styles/components/layout/workbench/workbench.css +1086 -0
- package/dist/styles/components/media/lucide-icon/lucide-icon.css +15 -0
- package/dist/styles/components/navigation/app-tab/app-tab.css +384 -0
- package/dist/styles/components/navigation/disclosure-arrow/disclosure-arrow.css +23 -0
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +342 -0
- package/dist/styles/components/navigation/tab-bar/tab-bar.css +197 -0
- package/dist/styles/components/navigation/tab-navigator/tab-navigator.css +325 -0
- package/dist/styles/components/surfaces/content-item/content-item.css +138 -0
- package/dist/styles/components/surfaces/sunken-panel/sunken-panel.css +31 -0
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +425 -0
- package/dist/styles/components/typography/text/text.css +220 -0
- package/dist/styles/composer.css +100 -0
- package/dist/styles/content-item.css +138 -0
- package/dist/styles/content-swap.css +154 -0
- package/dist/styles/corner-status.css +60 -0
- package/dist/styles/document.css +98 -0
- package/dist/styles/edge-activity-indicator.css +127 -0
- package/dist/styles/file-picker.css +81 -0
- package/dist/styles/floating-toolbar.css +87 -6
- package/dist/styles/foundation.css +254 -53
- package/dist/styles/framed-list.css +47 -0
- package/dist/styles/grid.css +88 -0
- package/dist/styles/icon-button.css +22 -0
- package/dist/styles/icon-toggle-button.css +83 -0
- package/dist/styles/layout.css +1 -21
- package/dist/styles/list-action-row.css +323 -17
- package/dist/styles/list-header.css +128 -59
- package/dist/styles/list-inset-control.css +25 -2
- package/dist/styles/list-inset-text.css +27 -12
- package/dist/styles/list-item.css +371 -33
- package/dist/styles/list.css +214 -7
- package/dist/styles/loading-spinner.css +4 -0
- package/dist/styles/lucide-icon.css +9 -0
- package/dist/styles/nav-stack.css +280 -49
- package/dist/styles/pane.css +322 -2
- package/dist/styles/popup-menu.css +370 -0
- package/dist/styles/resizable-region.css +438 -4
- package/dist/styles/row.css +114 -0
- package/dist/styles/segmented-control.css +34 -3
- package/dist/styles/select.css +338 -23
- package/dist/styles/skeleton.css +64 -3
- package/dist/styles/spacer.css +11 -0
- package/dist/styles/split-button.css +95 -0
- package/dist/styles/split-view.css +114 -3
- package/dist/styles/state-banner.css +141 -42
- package/dist/styles/styles.css +22 -1
- package/dist/styles/summary-row.css +161 -0
- package/dist/styles/sunken-panel.css +13 -4
- package/dist/styles/surface-scaffold.css +425 -0
- package/dist/styles/tab-bar.css +161 -9
- package/dist/styles/tab-navigator.css +325 -0
- package/dist/styles/text.css +220 -0
- package/dist/styles/token-search-field.css +202 -59
- package/dist/styles/toolbar-control-group.css +886 -42
- package/dist/styles/toolbar-text.css +184 -7
- package/dist/styles/toolbar.css +363 -17
- package/dist/styles/value-table.css +115 -7
- package/dist/styles/webawesome.css +282 -20
- package/dist/styles/workbench.css +999 -7
- package/dist/summary-row.d.ts +56 -0
- package/dist/summary-row.js +4 -0
- package/dist/summary-row.js.map +1 -0
- package/dist/sunken-panel.d.ts +23 -4
- package/dist/sunken-panel.js +2 -1
- package/dist/surface-scaffold-register.d.ts +9 -0
- package/dist/surface-scaffold-register.js +151 -0
- package/dist/surface-scaffold-register.js.map +1 -0
- package/dist/surface-scaffold.d.ts +170 -0
- package/dist/surface-scaffold.js +4 -0
- package/dist/surface-scaffold.js.map +1 -0
- package/dist/tab-bar.d.ts +31 -6
- package/dist/tab-bar.js +1 -1
- package/dist/tab-navigator.d.ts +114 -0
- package/dist/tab-navigator.js +102 -0
- package/dist/tab-navigator.js.map +1 -0
- package/dist/text.d.ts +98 -0
- package/dist/text.js +3 -0
- package/dist/text.js.map +1 -0
- package/dist/token-search-field.d.ts +3 -59
- package/dist/token-search-field.js +2 -1
- package/dist/token-search-model-aYR0YAei.d.ts +184 -0
- package/dist/token-search-model.d.ts +3 -0
- package/dist/token-search-model.js +3 -0
- package/dist/token-search-model.js.map +1 -0
- package/dist/toolbar-control-group.d.ts +87 -4
- package/dist/toolbar-control-group.js +3 -1
- package/dist/toolbar-text.d.ts +46 -12
- package/dist/toolbar-text.js +2 -1
- package/dist/toolbar.d.ts +71 -9
- package/dist/toolbar.js +1 -1
- package/dist/types-CVgIwSdq.d.ts +189 -0
- package/dist/value-table.d.ts +30 -4
- package/dist/value-table.js +2 -1
- package/dist/webawesome.d.ts +8 -1
- package/dist/wire-catalog.d.ts +88 -13
- package/dist/wire-catalog.js +240 -206
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-comboboxes.d.ts +26 -0
- package/dist/wire-comboboxes.js +3 -0
- package/dist/wire-comboboxes.js.map +1 -0
- package/dist/wire-composers.d.ts +16 -0
- package/dist/wire-composers.js +3 -0
- package/dist/wire-composers.js.map +1 -0
- package/dist/wire-content-items.d.ts +11 -0
- package/dist/wire-content-items.js +139 -0
- package/dist/wire-content-items.js.map +1 -0
- package/dist/wire-corner-status.d.ts +11 -0
- package/dist/wire-corner-status.js +3 -0
- package/dist/wire-corner-status.js.map +1 -0
- package/dist/wire-file-pickers.d.ts +26 -0
- package/dist/wire-file-pickers.js +3 -0
- package/dist/wire-file-pickers.js.map +1 -0
- package/dist/wire-list-focus-scroll.d.ts +16 -0
- package/dist/wire-list-focus-scroll.js +3 -0
- package/dist/wire-list-focus-scroll.js.map +1 -0
- package/dist/wire-list-reorder.d.ts +41 -0
- package/dist/wire-list-reorder.js +3 -0
- package/dist/wire-list-reorder.js.map +1 -0
- package/dist/wire-nav-stack.d.ts +4 -1
- package/dist/wire-nav-stack.js +312 -16
- package/dist/wire-nav-stack.js.map +1 -1
- package/dist/wire-resizable-regions.d.ts +2 -1
- package/dist/wire-resizable-regions.js +2 -1
- package/dist/wire-scroll-dividers.d.ts +87 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/wire-sidebar.d.ts +24 -4
- package/dist/wire-sidebar.js +122 -19
- package/dist/wire-sidebar.js.map +1 -1
- package/dist/wire-tab-bars.d.ts +1 -0
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-tab-navigator.d.ts +13 -0
- package/dist/wire-tab-navigator.js +153 -0
- package/dist/wire-tab-navigator.js.map +1 -0
- package/dist/wire-token-search-fields.d.ts +5 -1
- package/dist/wire-token-search-fields.js +2 -1
- package/dist/wire-toolbar-visibility.d.ts +13 -0
- package/dist/wire-toolbar-visibility.js +3 -0
- package/dist/wire-toolbar-visibility.js.map +1 -0
- package/dist/wire-workbench.d.ts +116 -0
- package/dist/wire-workbench.js +6 -0
- package/dist/wire-workbench.js.map +1 -0
- package/dist/workbench.d.ts +253 -10
- package/dist/workbench.js +20 -62
- package/dist/workbench.js.map +1 -1
- package/docs/accessibility.md +617 -32
- package/docs/anchored-surface.md +101 -0
- package/docs/app-layouts.md +159 -10
- package/docs/apple-hig.md +2 -0
- package/docs/catalog.md +403 -110
- package/docs/collapsible-panel.md +272 -16
- package/docs/component-contract.md +700 -79
- package/docs/component-integration.md +75 -0
- package/docs/component-selection.md +908 -79
- package/docs/composer.md +143 -0
- package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -0
- package/docs/design/templates/choice-chips/color-palette.svg +1 -0
- package/docs/design/templates/choice-chips/compact-icons-dark.svg +1 -0
- package/docs/design/templates/choice-chips/compact-icons.svg +1 -0
- package/docs/design/templates/choice-chips/multiple-dark.svg +1 -0
- package/docs/design/templates/choice-chips/multiple.svg +1 -0
- package/docs/design/templates/choice-chips-dark.svg +1 -0
- package/docs/design/templates/choice-chips.svg +1 -0
- package/docs/design/templates/composer/chat-dark.svg +1 -0
- package/docs/design/templates/composer/chat.svg +1 -0
- package/docs/design/templates/composer/prompt-dark.svg +1 -0
- package/docs/design/templates/composer/prompt.svg +1 -0
- package/docs/design/templates/composer-dark.svg +1 -0
- package/docs/design/templates/composer.svg +1 -0
- package/docs/design/templates/empty-state/filtered-dark.svg +1 -1
- package/docs/design/templates/empty-state/filtered.svg +1 -1
- package/docs/design/templates/empty-state/with-action-dark.svg +1 -1
- package/docs/design/templates/empty-state/with-action.svg +1 -1
- package/docs/design/templates/empty-state-dark.svg +1 -1
- package/docs/design/templates/empty-state.svg +1 -1
- package/docs/design/templates/list/compact-dark.svg +1 -1
- package/docs/design/templates/list/compact.svg +1 -1
- package/docs/design/templates/list/stack-dark.svg +1 -1
- package/docs/design/templates/list/stack.svg +1 -1
- package/docs/design/templates/list-action-row/default-dark.svg +1 -1
- package/docs/design/templates/list-action-row/default.svg +1 -1
- package/docs/design/templates/list-action-row/icon-tile-dark.svg +1 -0
- package/docs/design/templates/list-action-row/icon-tile.svg +1 -0
- package/docs/design/templates/list-action-row/selected-dark.svg +1 -1
- package/docs/design/templates/list-action-row/selected.svg +1 -1
- package/docs/design/templates/list-action-row/trailing-menu-dark.svg +1 -0
- package/docs/design/templates/list-action-row/trailing-menu.svg +1 -0
- package/docs/design/templates/list-action-row-dark.svg +1 -1
- package/docs/design/templates/list-action-row.svg +1 -1
- package/docs/design/templates/list-dark.svg +1 -1
- package/docs/design/templates/list-header/action-dark.svg +1 -1
- package/docs/design/templates/list-header/action.svg +1 -1
- package/docs/design/templates/list-header/count-dark.svg +1 -1
- package/docs/design/templates/list-header/count.svg +1 -1
- package/docs/design/templates/list-header/inline-action-dark.svg +1 -0
- package/docs/design/templates/list-header/inline-action.svg +1 -0
- package/docs/design/templates/list-header/size-l-dark.svg +1 -0
- package/docs/design/templates/list-header/size-l.svg +1 -0
- package/docs/design/templates/list-header/size-m-dark.svg +1 -0
- package/docs/design/templates/list-header/size-m.svg +1 -0
- package/docs/design/templates/list-header/size-xl-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xl.svg +1 -0
- package/docs/design/templates/list-header/size-xs-dark.svg +1 -0
- package/docs/design/templates/list-header/size-xs.svg +1 -0
- package/docs/design/templates/list-header/toggle-collapsed-dark.svg +1 -1
- package/docs/design/templates/list-header/toggle-collapsed.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded-dark.svg +1 -1
- package/docs/design/templates/list-header/toggle-expanded.svg +1 -1
- package/docs/design/templates/list-header-dark.svg +1 -1
- package/docs/design/templates/list-header.svg +1 -1
- package/docs/design/templates/list-item/default-dark.svg +1 -1
- package/docs/design/templates/list-item/default.svg +1 -1
- package/docs/design/templates/list-item/icon-tile-dark.svg +1 -0
- package/docs/design/templates/list-item/icon-tile.svg +1 -0
- package/docs/design/templates/list-item/multiline-dark.svg +1 -1
- package/docs/design/templates/list-item/multiline.svg +1 -1
- package/docs/design/templates/list-item/selected-dark.svg +1 -1
- package/docs/design/templates/list-item/selected.svg +1 -1
- package/docs/design/templates/list-item/trailing-dark.svg +1 -1
- package/docs/design/templates/list-item/trailing.svg +1 -1
- package/docs/design/templates/list-item-dark.svg +1 -1
- package/docs/design/templates/list-item.svg +1 -1
- package/docs/design/templates/list.svg +1 -1
- package/docs/design/templates/segmented-control/equal-dark.svg +1 -1
- package/docs/design/templates/segmented-control/equal.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small-dark.svg +1 -1
- package/docs/design/templates/segmented-control/pill-small.svg +1 -1
- package/docs/design/templates/segmented-control-dark.svg +1 -1
- package/docs/design/templates/segmented-control.svg +1 -1
- package/docs/design/templates/skeleton-dark.svg +1 -1
- package/docs/design/templates/skeleton.svg +1 -1
- package/docs/design/templates/state-banner/danger-dark.svg +1 -1
- package/docs/design/templates/state-banner/danger.svg +1 -1
- package/docs/design/templates/state-banner/info-badge-dark.svg +1 -1
- package/docs/design/templates/state-banner/info-badge.svg +1 -1
- package/docs/design/templates/state-banner/info-dark.svg +1 -1
- package/docs/design/templates/state-banner/info.svg +1 -1
- package/docs/design/templates/state-banner/strip-dark.svg +1 -0
- package/docs/design/templates/state-banner/strip.svg +1 -0
- package/docs/design/templates/state-banner/success-dark.svg +1 -1
- package/docs/design/templates/state-banner/success.svg +1 -1
- package/docs/design/templates/state-banner/warning-dark.svg +1 -1
- package/docs/design/templates/state-banner/warning.svg +1 -1
- package/docs/design/templates/state-banner-dark.svg +1 -1
- package/docs/design/templates/state-banner.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs-dark.svg +1 -1
- package/docs/design/templates/tab-bar/workspace-tabs.svg +1 -1
- package/docs/design/templates/tab-bar-dark.svg +1 -1
- package/docs/design/templates/tab-bar.svg +1 -1
- package/docs/design/templates/token-search-field/empty-dark.svg +1 -1
- package/docs/design/templates/token-search-field/empty.svg +1 -1
- package/docs/design/templates/token-search-field/tokens-dark.svg +1 -1
- package/docs/design/templates/token-search-field/tokens.svg +1 -1
- package/docs/design/templates/token-search-field-dark.svg +1 -1
- package/docs/design/templates/token-search-field.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
- package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
- package/docs/design/templates/toolbar/width-visibility-320-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-320.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600-dark.svg +1 -0
- package/docs/design/templates/toolbar/width-visibility-600.svg +1 -0
- package/docs/design/templates/toolbar-control-group/borderless-single-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/borderless-single.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-buttons-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-buttons.svg +1 -1
- package/docs/design/templates/toolbar-control-group/icon-tile-brand-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-brand.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-danger.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-neutral.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-success.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning-dark.svg +1 -0
- package/docs/design/templates/toolbar-control-group/icon-tile-warning.svg +1 -0
- package/docs/design/templates/toolbar-control-group/push-buttons-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/push-buttons.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group/with-text.svg +1 -1
- package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
- package/docs/design/templates/toolbar-control-group.svg +1 -1
- package/docs/design/templates/toolbar-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/dark-tone-dark.svg +1 -0
- package/docs/design/templates/toolbar-text/dark-tone.svg +1 -0
- package/docs/design/templates/toolbar-text/default-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/default.svg +1 -1
- package/docs/design/templates/toolbar-text/large-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/large.svg +1 -1
- package/docs/design/templates/toolbar-text/small-dark.svg +1 -1
- package/docs/design/templates/toolbar-text/small.svg +1 -1
- package/docs/design/templates/toolbar-text-dark.svg +1 -1
- package/docs/design/templates/toolbar-text.svg +1 -1
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/design/templates/value-table/details-dark.svg +1 -1
- package/docs/design/templates/value-table/details.svg +1 -1
- package/docs/design/templates/value-table-dark.svg +1 -1
- package/docs/design/templates/value-table.svg +1 -1
- package/docs/design/templates.md +19 -9
- package/docs/design-philosophy.md +58 -11
- package/docs/device-class.md +2 -1
- package/docs/document-baseline.md +93 -0
- package/docs/examples/application-ui-profile.json +8 -8
- package/docs/examples/command-palette-adapter.tsx +9 -7
- package/docs/examples/component-catalog-extension.json +8 -1
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +8 -9
- package/docs/layout.md +764 -40
- package/docs/nav-stack.md +275 -11
- package/docs/recipes.md +125 -69
- package/docs/split-view.md +94 -5
- package/docs/sunken-panel.md +54 -1
- package/docs/surface-scaffold.md +270 -0
- package/docs/tab-navigator.md +255 -0
- package/docs/type-contracts.md +57 -22
- package/docs/ui-analyzer.md +334 -14
- package/docs/ui-doctor.md +207 -10
- package/docs/ui-evaluator.md +17 -0
- package/docs/ux-demo.md +47 -16
- package/docs/webawesome-theme.md +148 -14
- package/docs/workbench.md +600 -11
- package/docs/writing.md +152 -0
- package/doctor/cli.mjs +5 -0
- package/doctor/component-style-checks.mjs +457 -0
- package/doctor/config.schema.json +26 -0
- package/doctor/copy-capitalization-checks.mjs +591 -0
- package/doctor/eslint-diagnostics.d.mts +16 -0
- package/doctor/eslint-diagnostics.mjs +17 -0
- package/doctor/index.d.mts +6 -0
- package/doctor/index.mjs +214 -47
- package/evaluator/index.mjs +73 -8
- package/llms.txt +702 -56
- package/package.json +256 -25
- package/scripts/component-catalog-extension-validation.mjs +28 -0
- package/traversal-exclusions.mjs +60 -1
- package/ux-demo/recipes/app-shell.tsx +181 -189
- package/ux-demo/recipes/collapsible-sidebar.tsx +177 -139
- package/ux-demo/recipes/compact-toolbar.tsx +120 -101
- package/ux-demo/recipes/composer-form.tsx +86 -62
- package/ux-demo/recipes/list-detail-dialog.tsx +219 -114
- package/ux-demo/recipes/list-workspace-states.tsx +95 -80
- package/ux-demo/recipes/loaders.ts +5 -2
- package/ux-demo/recipes/loading-inspector.tsx +157 -117
- package/ux-demo/recipes/mount-recipe.ts +0 -5
- package/ux-demo/recipes/navigation-sidebar.tsx +98 -83
- package/ux-demo/recipes/navigation-stack.tsx +42 -29
- package/ux-demo/recipes/types.ts +14 -1
- package/ux-demo/recipes/workspace-header.tsx +77 -51
- package/vite-ux-review.d.mts +83 -0
- package/vite-ux-review.mjs +120 -0
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/ai/component-catalog-v2.d.ts +0 -67
- package/ai/component-catalog-v2.json +0 -4675
- package/ai/component-catalog-v2.schema.json +0 -246
- package/dist/browser/panel-header.js +0 -7
- package/dist/chunk-5VTB2BKP.js +0 -35
- package/dist/chunk-5VTB2BKP.js.map +0 -1
- package/dist/chunk-6WTETUZ6.js +0 -21
- package/dist/chunk-6WTETUZ6.js.map +0 -1
- package/dist/chunk-7KEUJIIC.js.map +0 -1
- package/dist/chunk-7XRDUG4Y.js +0 -58
- package/dist/chunk-7XRDUG4Y.js.map +0 -1
- package/dist/chunk-B3A3IVO5.js +0 -83
- package/dist/chunk-B3A3IVO5.js.map +0 -1
- package/dist/chunk-DPDBVKNA.js +0 -113
- package/dist/chunk-DPDBVKNA.js.map +0 -1
- package/dist/chunk-FEAMR7S4.js +0 -68
- package/dist/chunk-FEAMR7S4.js.map +0 -1
- package/dist/chunk-FEY65TBV.js +0 -15
- package/dist/chunk-FEY65TBV.js.map +0 -1
- package/dist/chunk-IJBSZ4NX.js.map +0 -1
- package/dist/chunk-J5BFYY7Q.js +0 -35
- package/dist/chunk-J5BFYY7Q.js.map +0 -1
- package/dist/chunk-JRKSK2HX.js.map +0 -1
- package/dist/chunk-KWWR5VMS.js.map +0 -1
- package/dist/chunk-LPOMRC4C.js.map +0 -1
- package/dist/chunk-M7JBER5U.js.map +0 -1
- package/dist/chunk-NENBUYX5.js +0 -79
- package/dist/chunk-NENBUYX5.js.map +0 -1
- package/dist/chunk-NWSEP5RT.js +0 -117
- package/dist/chunk-NWSEP5RT.js.map +0 -1
- package/dist/chunk-OJWWHFH3.js +0 -426
- package/dist/chunk-OJWWHFH3.js.map +0 -1
- package/dist/chunk-PSKN344N.js.map +0 -1
- package/dist/chunk-PX3YSS5C.js.map +0 -1
- package/dist/chunk-QO55FN2Y.js.map +0 -1
- package/dist/chunk-R7ZWUN64.js +0 -38
- package/dist/chunk-R7ZWUN64.js.map +0 -1
- package/dist/chunk-RKVQEH4J.js.map +0 -1
- package/dist/chunk-SRSJO5QE.js.map +0 -1
- package/dist/chunk-SYDMYBPG.js +0 -31
- package/dist/chunk-SYDMYBPG.js.map +0 -1
- package/dist/chunk-TB6DY7H5.js +0 -25
- package/dist/chunk-TB6DY7H5.js.map +0 -1
- package/dist/chunk-UFZKLBCF.js +0 -108
- package/dist/chunk-UFZKLBCF.js.map +0 -1
- package/dist/chunk-UKKSMZYT.js +0 -281
- package/dist/chunk-UKKSMZYT.js.map +0 -1
- package/dist/chunk-W2FK7ZNY.js +0 -26
- package/dist/chunk-W2FK7ZNY.js.map +0 -1
- package/dist/chunk-W5L2JSBY.js +0 -40
- package/dist/chunk-W5L2JSBY.js.map +0 -1
- package/dist/chunk-Y45PPBDV.js.map +0 -1
- package/dist/chunk-Y6LYKFXY.js.map +0 -1
- package/dist/divider-sides-267FA7sY.d.ts +0 -4
- package/dist/panel-header.d.ts +0 -42
- package/dist/panel-header.js +0 -7
- package/dist/panel-header.js.map +0 -1
- package/dist/styles/panel-header.css +0 -64
- package/dist/styles/tab-scaffold.css +0 -84
- package/dist/tab-scaffold.d.ts +0 -30
- package/dist/tab-scaffold.js +0 -51
- package/dist/tab-scaffold.js.map +0 -1
- package/dist/wire-tab-scaffold.d.ts +0 -11
- package/dist/wire-tab-scaffold.js +0 -21
- package/dist/wire-tab-scaffold.js.map +0 -1
- package/docs/design/templates/panel-header/icon-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-actions.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions-dark.svg +0 -1
- package/docs/design/templates/panel-header/icon-summary-actions.svg +0 -1
- package/docs/design/templates/panel-header/no-icon-dark.svg +0 -1
- package/docs/design/templates/panel-header/no-icon.svg +0 -1
- package/docs/design/templates/panel-header/page-heading-dark.svg +0 -1
- package/docs/design/templates/panel-header/page-heading.svg +0 -1
- package/docs/design/templates/panel-header/title-only-dark.svg +0 -1
- package/docs/design/templates/panel-header/title-only.svg +0 -1
- package/docs/design/templates/panel-header-dark.svg +0 -1
- package/docs/design/templates/panel-header.svg +0 -1
- package/docs/tab-scaffold.md +0 -50
- package/ux-demo/recipes/recipes.css +0 -448
package/docs/writing.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Writing interface copy
|
|
2
|
+
|
|
3
|
+
Kerf UI follows Apple's capitalization conventions for interface text.
|
|
4
|
+
Apple's _Writing_ guidance asks for one style per UI element type, applied
|
|
5
|
+
consistently, and its element guidance assigns those styles. This page is the
|
|
6
|
+
package default, so every Kerf application, demo, and recipe uses the same
|
|
7
|
+
rule. An application may replace it only through a written, product-wide
|
|
8
|
+
style. It should never vary from one screen to the next.
|
|
9
|
+
|
|
10
|
+
## Capitalization
|
|
11
|
+
|
|
12
|
+
**Names are title style. Descriptions are sentence style.** Text that names a
|
|
13
|
+
command, control, view, or field uses title style ("Save Draft", "Workspace
|
|
14
|
+
Settings", "Release Date"). Text that describes, explains, reports, or asks
|
|
15
|
+
uses sentence style ("Changes sync when you reconnect").
|
|
16
|
+
|
|
17
|
+
| Element | Style | Examples |
|
|
18
|
+
| --------------------------------------------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------ |
|
|
19
|
+
| Buttons, split-button and toolbar actions, link-style commands | Title | Save Draft, Add to Favorites, Don’t Save, Log In |
|
|
20
|
+
| Menu items, menu group headings, popup-menu triggers | Title | Copy Reference, Sort By, Recently Updated, New Folder… |
|
|
21
|
+
| Segmented-control segments, `Select` and pop-up choices, tabs | Title | List View, Last 30 Days, In Review |
|
|
22
|
+
| Page, view, pane, dialog, and toolbar titles (`ToolbarText` titles), back labels | Title | Workspace Settings, Back to Inbox |
|
|
23
|
+
| Group and list headers (`ListHeader`), table column headings | Title | Saved Projects, Needs Attention, Last Modified |
|
|
24
|
+
| Catalog example and stack labels (`CatalogExample`, `CatalogExampleStack`) | Title | Heading Identity Stays Whole, Icon Trigger in a Group |
|
|
25
|
+
| Content item titles: the name an item or card shows | Title | Build Output, Work Area, Unsaved Changes |
|
|
26
|
+
| Field labels (`FieldLabel`, a field's `label`) | Title | Project Name, Release Date |
|
|
27
|
+
| Region and landmark names (accessible names of panes, toolbars, groups, lists, tab bars) | Title | Ticket Workbench, View Actions, Open Documents |
|
|
28
|
+
| Accessible names of icon-only controls | Title | More Actions, Clear Search |
|
|
29
|
+
| `EmptyState`, `StateBanner`, alert, and notification titles that are fragments | Title, no ending punctuation | No Release Tasks, Migration Needs Review |
|
|
30
|
+
| The same titles written as complete sentences | Sentence, with punctuation | Release tasks could not be refreshed. |
|
|
31
|
+
| Checkbox, switch, and radio option text | Sentence | Show hidden files, Notify me about replies |
|
|
32
|
+
| Body copy, `description`, `detail`, hints, empty-state and banner detail, dialog and alert messages | Sentence, with punctuation | Changes sync when you reconnect. |
|
|
33
|
+
| Tooltips and help text | Sentence | Copy the link to this ticket |
|
|
34
|
+
| Placeholders | Sentence | Search tickets |
|
|
35
|
+
| Status lines, counts, and timestamps (`ToolbarText` status, `Badge`, `CornerStatus`) | Sentence | Saved just now, 3 of 12 updated |
|
|
36
|
+
| Progress labels (`LoadingSpinner` and `Skeleton` `label`): the operation under way | Sentence, trailing ellipsis | Loading preview…, Refreshing release tasks… |
|
|
37
|
+
|
|
38
|
+
A name that a component composes into a longer label is a name too, so pass
|
|
39
|
+
it in title style. A panel toolbar's `toggle: { action, name }` labels the
|
|
40
|
+
toggle group with `name` and completes "Show …" / "Hide …" with it:
|
|
41
|
+
`name: "Navigator"` gives "Show Navigator". Kerf UI never recapitalizes it.
|
|
42
|
+
|
|
43
|
+
Data is never recapitalized. Names that a person or a system supplies keep
|
|
44
|
+
their own spelling: file names, ticket titles, user names, and tags. So do
|
|
45
|
+
code identifiers shown as text, such as a prop value a specimen is labeled
|
|
46
|
+
with (`danger`, `transparent`). A content
|
|
47
|
+
item that shows such data (a ticket subject, a message) keeps it as written;
|
|
48
|
+
only a title the interface itself names is title style. `ContentItem`'s own
|
|
49
|
+
`title` prop is a native tooltip, so it is sentence style. Keep a content
|
|
50
|
+
item's `ariaLabel` equal to its visible title.
|
|
51
|
+
|
|
52
|
+
### Title-style rules
|
|
53
|
+
|
|
54
|
+
From the [Apple Style Guide](https://support.apple.com/guide/applestyleguide/c-apsgb744e4a3/web)
|
|
55
|
+
(_capitalization_):
|
|
56
|
+
|
|
57
|
+
- **Capitalize** the first and last word, whatever their part of speech.
|
|
58
|
+
- **Capitalize** nouns, pronouns, verbs, adjectives, and adverbs, however
|
|
59
|
+
short: It, This, Your, Is, Are, Be.
|
|
60
|
+
- **Capitalize** subordinating conjunctions such as If, and prepositions of
|
|
61
|
+
five letters or more: About, Between, Through.
|
|
62
|
+
- **Capitalize** a preposition of any length that belongs to a phrasal verb
|
|
63
|
+
or acts as another part of speech: Start Up the Computer, Turn On, Log In to
|
|
64
|
+
the Server.
|
|
65
|
+
- **Capitalize** the second word of a hyphenated compound: High-Level Events,
|
|
66
|
+
Pop-Up Menu. Built-in and Plug-in are the exceptions.
|
|
67
|
+
- **Keep lowercase**:
|
|
68
|
+
- articles (a, an, the), unless one is the first word or follows a colon;
|
|
69
|
+
- coordinating conjunctions (and, but, or, nor, for, yet, so);
|
|
70
|
+
- _to_ in an infinitive (How to Start Your Computer);
|
|
71
|
+
- _as_ (Export a Document as a PDF);
|
|
72
|
+
- prepositions of four letters or fewer (at, by, for, from, in, into, of,
|
|
73
|
+
off, on, onto, out, over, to, up, with).
|
|
74
|
+
- **Keep the brand's own spelling** for words that always start lowercase,
|
|
75
|
+
such as iPad, iOS, and macOS.
|
|
76
|
+
|
|
77
|
+
### Sentence-style rules
|
|
78
|
+
|
|
79
|
+
Capitalize the first word and proper nouns or adjectives only. End a complete
|
|
80
|
+
sentence with punctuation. Leave a fragment without ending punctuation.
|
|
81
|
+
Tooltips may omit the final period.
|
|
82
|
+
|
|
83
|
+
### Related conventions
|
|
84
|
+
|
|
85
|
+
- An ellipsis (…) ends a command or menu item that needs more input before it
|
|
86
|
+
acts: New Ticket…, Save As…. The dialog it opens repeats the command as its
|
|
87
|
+
title, without the ellipsis.
|
|
88
|
+
- Label an action with its result. Prefer a verb: Publish Update, not OK.
|
|
89
|
+
- Keep a control's accessible name equal to its visible label, or starting
|
|
90
|
+
with it.
|
|
91
|
+
|
|
92
|
+
## Diagnostics
|
|
93
|
+
|
|
94
|
+
`kerf-ui-doctor` reports `KUI-D040` (warning) when a string or template
|
|
95
|
+
literal passed to a known title-style prop leaves a word lowercase that title
|
|
96
|
+
style capitalizes. In a template literal it judges only the static words:
|
|
97
|
+
`` `Edit ${name} shortcut` `` should be `` `Edit ${name} Shortcut` ``, and the
|
|
98
|
+
interpolated value keeps its own spelling. The covered props are:
|
|
99
|
+
|
|
100
|
+
- `ToolbarText` `text` when the text is a title: it has `headingLevel`, a
|
|
101
|
+
large size, or sits in a toolbar or panel `title`, `header`, or (unless small) `leading` slot;
|
|
102
|
+
- `ListHeader`, `ListActionRow`, `SplitButton`, and `Combobox` `label`;
|
|
103
|
+
- `CatalogExample` and `CatalogExampleStack` `label`;
|
|
104
|
+
- `EmptyState` and `StateBanner` `title`;
|
|
105
|
+
- `PopupMenu` `text` and item and heading labels, including submenus;
|
|
106
|
+
- `SegmentedControl`, `Select`, and `TabNavigator` choice and tab labels;
|
|
107
|
+
- `NavStack` view titles and `backText`, and `SplitView` `backLabel`;
|
|
108
|
+
- `FieldLabel` text and the text of a `button` or `wa-button`;
|
|
109
|
+
- the `name` of a panel toolbar's `toggle: { action, name }`;
|
|
110
|
+
- region and landmark names: the `label` of `Pane`, `Workbench`, `Toolbar`,
|
|
111
|
+
`ToolbarControlGroup`, `TabBar`, `NavStack`, `CollapsiblePanel`,
|
|
112
|
+
`FloatingToolbar`, and `ResizableRegion`, the `ariaLabel` of `SunkenPanel`
|
|
113
|
+
and `List`, a `Pane`'s `contentLabel`, the panel, toolbar, and pane labels
|
|
114
|
+
inside `Workbench`, `CollapsiblePanel`, and `NavStack` configuration, and
|
|
115
|
+
the `aria-label` of a landmark element (`section`, `nav`, `aside`, `main`,
|
|
116
|
+
`header`, `footer`, `form`, `search`) or landmark role;
|
|
117
|
+
- the `label` of a raw `wa-input`, `wa-select`, `wa-textarea`, or
|
|
118
|
+
`wa-radio-group`;
|
|
119
|
+
- the accessible names of icon-only controls: `IconButton` and
|
|
120
|
+
`IconToggleButton` `label`, `PopupMenu` `label`, `SplitButton`
|
|
121
|
+
`optionsLabel`, `TokenSearchField` `clearLabel`, and the `aria-label` of a
|
|
122
|
+
`button` or `wa-button` whose only content is an icon.
|
|
123
|
+
|
|
124
|
+
The check never judges sentence-style surfaces (including `wa-checkbox`,
|
|
125
|
+
`wa-switch`, and `wa-radio` option text and the `LoadingSpinner` and
|
|
126
|
+
`Skeleton` status labels), interpolated or other dynamic values, or text
|
|
127
|
+
ending with `.`, `!`, or `?`. It skips a word joined to an interpolation, tokens containing digits, code, or paths, and
|
|
128
|
+
lowercase-led brands such as iOS. It does not report capitalized short words,
|
|
129
|
+
because Apple capitalizes a phrasal verb's particle. Suppress `KUI-D040` for a
|
|
130
|
+
lowercase brand or product name. See [the doctor](./ui-doctor.md).
|
|
131
|
+
|
|
132
|
+
## Sources
|
|
133
|
+
|
|
134
|
+
- Apple Human Interface Guidelines,
|
|
135
|
+
[Writing](https://developer.apple.com/design/human-interface-guidelines/writing):
|
|
136
|
+
choose a capitalization style for each element type and use it consistently.
|
|
137
|
+
- [Menus](https://developer.apple.com/design/human-interface-guidelines/menus)
|
|
138
|
+
and [The menu bar](https://developer.apple.com/design/human-interface-guidelines/the-menu-bar):
|
|
139
|
+
menu items and multi-word menu titles use title-style capitalization.
|
|
140
|
+
- [Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts)
|
|
141
|
+
and [Notifications](https://developer.apple.com/design/human-interface-guidelines/notifications):
|
|
142
|
+
a fragment title uses title style. A complete-sentence title and the
|
|
143
|
+
message use sentence style with punctuation.
|
|
144
|
+
- [Offering help](https://developer.apple.com/design/human-interface-guidelines/offering-help):
|
|
145
|
+
tooltips use sentence case.
|
|
146
|
+
- The archived OS X Human Interface Guidelines, _Use the Right Capitalization
|
|
147
|
+
Style in Labels and Text_. Title style covers menu titles and items, push
|
|
148
|
+
buttons, toolbar item labels, and labels that are not sentences, such as
|
|
149
|
+
group box and list headings. Sentence style covers checkbox and radio option
|
|
150
|
+
text and dialog messages.
|
|
151
|
+
- [Apple Style Guide](https://support.apple.com/guide/applestyleguide/c-apsgb744e4a3/web),
|
|
152
|
+
_capitalization_: the title-style word rules above.
|
package/doctor/cli.mjs
CHANGED
|
@@ -54,6 +54,7 @@ Options:
|
|
|
54
54
|
--browser <list> Comma-separated chromium,firefox,webkit
|
|
55
55
|
--eslint <preset> recommended-ui or strict-ui
|
|
56
56
|
--format <format> text or json (default: text)
|
|
57
|
+
--fail-on <severity> error, review, or warning (default: error)
|
|
57
58
|
--output <path> Also write the merged report
|
|
58
59
|
--no-cache Disable the content-addressed cache
|
|
59
60
|
|
|
@@ -68,6 +69,7 @@ Exit codes: 0 clean, 1 findings, 2 configuration/tool failure, 130 cancelled.`);
|
|
|
68
69
|
const browserList = take('--browser');
|
|
69
70
|
const eslintConfig = take('--eslint') ?? 'recommended-ui';
|
|
70
71
|
const format = take('--format') ?? 'text';
|
|
72
|
+
const failOn = take('--fail-on');
|
|
71
73
|
const output = take('--output');
|
|
72
74
|
const full = args.includes('--full');
|
|
73
75
|
const changed = args.includes('--changed');
|
|
@@ -80,6 +82,8 @@ Exit codes: 0 clean, 1 findings, 2 configuration/tool failure, 130 cancelled.`);
|
|
|
80
82
|
throw new Error('--full and --changed are mutually exclusive.');
|
|
81
83
|
if (!['text', 'json'].includes(format))
|
|
82
84
|
throw new Error('--format must be text or json.');
|
|
85
|
+
if (failOn && !['error', 'review', 'warning'].includes(failOn))
|
|
86
|
+
throw new Error('--fail-on must be error, review, or warning.');
|
|
83
87
|
if (!['recommended-ui', 'strict-ui'].includes(eslintConfig))
|
|
84
88
|
throw new Error('--eslint must be recommended-ui or strict-ui.');
|
|
85
89
|
const abort = new globalThis.AbortController();
|
|
@@ -95,6 +99,7 @@ Exit codes: 0 clean, 1 findings, 2 configuration/tool failure, 130 cancelled.`);
|
|
|
95
99
|
cache: !noCache,
|
|
96
100
|
signal: abort.signal,
|
|
97
101
|
eslintConfig,
|
|
102
|
+
failOn,
|
|
98
103
|
browser: url
|
|
99
104
|
? { url, browsers: browserList?.split(',').map((item) => item.trim()) }
|
|
100
105
|
: undefined,
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { basename, dirname, extname, relative, resolve } from 'node:path';
|
|
3
|
+
|
|
4
|
+
import postcss from 'postcss';
|
|
5
|
+
import ts from 'typescript';
|
|
6
|
+
|
|
7
|
+
import { loadApplicationUiProfile } from '../ai/application-ui-profile.mjs';
|
|
8
|
+
import { isUiTraversalExcluded } from '../traversal-exclusions.mjs';
|
|
9
|
+
|
|
10
|
+
const scriptExtensions = new Set(['.tsx', '.jsx']);
|
|
11
|
+
const kebab = (name) =>
|
|
12
|
+
name
|
|
13
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
14
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
15
|
+
.toLowerCase();
|
|
16
|
+
const componentName = (name) => /^[A-Z][A-Za-z0-9]*$/.test(name);
|
|
17
|
+
const classNames = (value) =>
|
|
18
|
+
[...value.matchAll(/(?:^|\s)([a-z][a-z0-9_-]*)(?=\s|$)/g)].map(
|
|
19
|
+
(match) => match[1],
|
|
20
|
+
);
|
|
21
|
+
const block = (name) => name.split(/__|--/)[0];
|
|
22
|
+
const unknown = '\u0000';
|
|
23
|
+
|
|
24
|
+
function combinations(left, right) {
|
|
25
|
+
if (left.length * right.length > 32) return [unknown];
|
|
26
|
+
return left.flatMap((a) => right.map((b) => a + b));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function staticPatterns(node, bindings = new Map(), seen = new Set()) {
|
|
30
|
+
if (!node) return [unknown];
|
|
31
|
+
if (ts.isIdentifier(node) && bindings.has(node.text) && !seen.has(node.text))
|
|
32
|
+
return staticPatterns(
|
|
33
|
+
bindings.get(node.text),
|
|
34
|
+
bindings,
|
|
35
|
+
new Set([...seen, node.text]),
|
|
36
|
+
);
|
|
37
|
+
if (
|
|
38
|
+
ts.isCallExpression(node) &&
|
|
39
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
40
|
+
node.expression.name.text === 'join'
|
|
41
|
+
) {
|
|
42
|
+
const target = node.expression.expression;
|
|
43
|
+
const array = ts.isIdentifier(target) ? bindings.get(target.text) : target;
|
|
44
|
+
if (array && ts.isArrayLiteralExpression(array)) {
|
|
45
|
+
const separator =
|
|
46
|
+
node.arguments[0] && ts.isStringLiteral(node.arguments[0])
|
|
47
|
+
? node.arguments[0].text
|
|
48
|
+
: ',';
|
|
49
|
+
let patterns = [''];
|
|
50
|
+
for (const [index, element] of array.elements.entries())
|
|
51
|
+
patterns = combinations(
|
|
52
|
+
patterns,
|
|
53
|
+
staticPatterns(element, bindings, seen).map(
|
|
54
|
+
(part) => `${index ? separator : ''}${part}`,
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
return patterns;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (
|
|
61
|
+
ts.isParenthesizedExpression(node) ||
|
|
62
|
+
ts.isAsExpression(node) ||
|
|
63
|
+
ts.isTypeAssertionExpression(node)
|
|
64
|
+
)
|
|
65
|
+
return staticPatterns(node.expression, bindings, seen);
|
|
66
|
+
if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node))
|
|
67
|
+
return [node.text];
|
|
68
|
+
if (ts.isConditionalExpression(node))
|
|
69
|
+
return [
|
|
70
|
+
...new Set([
|
|
71
|
+
...staticPatterns(node.whenTrue, bindings, seen),
|
|
72
|
+
...staticPatterns(node.whenFalse, bindings, seen),
|
|
73
|
+
]),
|
|
74
|
+
];
|
|
75
|
+
if (ts.isTemplateExpression(node)) {
|
|
76
|
+
let patterns = [node.head.text];
|
|
77
|
+
for (const span of node.templateSpans)
|
|
78
|
+
patterns = combinations(
|
|
79
|
+
combinations(patterns, staticPatterns(span.expression, bindings, seen)),
|
|
80
|
+
[span.literal.text],
|
|
81
|
+
);
|
|
82
|
+
return patterns;
|
|
83
|
+
}
|
|
84
|
+
if (
|
|
85
|
+
ts.isBinaryExpression(node) &&
|
|
86
|
+
node.operatorToken.kind === ts.SyntaxKind.PlusToken
|
|
87
|
+
)
|
|
88
|
+
return combinations(
|
|
89
|
+
staticPatterns(node.left, bindings, seen),
|
|
90
|
+
staticPatterns(node.right, bindings, seen),
|
|
91
|
+
);
|
|
92
|
+
return [unknown];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function guaranteedClasses(node, bindings) {
|
|
96
|
+
if (!node) return new Set();
|
|
97
|
+
if (
|
|
98
|
+
ts.isParenthesizedExpression(node) ||
|
|
99
|
+
ts.isAsExpression(node) ||
|
|
100
|
+
ts.isTypeAssertionExpression(node)
|
|
101
|
+
)
|
|
102
|
+
return guaranteedClasses(node.expression, bindings);
|
|
103
|
+
const patterns = staticPatterns(node, bindings);
|
|
104
|
+
const classes = new Set(classNames(patterns[0]));
|
|
105
|
+
for (const pattern of patterns.slice(1)) {
|
|
106
|
+
const other = new Set(classNames(pattern));
|
|
107
|
+
for (const name of classes) if (!other.has(name)) classes.delete(name);
|
|
108
|
+
}
|
|
109
|
+
return classes;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function returnedIntrinsic(node) {
|
|
113
|
+
while (node && ts.isParenthesizedExpression(node)) node = node.expression;
|
|
114
|
+
if (node && ts.isConditionalExpression(node))
|
|
115
|
+
return (
|
|
116
|
+
returnedIntrinsic(node.whenTrue) && returnedIntrinsic(node.whenFalse)
|
|
117
|
+
);
|
|
118
|
+
const tag =
|
|
119
|
+
node && ts.isJsxElement(node)
|
|
120
|
+
? node.openingElement.tagName
|
|
121
|
+
: node && ts.isJsxSelfClosingElement(node)
|
|
122
|
+
? node.tagName
|
|
123
|
+
: undefined;
|
|
124
|
+
return Boolean(tag && ts.isIdentifier(tag) && /^[a-z]/.test(tag.text));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function belongsToComponentReturn(node, owner) {
|
|
128
|
+
let scope = node.parent;
|
|
129
|
+
while (scope && !ts.isFunctionLike(scope)) scope = scope.parent;
|
|
130
|
+
if (!scope) return false;
|
|
131
|
+
if (ts.isFunctionDeclaration(scope)) return scope.name?.text === owner;
|
|
132
|
+
return (
|
|
133
|
+
ts.isArrowFunction(scope) &&
|
|
134
|
+
ts.isVariableDeclaration(scope.parent) &&
|
|
135
|
+
ts.isIdentifier(scope.parent.name) &&
|
|
136
|
+
scope.parent.name.text === owner
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function catalogAliases(workspaceRoot, packageRoot) {
|
|
141
|
+
const aliases = new Map();
|
|
142
|
+
const profile = await loadApplicationUiProfile({
|
|
143
|
+
workspaceRoot,
|
|
144
|
+
startDirectory: packageRoot,
|
|
145
|
+
knownRules: [],
|
|
146
|
+
packageProfile: resolve(
|
|
147
|
+
import.meta.dirname,
|
|
148
|
+
'../ai/application-ui-profile.defaults.json',
|
|
149
|
+
),
|
|
150
|
+
});
|
|
151
|
+
for (const catalog of profile.profile?.catalogs ?? []) {
|
|
152
|
+
const owner = profile.provenance?.[`$catalogs.${catalog.package}`];
|
|
153
|
+
if (!owner || !catalog.selection?.path) continue;
|
|
154
|
+
try {
|
|
155
|
+
const selection = JSON.parse(
|
|
156
|
+
await readFile(resolve(dirname(owner), catalog.selection.path), 'utf8'),
|
|
157
|
+
);
|
|
158
|
+
const composition = catalog.composition?.path
|
|
159
|
+
? JSON.parse(
|
|
160
|
+
await readFile(
|
|
161
|
+
resolve(dirname(owner), catalog.composition.path),
|
|
162
|
+
'utf8',
|
|
163
|
+
),
|
|
164
|
+
)
|
|
165
|
+
: { entries: [] };
|
|
166
|
+
const composed = new Map(
|
|
167
|
+
(composition.entries ?? []).map((entry) => [entry.key, entry]),
|
|
168
|
+
);
|
|
169
|
+
for (const entry of selection.entries ?? []) {
|
|
170
|
+
if (!entry.source || !entry.name) continue;
|
|
171
|
+
const source = resolve(dirname(owner), entry.source);
|
|
172
|
+
const relativeSource = relative(packageRoot, source);
|
|
173
|
+
if (relativeSource === '..' || relativeSource.startsWith('../'))
|
|
174
|
+
continue;
|
|
175
|
+
const detail = composed.get(
|
|
176
|
+
`${selection.package ?? catalog.package}:${entry.id}`,
|
|
177
|
+
);
|
|
178
|
+
const classes = [
|
|
179
|
+
detail?.boundaries?.rootClass,
|
|
180
|
+
...(detail?.boundaries?.publicClasses ?? []),
|
|
181
|
+
...(entry.publicClasses ?? []),
|
|
182
|
+
].filter(Boolean);
|
|
183
|
+
const styleSources = [
|
|
184
|
+
...(detail?.styleSources ?? []),
|
|
185
|
+
...(entry.styleSources ?? []),
|
|
186
|
+
].map((style) => resolve(dirname(owner), style));
|
|
187
|
+
aliases.set(`${source}:${entry.name}`, {
|
|
188
|
+
classes: new Set(classes),
|
|
189
|
+
styles: new Set(styleSources),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
// The catalog stage reports invalid or missing artifacts.
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return aliases;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function componentFacts(file, source) {
|
|
200
|
+
const syntax = file.endsWith('.tsx') ? ts.ScriptKind.TSX : ts.ScriptKind.JSX;
|
|
201
|
+
const ast = ts.createSourceFile(
|
|
202
|
+
file,
|
|
203
|
+
source,
|
|
204
|
+
ts.ScriptTarget.Latest,
|
|
205
|
+
true,
|
|
206
|
+
syntax,
|
|
207
|
+
);
|
|
208
|
+
const components = new Map();
|
|
209
|
+
const visit = (node, owner) => {
|
|
210
|
+
if (
|
|
211
|
+
ts.isFunctionDeclaration(node) &&
|
|
212
|
+
node.name &&
|
|
213
|
+
componentName(node.name.text)
|
|
214
|
+
)
|
|
215
|
+
owner = node.name.text;
|
|
216
|
+
if (
|
|
217
|
+
ts.isVariableDeclaration(node) &&
|
|
218
|
+
ts.isIdentifier(node.name) &&
|
|
219
|
+
componentName(node.name.text)
|
|
220
|
+
)
|
|
221
|
+
owner = node.name.text;
|
|
222
|
+
else if (
|
|
223
|
+
owner &&
|
|
224
|
+
ts.isVariableDeclaration(node) &&
|
|
225
|
+
ts.isIdentifier(node.name) &&
|
|
226
|
+
node.initializer
|
|
227
|
+
)
|
|
228
|
+
components.get(owner)?.bindings.set(node.name.text, node.initializer);
|
|
229
|
+
if (
|
|
230
|
+
owner &&
|
|
231
|
+
(ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node))
|
|
232
|
+
) {
|
|
233
|
+
if (ts.isIdentifier(node.tagName) && /^[a-z]/.test(node.tagName.text)) {
|
|
234
|
+
for (const attribute of node.attributes.properties) {
|
|
235
|
+
if (
|
|
236
|
+
!ts.isJsxAttribute(attribute) ||
|
|
237
|
+
!['class', 'className'].includes(attribute.name.text)
|
|
238
|
+
)
|
|
239
|
+
continue;
|
|
240
|
+
const value = attribute.initializer;
|
|
241
|
+
const classes =
|
|
242
|
+
value && ts.isStringLiteral(value)
|
|
243
|
+
? classNames(value.text)
|
|
244
|
+
: value && ts.isJsxExpression(value)
|
|
245
|
+
? guaranteedClasses(
|
|
246
|
+
value.expression,
|
|
247
|
+
components.get(owner)?.bindings,
|
|
248
|
+
)
|
|
249
|
+
: [];
|
|
250
|
+
if (
|
|
251
|
+
value &&
|
|
252
|
+
ts.isJsxExpression(value) &&
|
|
253
|
+
staticPatterns(
|
|
254
|
+
value.expression,
|
|
255
|
+
components.get(owner)?.bindings,
|
|
256
|
+
).every((pattern) => pattern === unknown)
|
|
257
|
+
)
|
|
258
|
+
components.get(owner).uncertain = true;
|
|
259
|
+
for (const name of classes) components.get(owner)?.add(name);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (
|
|
264
|
+
owner &&
|
|
265
|
+
ts.isReturnStatement(node) &&
|
|
266
|
+
belongsToComponentReturn(node, owner) &&
|
|
267
|
+
returnedIntrinsic(node.expression)
|
|
268
|
+
)
|
|
269
|
+
components.get(owner).intrinsic = true;
|
|
270
|
+
if (
|
|
271
|
+
owner &&
|
|
272
|
+
ts.isArrowFunction(node) &&
|
|
273
|
+
ts.isVariableDeclaration(node.parent) &&
|
|
274
|
+
ts.isIdentifier(node.parent.name) &&
|
|
275
|
+
node.parent.name.text === owner &&
|
|
276
|
+
returnedIntrinsic(node.body)
|
|
277
|
+
)
|
|
278
|
+
components.get(owner).intrinsic = true;
|
|
279
|
+
ts.forEachChild(node, (child) => visit(child, owner));
|
|
280
|
+
};
|
|
281
|
+
const declarations = (node) => {
|
|
282
|
+
if (
|
|
283
|
+
ts.isFunctionDeclaration(node) &&
|
|
284
|
+
node.name &&
|
|
285
|
+
componentName(node.name.text)
|
|
286
|
+
)
|
|
287
|
+
components.set(
|
|
288
|
+
node.name.text,
|
|
289
|
+
Object.assign(new Set(), { bindings: new Map() }),
|
|
290
|
+
);
|
|
291
|
+
if (
|
|
292
|
+
ts.isVariableDeclaration(node) &&
|
|
293
|
+
ts.isIdentifier(node.name) &&
|
|
294
|
+
componentName(node.name.text)
|
|
295
|
+
)
|
|
296
|
+
components.set(
|
|
297
|
+
node.name.text,
|
|
298
|
+
Object.assign(new Set(), { bindings: new Map() }),
|
|
299
|
+
);
|
|
300
|
+
ts.forEachChild(node, declarations);
|
|
301
|
+
};
|
|
302
|
+
declarations(ast);
|
|
303
|
+
visit(ast);
|
|
304
|
+
return components;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function diagnostic(id, file, line, message, action) {
|
|
308
|
+
return {
|
|
309
|
+
id,
|
|
310
|
+
severity: 'error',
|
|
311
|
+
stage: 'analyzer',
|
|
312
|
+
message,
|
|
313
|
+
location: { file, line, column: 1 },
|
|
314
|
+
action,
|
|
315
|
+
documentation: '@kerfjs/ui/docs/ui-doctor.md#component-style-naming',
|
|
316
|
+
meaning: {
|
|
317
|
+
'KUI-D030': 'Component root class does not match its name',
|
|
318
|
+
'KUI-D031': 'Component stylesheet does not match its name',
|
|
319
|
+
'KUI-D032': 'Stylesheet selects another component class',
|
|
320
|
+
}[id],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export async function checkComponentStyles(
|
|
325
|
+
packageRoot,
|
|
326
|
+
inputs,
|
|
327
|
+
ownershipGroups = [],
|
|
328
|
+
selectedPaths,
|
|
329
|
+
workspaceRoot = packageRoot,
|
|
330
|
+
) {
|
|
331
|
+
const aliases = await catalogAliases(workspaceRoot, packageRoot);
|
|
332
|
+
const scripts = new Map();
|
|
333
|
+
const styles = new Map();
|
|
334
|
+
const importedBy = new Map();
|
|
335
|
+
for (const file of inputs) {
|
|
336
|
+
if (isUiTraversalExcluded(packageRoot, file)) continue;
|
|
337
|
+
const extension = extname(file);
|
|
338
|
+
if (scriptExtensions.has(extension)) {
|
|
339
|
+
const source = await readFile(file, 'utf8');
|
|
340
|
+
scripts.set(file, componentFacts(file, source));
|
|
341
|
+
for (const match of source.matchAll(
|
|
342
|
+
/\bimport\s*(?:['"]|[^;]*?\bfrom\s*['"])(\.[^'"]+\.css)['"]/g,
|
|
343
|
+
)) {
|
|
344
|
+
const style = resolve(dirname(file), match[1]);
|
|
345
|
+
const importers = importedBy.get(style) ?? [];
|
|
346
|
+
importers.push(file);
|
|
347
|
+
importedBy.set(style, importers);
|
|
348
|
+
}
|
|
349
|
+
} else if (extension === '.css')
|
|
350
|
+
styles.set(file, await readFile(file, 'utf8'));
|
|
351
|
+
}
|
|
352
|
+
const owners = new Map();
|
|
353
|
+
for (const [file, components] of scripts)
|
|
354
|
+
for (const [name, classes] of components)
|
|
355
|
+
if (classes.has(kebab(name)))
|
|
356
|
+
owners.set(kebab(name), { file, name, classes });
|
|
357
|
+
const diagnostics = [];
|
|
358
|
+
for (const [file, source] of styles) {
|
|
359
|
+
if (
|
|
360
|
+
ownershipGroups.some((group) =>
|
|
361
|
+
group.styleSources?.some(
|
|
362
|
+
(style) => resolve(packageRoot, style) === file,
|
|
363
|
+
),
|
|
364
|
+
)
|
|
365
|
+
)
|
|
366
|
+
continue;
|
|
367
|
+
const stem = basename(file, '.css');
|
|
368
|
+
const pair =
|
|
369
|
+
[...scriptExtensions]
|
|
370
|
+
.map((extension) => resolve(dirname(file), `${stem}${extension}`))
|
|
371
|
+
.find((candidate) => scripts.has(candidate)) ??
|
|
372
|
+
(importedBy.get(file)?.length === 1
|
|
373
|
+
? importedBy.get(file)[0]
|
|
374
|
+
: undefined);
|
|
375
|
+
if (!pair) continue;
|
|
376
|
+
const path = relative(packageRoot, file).replaceAll('\\', '/');
|
|
377
|
+
if (
|
|
378
|
+
selectedPaths?.length &&
|
|
379
|
+
!selectedPaths.includes(path) &&
|
|
380
|
+
!selectedPaths.includes(relative(packageRoot, pair).replaceAll('\\', '/'))
|
|
381
|
+
)
|
|
382
|
+
continue;
|
|
383
|
+
const components = scripts.get(pair);
|
|
384
|
+
const matching =
|
|
385
|
+
[...components].find(([name]) => kebab(name) === stem) ??
|
|
386
|
+
[...components].find(([name]) =>
|
|
387
|
+
aliases.get(`${pair}:${name}`)?.styles.has(file),
|
|
388
|
+
);
|
|
389
|
+
if (!matching) {
|
|
390
|
+
const names = [...components.keys()];
|
|
391
|
+
if (names.length === 1)
|
|
392
|
+
diagnostics.push(
|
|
393
|
+
diagnostic(
|
|
394
|
+
'KUI-D031',
|
|
395
|
+
path,
|
|
396
|
+
1,
|
|
397
|
+
`${basename(file)} is paired with ${basename(pair)}, but its component ${names[0]} calls for ${kebab(names[0])}.css.`,
|
|
398
|
+
`Rename the stylesheet and its import to ${kebab(names[0])}.css, or rename the component and source pair.`,
|
|
399
|
+
),
|
|
400
|
+
);
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
const [name, renderedClasses] = matching;
|
|
404
|
+
const declaredClasses =
|
|
405
|
+
aliases.get(`${pair}:${name}`)?.classes ?? new Set();
|
|
406
|
+
if (
|
|
407
|
+
renderedClasses.intrinsic &&
|
|
408
|
+
!renderedClasses.uncertain &&
|
|
409
|
+
!renderedClasses.has(stem) &&
|
|
410
|
+
![...declaredClasses].some((className) => renderedClasses.has(className))
|
|
411
|
+
)
|
|
412
|
+
diagnostics.push(
|
|
413
|
+
diagnostic(
|
|
414
|
+
'KUI-D030',
|
|
415
|
+
relative(packageRoot, pair).replaceAll('\\', '/'),
|
|
416
|
+
1,
|
|
417
|
+
`${name} must render its own .${stem} root class.`,
|
|
418
|
+
`Add class="${stem}" to an element rendered by ${name}, then select that class in ${basename(file)}.`,
|
|
419
|
+
),
|
|
420
|
+
);
|
|
421
|
+
let sheet;
|
|
422
|
+
try {
|
|
423
|
+
sheet = postcss.parse(source, { from: file });
|
|
424
|
+
} catch {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
sheet.walkRules((rule) => {
|
|
428
|
+
if (
|
|
429
|
+
rule.parent?.type === 'atrule' &&
|
|
430
|
+
/keyframes$/i.test(rule.parent.name)
|
|
431
|
+
)
|
|
432
|
+
return;
|
|
433
|
+
const selected = [
|
|
434
|
+
...new Set(
|
|
435
|
+
[...rule.selector.matchAll(/\.([a-z][a-z0-9_-]*)/gi)].map(
|
|
436
|
+
(match) => match[1],
|
|
437
|
+
),
|
|
438
|
+
),
|
|
439
|
+
];
|
|
440
|
+
for (const className of selected) {
|
|
441
|
+
const foreign = owners.get(block(className));
|
|
442
|
+
if (!foreign || foreign.name === name || foreign.file === pair)
|
|
443
|
+
continue;
|
|
444
|
+
diagnostics.push(
|
|
445
|
+
diagnostic(
|
|
446
|
+
'KUI-D032',
|
|
447
|
+
path,
|
|
448
|
+
rule.source?.start?.line ?? 1,
|
|
449
|
+
`${basename(file)} selects .${className}, which belongs to ${foreign.name} in ${relative(packageRoot, foreign.file).replaceAll('\\', '/')}.`,
|
|
450
|
+
`Move this rule to ${kebab(foreign.name)}.css or configure ${foreign.name} through its public API.`,
|
|
451
|
+
),
|
|
452
|
+
);
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
return diagnostics;
|
|
457
|
+
}
|
|
@@ -9,6 +9,31 @@
|
|
|
9
9
|
"schemaVersion": { "const": 1 },
|
|
10
10
|
"mode": { "enum": ["full", "changed"] },
|
|
11
11
|
"package": { "type": "string", "minLength": 1 },
|
|
12
|
+
"ownership": { "enum": ["package", "component"] },
|
|
13
|
+
"ownershipContext": { "enum": ["subject", "any", "any-package"] },
|
|
14
|
+
"implicitComponentOwnership": { "type": "boolean" },
|
|
15
|
+
"ownershipGroups": {
|
|
16
|
+
"type": "array",
|
|
17
|
+
"items": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"required": ["styleSources", "sources"],
|
|
20
|
+
"properties": {
|
|
21
|
+
"styleSources": {
|
|
22
|
+
"type": "array",
|
|
23
|
+
"minItems": 1,
|
|
24
|
+
"uniqueItems": true,
|
|
25
|
+
"items": { "$ref": "#/$defs/path" }
|
|
26
|
+
},
|
|
27
|
+
"sources": {
|
|
28
|
+
"type": "array",
|
|
29
|
+
"minItems": 1,
|
|
30
|
+
"uniqueItems": true,
|
|
31
|
+
"items": { "$ref": "#/$defs/path" }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"additionalProperties": false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
12
37
|
"stages": {
|
|
13
38
|
"type": "object",
|
|
14
39
|
"properties": {
|
|
@@ -37,6 +62,7 @@
|
|
|
37
62
|
"additionalProperties": false
|
|
38
63
|
},
|
|
39
64
|
"cache": { "type": "boolean" },
|
|
65
|
+
"failOn": { "enum": ["error", "review", "warning"] },
|
|
40
66
|
"suppressions": {
|
|
41
67
|
"type": "array",
|
|
42
68
|
"items": {
|