@kerfjs/ui 5.0.0-beta.56 → 5.0.0-beta.58
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 +81 -37
- package/ai/application-ui-diagnostic-ids-v1.json +9 -1
- package/ai/application-ui-profile-sync.cjs +1 -1
- package/ai/application-ui-profile.defaults.json +63 -8
- package/ai/application-ui-profile.mjs +1 -1
- package/ai/component-catalog.json +211 -33
- package/ai/component-catalog.schema.json +2 -0
- 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} +2 -1
- package/ai/{component-catalog-v2.d.ts → component-composition.d.ts} +9 -5
- package/ai/{component-catalog-v2.json → component-composition.json} +155 -24
- package/ai/{component-catalog-v2.schema.json → component-composition.schema.json} +21 -5
- package/ai/components/README.md +170 -0
- package/ai/components/application-tabs.md +65 -0
- package/ai/components/badge.md +72 -0
- package/ai/components/collapsible-panel.md +102 -0
- package/ai/components/content-item.md +90 -0
- package/ai/components/disclosure-arrow.md +77 -0
- package/ai/components/document-baseline.md +75 -0
- package/ai/components/empty-state.md +80 -0
- package/ai/components/feedback.md +71 -0
- package/ai/components/floating-toolbar.md +80 -0
- package/ai/components/foundation.md +65 -0
- package/ai/components/grid.md +93 -0
- package/ai/components/headers.md +63 -0
- package/ai/components/layout.md +75 -0
- package/ai/components/list-action-row.md +91 -0
- package/ai/components/list-header.md +89 -0
- package/ai/components/list-inset-control.md +74 -0
- package/ai/components/list-inset-text.md +72 -0
- package/ai/components/list-item.md +88 -0
- package/ai/components/list.md +103 -0
- package/ai/components/loading-spinner.md +72 -0
- package/ai/components/lucide-icon.md +66 -0
- package/ai/components/nav-stack.md +103 -0
- package/ai/components/pane.md +100 -0
- package/ai/components/popup-menu.md +82 -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 +101 -0
- package/ai/components/row.md +96 -0
- package/ai/components/segmented-control.md +82 -0
- package/ai/components/select.md +107 -0
- package/ai/components/skeleton.md +84 -0
- package/ai/components/spacer.md +86 -0
- package/ai/components/split-view.md +102 -0
- package/ai/components/state-banner.md +92 -0
- package/ai/components/sunken-panel.md +79 -0
- package/ai/components/surface-scaffold.md +78 -0
- package/ai/components/tab-bar.md +112 -0
- package/ai/components/tab-scaffold.md +94 -0
- package/ai/components/tabs.md +90 -0
- package/ai/components/text.md +82 -0
- package/ai/components/token-search-field.md +101 -0
- package/ai/components/toolbar-control-group.md +102 -0
- package/ai/components/toolbar-text.md +76 -0
- package/ai/components/toolbar.md +95 -0
- package/ai/components/value-table.md +72 -0
- package/ai/components/wa-accordion-item.md +55 -0
- package/ai/components/wa-accordion.md +65 -0
- package/ai/components/wa-animated-image.md +55 -0
- package/ai/components/wa-animation.md +55 -0
- package/ai/components/wa-avatar.md +55 -0
- package/ai/components/wa-badge.md +55 -0
- package/ai/components/wa-breadcrumb-item.md +53 -0
- package/ai/components/wa-breadcrumb.md +55 -0
- package/ai/components/wa-button-group.md +59 -0
- package/ai/components/wa-button.md +55 -0
- package/ai/components/wa-callout.md +58 -0
- package/ai/components/wa-card.md +59 -0
- package/ai/components/wa-carousel-item.md +53 -0
- package/ai/components/wa-carousel.md +55 -0
- package/ai/components/wa-checkbox-group.md +55 -0
- package/ai/components/wa-checkbox.md +55 -0
- package/ai/components/wa-color-picker.md +55 -0
- package/ai/components/wa-comparison.md +55 -0
- package/ai/components/wa-copy-button.md +55 -0
- package/ai/components/wa-details.md +61 -0
- package/ai/components/wa-dialog.md +59 -0
- package/ai/components/wa-divider.md +53 -0
- package/ai/components/wa-drawer.md +55 -0
- package/ai/components/wa-dropdown-item.md +60 -0
- package/ai/components/wa-dropdown.md +60 -0
- package/ai/components/wa-format-bytes.md +53 -0
- package/ai/components/wa-format-date.md +53 -0
- package/ai/components/wa-format-number.md +53 -0
- package/ai/components/wa-icon.md +58 -0
- package/ai/components/wa-include.md +53 -0
- package/ai/components/wa-input.md +59 -0
- package/ai/components/wa-intersection-observer.md +53 -0
- package/ai/components/wa-known-date.md +53 -0
- package/ai/components/wa-markdown.md +53 -0
- package/ai/components/wa-mutation-observer.md +53 -0
- package/ai/components/wa-number-input.md +55 -0
- package/ai/components/wa-option.md +59 -0
- package/ai/components/wa-otp-input.md +53 -0
- package/ai/components/wa-page.md +53 -0
- package/ai/components/wa-pagination.md +55 -0
- package/ai/components/wa-popover.md +55 -0
- package/ai/components/wa-popup.md +53 -0
- package/ai/components/wa-progress-bar.md +53 -0
- package/ai/components/wa-progress-ring.md +53 -0
- package/ai/components/wa-qr-code.md +53 -0
- package/ai/components/wa-radio-group.md +59 -0
- package/ai/components/wa-radio.md +55 -0
- package/ai/components/wa-random-content.md +53 -0
- package/ai/components/wa-rating.md +55 -0
- package/ai/components/wa-relative-time.md +53 -0
- package/ai/components/wa-resize-observer.md +53 -0
- package/ai/components/wa-scroller.md +53 -0
- package/ai/components/wa-select.md +63 -0
- package/ai/components/wa-skeleton.md +53 -0
- package/ai/components/wa-slider.md +55 -0
- package/ai/components/wa-spinner.md +58 -0
- package/ai/components/wa-split-panel.md +58 -0
- package/ai/components/wa-switch.md +53 -0
- package/ai/components/wa-tab-group.md +69 -0
- package/ai/components/wa-tab-panel.md +60 -0
- package/ai/components/wa-tab.md +59 -0
- package/ai/components/wa-tag.md +59 -0
- package/ai/components/wa-textarea.md +53 -0
- package/ai/components/wa-time-input.md +55 -0
- package/ai/components/wa-toast-item.md +60 -0
- package/ai/components/wa-toast.md +60 -0
- package/ai/components/wa-tooltip.md +55 -0
- package/ai/components/wa-tree-item.md +55 -0
- package/ai/components/wa-tree.md +55 -0
- package/ai/components/wa-zoomable-frame.md +55 -0
- package/ai/components/workbench.md +114 -0
- package/ai/public-api-signatures-v1.md +174 -43
- package/ai/skill.md +100 -48
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/component-ownership.d.mts +56 -0
- package/analyzer/component-ownership.mjs +184 -0
- package/analyzer/index.d.mts +3 -0
- package/analyzer/index.mjs +274 -20
- package/analyzer/selectors.d.mts +21 -0
- package/analyzer/selectors.mjs +212 -0
- package/dist/browser/catalog.js +25 -0
- package/dist/browser/collapsible-panel.js +7 -0
- package/dist/browser/nav-stack.js +8 -0
- package/dist/browser/split-view.js +10 -0
- package/dist/browser/tab-scaffold.js +4 -0
- package/dist/browser/workbench.js +10 -0
- package/dist/catalog-resources.d.ts +2 -2
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +8 -7
- package/dist/catalog.js.map +1 -1
- package/dist/{chunk-QQOTQTDD.js → chunk-2CCMJTVY.js} +13 -10
- package/dist/chunk-2CCMJTVY.js.map +1 -0
- package/dist/{chunk-PK4N5QTO.js → chunk-553ASUK6.js} +2 -3
- package/dist/chunk-553ASUK6.js.map +1 -0
- package/dist/{chunk-G33XC2NB.js → chunk-6YFHCLHG.js} +2 -2
- package/dist/chunk-6YFHCLHG.js.map +1 -0
- package/dist/{chunk-ZIYOJFZD.js → chunk-7JUBXOIV.js} +17 -4
- package/dist/chunk-7JUBXOIV.js.map +1 -0
- package/dist/{chunk-T4UZTNZ4.js → chunk-EVYKTVBQ.js} +2 -11
- package/dist/chunk-EVYKTVBQ.js.map +1 -0
- package/dist/{chunk-AK67F6QN.js → chunk-EZVNC4J6.js} +4 -1
- package/dist/chunk-EZVNC4J6.js.map +1 -0
- package/dist/{chunk-MA6Z6EIM.js → chunk-F4QMLOXJ.js} +3 -2
- package/dist/chunk-F4QMLOXJ.js.map +1 -0
- package/dist/chunk-JCV4GXWB.js +249 -0
- package/dist/chunk-JCV4GXWB.js.map +1 -0
- package/dist/chunk-K47P7QZC.js +17 -0
- package/dist/chunk-K47P7QZC.js.map +1 -0
- package/dist/{chunk-MOBRFZH3.js → chunk-OUK6QRDR.js} +2 -12
- package/dist/chunk-OUK6QRDR.js.map +1 -0
- package/dist/{chunk-VNPQDCQZ.js → chunk-QOWG4ZCL.js} +3 -2
- package/dist/chunk-QOWG4ZCL.js.map +1 -0
- package/dist/{chunk-V65EOWNF.js → chunk-QPUPLNNB.js} +20 -8
- package/dist/chunk-QPUPLNNB.js.map +1 -0
- package/dist/{chunk-O3EXIBEZ.js → chunk-W4XKTST6.js} +8 -7
- package/dist/chunk-W4XKTST6.js.map +1 -0
- package/dist/{chunk-K6UNVKDK.js → chunk-XDKAYSVD.js} +3 -1
- package/dist/chunk-XDKAYSVD.js.map +1 -0
- package/dist/collapsible-panel.d.ts +9 -9
- package/dist/collapsible-panel.js +2 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11 -9
- package/dist/list-action-row.js +2 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +2 -1
- package/dist/nav-stack.d.ts +13 -1
- package/dist/nav-stack.js +1 -1
- package/dist/pane.d.ts +20 -3
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-C8sF-YZC.d.ts → panel-toolbar-DqwtBxQL.d.ts} +13 -13
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +3 -3
- package/dist/split-view.js +3 -2
- package/dist/split-view.js.map +1 -1
- package/dist/state-banner.js +1 -1
- package/dist/styles/app-tab.css +31 -0
- package/dist/styles/badge.css +19 -11
- package/dist/styles/collapsible-panel.css +13 -9
- package/dist/styles/floating-toolbar.css +25 -6
- package/dist/styles/list-header.css +0 -12
- package/dist/styles/list.css +4 -4
- package/dist/styles/nav-stack.css +46 -19
- package/dist/styles/pane.css +50 -0
- package/dist/styles/popup-menu.css +151 -0
- package/dist/styles/resizable-region.css +22 -10
- package/dist/styles/select.css +28 -14
- package/dist/styles/skeleton.css +30 -3
- package/dist/styles/split-view.css +10 -7
- package/dist/styles/state-banner.css +0 -19
- package/dist/styles/surface-scaffold.css +8 -3
- package/dist/styles/tab-bar.css +79 -28
- package/dist/styles/tab-scaffold.css +25 -1
- package/dist/styles/text.css +16 -0
- package/dist/styles/toolbar-control-group.css +121 -66
- package/dist/styles/toolbar-text.css +21 -0
- package/dist/styles/toolbar.css +8 -32
- package/dist/styles/workbench.css +18 -18
- package/dist/tab-scaffold.d.ts +11 -1
- package/dist/tab-scaffold.js +2 -0
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/toolbar-control-group.d.ts +3 -1
- package/dist/toolbar-control-group.js +1 -1
- package/dist/toolbar-text.d.ts +7 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +8 -1
- package/dist/toolbar.js +1 -1
- package/dist/{types-DXAGogOS.d.ts → types-BuHELdXR.d.ts} +1 -1
- package/dist/wire-catalog.d.ts +3 -1
- package/dist/wire-catalog.js +2 -0
- package/dist/wire-catalog.js.map +1 -1
- package/dist/wire-scroll-dividers.d.ts +69 -0
- package/dist/wire-scroll-dividers.js +3 -0
- package/dist/wire-scroll-dividers.js.map +1 -0
- package/dist/workbench.d.ts +17 -16
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +9 -1
- package/docs/catalog.md +10 -5
- package/docs/collapsible-panel.md +22 -13
- package/docs/component-contract.md +147 -21
- package/docs/component-selection.md +21 -8
- 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-philosophy.md +30 -3
- package/docs/examples/application-ui-profile.json +4 -4
- package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json} +3 -3
- package/docs/layout.md +82 -3
- package/docs/nav-stack.md +33 -3
- package/docs/split-view.md +10 -5
- package/docs/tab-scaffold.md +23 -1
- package/docs/type-contracts.md +4 -3
- package/docs/ui-analyzer.md +99 -5
- package/docs/ui-doctor.md +10 -0
- package/docs/workbench.md +31 -20
- package/doctor/index.mjs +6 -1
- package/llms.txt +85 -20
- package/package.json +17 -5
- package/ux-demo/recipes/collapsible-sidebar.tsx +0 -1
- package/ux-demo/recipes/composer-form.tsx +0 -1
- package/ux-demo/recipes/list-detail-dialog.tsx +0 -2
- package/ux-demo/recipes/list-workspace-states.tsx +0 -1
- package/ux-demo/recipes/loading-inspector.tsx +0 -1
- package/ux-demo/recipes/workspace-header.tsx +0 -1
- package/ai/component-catalog-extension-v2.d.ts +0 -7
- package/ai/component-catalog-extension-v2.schema.json +0 -7
- package/dist/chunk-AK67F6QN.js.map +0 -1
- package/dist/chunk-G33XC2NB.js.map +0 -1
- package/dist/chunk-K6UNVKDK.js.map +0 -1
- package/dist/chunk-MA6Z6EIM.js.map +0 -1
- package/dist/chunk-MOBRFZH3.js.map +0 -1
- package/dist/chunk-O3EXIBEZ.js.map +0 -1
- package/dist/chunk-PK4N5QTO.js.map +0 -1
- package/dist/chunk-QQOTQTDD.js.map +0 -1
- package/dist/chunk-T4UZTNZ4.js.map +0 -1
- package/dist/chunk-V65EOWNF.js.map +0 -1
- package/dist/chunk-VNPQDCQZ.js.map +0 -1
- package/dist/chunk-ZIYOJFZD.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 150" width="672" height="150"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="96"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="96" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="150" rx="0" fill="rgb(28,28,30)"/><text x="16" y="28" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Selected tab among peers</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="96"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="584" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="29" y="29" width="582" height="42" rx="21"/></clipPath><filter id="svgimg3sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg3cp3"><rect x="67" y="42" width="16.4" height="16"/></clipPath><clipPath id="svgimg3cp5"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3ct6"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3cp7"><rect x="240.5" y="42" width="16.5" height="16"/></clipPath><clipPath id="svgimg3cp9"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3ct10"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3cp11"><rect x="387" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp13"><rect x="411" y="42.5" width="60" height="15"/></clipPath><clipPath id="svgimg3ct14"><rect x="411" y="42.5" width="60" height="15"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><rect x="28.5" y="28.5" width="583" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg3ov1)"><rect x="30" y="31" width="173.1" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#svgimg3sh2)"/><rect x="30" y="30" width="173.1" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="30.5" y="30.5" width="172" height="39" rx="19.5" fill="none" stroke="rgba(72,72,74,0.8)" stroke-width="1"/><g clip-path="url(#svgimg3cp3)"><g color="rgb(138, 203, 255)"><clipPath id="svgimg3svgic4"><rect x="67.4" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic4)"><g transform="translate(67.39 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp5)"><g clip-path="url(#svgimg3ct6)"><text x="91.39" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">README.md</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="203.5" y="30.5" width="146" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp7)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic8"><rect x="240.5" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic8)"><g transform="translate(240.531 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp9)"><g clip-path="url(#svgimg3ct10)"><text x="264.53" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">index.ts</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="350.5" y="30.5" width="157" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp11)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic12"><rect x="387" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic12)"><g transform="translate(387.031 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp13)"><g clip-path="url(#svgimg3ct14)"><text x="411.03" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">styles.css</text></g></g></g></g></g></g></g></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 150" width="672" height="150"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="96"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="96" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="150" rx="0" fill="rgb(28,28,30)"/><text x="16" y="28" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Selected tab among peers</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="96"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="584" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="29" y="29" width="582" height="42" rx="21"/></clipPath><filter id="svgimg3sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg3cp3"><rect x="67" y="42" width="16.4" height="16"/></clipPath><clipPath id="svgimg3cp5"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3ct6"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3cp7"><rect x="240.5" y="42" width="16.5" height="16"/></clipPath><clipPath id="svgimg3cp9"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3ct10"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3cp11"><rect x="387" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp13"><rect x="411" y="42.5" width="60" height="15"/></clipPath><clipPath id="svgimg3ct14"><rect x="411" y="42.5" width="60" height="15"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><rect x="28.5" y="28.5" width="583" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments"><g/></g><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::after" data-domotion-pseudo-owner="source-fragments"><g/></g><g clip-path="url(#svgimg3ov1)"><rect x="30" y="31" width="173.1" height="40" rx="20" fill="rgba(0,0,0,0.5)" filter="url(#svgimg3sh2)"/><rect x="30" y="30" width="173.1" height="40" rx="20" fill="rgb(28,28,30)"/><rect x="30.5" y="30.5" width="172" height="39" rx="19.5" fill="none" stroke="rgba(72,72,74,0.8)" stroke-width="1"/><g clip-path="url(#svgimg3cp3)"><g color="rgb(138, 203, 255)"><clipPath id="svgimg3svgic4"><rect x="67.4" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic4)"><g transform="translate(67.39 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(138, 203, 255)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp5)"><g clip-path="url(#svgimg3ct6)"><text x="91.39" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(138,203,255)">README.md</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="203.5" y="30.5" width="146" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp7)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic8"><rect x="240.5" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic8)"><g transform="translate(240.531 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp9)"><g clip-path="url(#svgimg3ct10)"><text x="264.53" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">index.ts</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="350.5" y="30.5" width="157" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp11)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg3svgic12"><rect x="387" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic12)"><g transform="translate(387.031 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(174, 174, 178)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp13)"><g clip-path="url(#svgimg3ct14)"><text x="411.03" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(174,174,178)">styles.css</text></g></g></g></g></g></g></g></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 150" width="672" height="150"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="96"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="96" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="150" rx="0" fill="rgb(255,255,255)"/><text x="16" y="28" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Selected tab among peers</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="96"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="584" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="29" y="29" width="582" height="42" rx="21"/></clipPath><filter id="svgimg3sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg3cp3"><rect x="67" y="42" width="16.4" height="16"/></clipPath><clipPath id="svgimg3cp5"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3ct6"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3cp7"><rect x="240.5" y="42" width="16.5" height="16"/></clipPath><clipPath id="svgimg3cp9"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3ct10"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3cp11"><rect x="387" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp13"><rect x="411" y="42.5" width="60" height="15"/></clipPath><clipPath id="svgimg3ct14"><rect x="411" y="42.5" width="60" height="15"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><rect x="28.5" y="28.5" width="583" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g clip-path="url(#svgimg3ov1)"><rect x="30" y="31" width="173.1" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#svgimg3sh2)"/><rect x="30" y="30" width="173.1" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="30.5" y="30.5" width="172" height="39" rx="19.5" fill="none" stroke="rgba(209,209,214,0.8)" stroke-width="1"/><g clip-path="url(#svgimg3cp3)"><g color="rgb(12, 98, 243)"><clipPath id="svgimg3svgic4"><rect x="67.4" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic4)"><g transform="translate(67.39 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp5)"><g clip-path="url(#svgimg3ct6)"><text x="91.39" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">README.md</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="203.5" y="30.5" width="146" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp7)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic8"><rect x="240.5" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic8)"><g transform="translate(240.531 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp9)"><g clip-path="url(#svgimg3ct10)"><text x="264.53" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">index.ts</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="350.5" y="30.5" width="157" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp11)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic12"><rect x="387" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic12)"><g transform="translate(387.031 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp13)"><g clip-path="url(#svgimg3ct14)"><text x="411.03" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">styles.css</text></g></g></g></g></g></g></g></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 672 150" width="672" height="150"><defs><clipPath id="cp0"><rect x="16" y="38" width="640" height="96"/></clipPath><clipPath id="ct1"><rect x="16" y="16" width="640" height="22"/></clipPath><clipPath id="irc2"><rect x="16" y="38" width="640" height="96" rx="0"/></clipPath></defs><rect x="0" y="0" width="672" height="150" rx="0" fill="rgb(255,255,255)"/><text x="16" y="28" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Selected tab among peers</text><g clip-path="url(#cp0)"><g clip-path="url(#irc2)"><clipPath id="svgimg3vclip"><rect x="16" y="38" width="640" height="96"/></clipPath><g clip-path="url(#svgimg3vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg3cp0"><rect x="28" y="28" width="584" height="44"/></clipPath><clipPath id="svgimg3ov1"><rect x="29" y="29" width="582" height="42" rx="21"/></clipPath><filter id="svgimg3sh2" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="1.5"/></filter><clipPath id="svgimg3cp3"><rect x="67" y="42" width="16.4" height="16"/></clipPath><clipPath id="svgimg3cp5"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3ct6"><rect x="91.4" y="42.5" width="74.4" height="15"/></clipPath><clipPath id="svgimg3cp7"><rect x="240.5" y="42" width="16.5" height="16"/></clipPath><clipPath id="svgimg3cp9"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3ct10"><rect x="264.5" y="42.5" width="47.7" height="15"/></clipPath><clipPath id="svgimg3cp11"><rect x="387" y="42" width="16" height="16"/></clipPath><clipPath id="svgimg3cp13"><rect x="411" y="42.5" width="60" height="15"/></clipPath><clipPath id="svgimg3ct14"><rect x="411" y="42.5" width="60" height="15"/></clipPath></defs><g clip-path="url(#svgimg3cp0)"><rect x="28.5" y="28.5" width="583" height="43" rx="21.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/></g><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments"><g/></g><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::after" data-domotion-pseudo-owner="source-fragments"><g/></g><g clip-path="url(#svgimg3ov1)"><rect x="30" y="31" width="173.1" height="40" rx="20" fill="rgba(0,0,0,0.14)" filter="url(#svgimg3sh2)"/><rect x="30" y="30" width="173.1" height="40" rx="20" fill="rgb(255,255,255)"/><rect x="30.5" y="30.5" width="172" height="39" rx="19.5" fill="none" stroke="rgba(209,209,214,0.8)" stroke-width="1"/><g clip-path="url(#svgimg3cp3)"><g color="rgb(12, 98, 243)"><clipPath id="svgimg3svgic4"><rect x="67.4" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic4)"><g transform="translate(67.39 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(12, 98, 243)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp5)"><g clip-path="url(#svgimg3ct6)"><text x="91.39" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(12,98,243)">README.md</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="203.5" y="30.5" width="146" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp7)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic8"><rect x="240.5" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic8)"><g transform="translate(240.531 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp9)"><g clip-path="url(#svgimg3ct10)"><text x="264.53" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">index.ts</text></g></g></g><g clip-path="url(#svgimg3ov1)"><rect x="350.5" y="30.5" width="157" height="39" rx="19.5" fill="none" stroke="rgba(0,0,0,0)" stroke-width="1"/><g clip-path="url(#svgimg3cp11)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg3svgic12"><rect x="387" y="42" width="16" height="16"/></clipPath><g clip-path="url(#svgimg3svgic12)"><g transform="translate(387.031 42)scale(.66667)"><path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2 2 0 0 1 1.7.7l3.6 3.6A2 2 0 0 1 20 8v12a2 2 0 0 1-2 2Z" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M14 2v5a1 1 0 0 0 1 1h5" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M10 9H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 13H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/><path d="M16 17H8" style="marker:none;vector-effect:none;color-interpolation:srgb" fill="none" stroke="rgb(110, 110, 115)" stroke-width="2px" stroke-dasharray="none" stroke-linecap="round" stroke-linejoin="round" stroke-opacity="1" fill-opacity="1" opacity="1"/></g></g></g></g><g clip-path="url(#svgimg3cp13)"><g clip-path="url(#svgimg3ct14)"><text x="411.03" y="54.5" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="650" fill="rgb(110,110,115)">styles.css</text></g></g></g></g></g></g></g></svg>
|
|
@@ -22,13 +22,17 @@ Unrelated updates must not close controls, move focus, reset a draft, replace a
|
|
|
22
22
|
|
|
23
23
|
### Hierarchy precedes decoration
|
|
24
24
|
|
|
25
|
-
Establish one reading order and one dominant action per decision point. Group first with alignment, spacing, typography, and shared surfaces. A border, fill, badge, or nested card must communicate a real distinction.
|
|
25
|
+
Establish one reading order and one dominant action per decision point. Group first with alignment, spacing, typography, and shared surfaces. A border, fill, badge, or nested card must communicate a real distinction. A divider is chrome too: a line between a pane's own header and its list, or under a toolbar whose content already spaces itself, marks nothing and is dropped (`dividerSides=""`), never padded around. Put a control near where its effect appears — a collapsed drawer's restore beside the drawer, not in a distant top toolbar.
|
|
26
26
|
|
|
27
27
|
### Reach for the primitive, not for CSS
|
|
28
28
|
|
|
29
29
|
The package is designed to look right _unstyled_. A screen built from the
|
|
30
30
|
primitives, their props, and the semantic tokens should already read well, so
|
|
31
|
-
applications do not carry a component-customization stylesheet.
|
|
31
|
+
applications do not carry a component-customization stylesheet. Prefer a Kerf
|
|
32
|
+
UI component over a Web Awesome component over a raw HTML tag, using each for
|
|
33
|
+
what it is good at; a `Discouraged` Web Awesome element is reached only through
|
|
34
|
+
the Kerf component that wraps it (`PopupMenu`, `Select`), never rendered
|
|
35
|
+
directly. Before adding any `padding`, `margin`, `width`,
|
|
32
36
|
`height`, `border`, `background`, wrapper card, or decoration, check whether the
|
|
33
37
|
component, the pane, or the content-item already owns it — it almost always does,
|
|
34
38
|
and adding more usually **double-insets** or fights the component (the most common
|
|
@@ -40,13 +44,36 @@ configure those children through props and documented tokens instead. Never size
|
|
|
40
44
|
space, or re-skin a primitive by hand, and never build a heading, toolbar, card,
|
|
41
45
|
or pane geometry that a primitive provides.
|
|
42
46
|
|
|
47
|
+
### Components own their styles; configure, never override
|
|
48
|
+
|
|
49
|
+
Every component styles only itself. How it looks and sits is configuration —
|
|
50
|
+
typed props and data attributes such as size, density, inset, presentation,
|
|
51
|
+
tone, `dividerSides`, `ToolbarConfig`, and `PaneConfig` — never a stylesheet
|
|
52
|
+
somewhere else reaching into it. When a component must adapt inside another
|
|
53
|
+
(a `PopupMenu` inside a compact `ToolbarControlGroup`, an `AppTab` in a
|
|
54
|
+
segmented `TabBar`), the **child** styles itself in that context, in its own
|
|
55
|
+
stylesheet; the parent keys only its own elements on a child's state
|
|
56
|
+
(`:has(> .kui-select[open])`) and names kerf children by class, not by `wa-*`
|
|
57
|
+
tag. Values a parent provides to its children are custom properties named after
|
|
58
|
+
the parent. A component never writes another component's private variables and
|
|
59
|
+
never puts a hook class on a child's root to restyle it.
|
|
60
|
+
|
|
61
|
+
The same holds for applications and component packages built on Kerf UI: expose
|
|
62
|
+
configuration on your own components, configure kerf components through their
|
|
63
|
+
props, and treat a missing prop as a component gap to report, not a reason to
|
|
64
|
+
override. `npm run check:css-ownership` enforces this inside the package.
|
|
65
|
+
|
|
43
66
|
### Panes share one child-owned geometry
|
|
44
67
|
|
|
45
68
|
Sidebars, main areas, inspectors, and dialogs use the same unpadded pane. Their
|
|
46
69
|
children own margin, border, background, padding, and radius, so a transparent
|
|
47
70
|
surface occupies exactly the same geometry as a visible one. Major content
|
|
48
71
|
groups use 24px vertical separation; the inside of an item and the gap between
|
|
49
|
-
toolbar groups use 8px. Rows and actions keep 44px targets.
|
|
72
|
+
toolbar groups use 8px. Rows and actions keep 44px targets. Align text to text
|
|
73
|
+
and icons to icons: a title, a row label, and bare prose share one text column,
|
|
74
|
+
and a border is decoration, never the alignment anchor — a bordered surface
|
|
75
|
+
extends to the pane gutter rather than being indented so its border lines up
|
|
76
|
+
with a heading's text.
|
|
50
77
|
|
|
51
78
|
Use the package composition so the geometry has one owner:
|
|
52
79
|
|
|
@@ -10,15 +10,15 @@
|
|
|
10
10
|
"schemaVersion": 1
|
|
11
11
|
},
|
|
12
12
|
"composition": {
|
|
13
|
-
"path": "../../ai/component-
|
|
14
|
-
"schemaVersion":
|
|
13
|
+
"path": "../../ai/component-composition.json",
|
|
14
|
+
"schemaVersion": 1
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"package": "@acme/ui",
|
|
19
19
|
"composition": {
|
|
20
|
-
"path": "./component-
|
|
21
|
-
"schemaVersion":
|
|
20
|
+
"path": "./component-composition-extension.json",
|
|
21
|
+
"schemaVersion": 1
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
],
|
package/docs/examples/{component-catalog-extension-v2.json → component-composition-extension.json}
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "../../ai/component-
|
|
3
|
-
"schemaVersion":
|
|
2
|
+
"$schema": "../../ai/component-composition-extension.schema.json",
|
|
3
|
+
"schemaVersion": 1,
|
|
4
4
|
"package": "@acme/ui",
|
|
5
5
|
"compatibility": {
|
|
6
|
-
"
|
|
6
|
+
"componentCatalog": "./component-catalog-extension.json",
|
|
7
7
|
"identity": "package:id"
|
|
8
8
|
},
|
|
9
9
|
"entries": [
|
package/docs/layout.md
CHANGED
|
@@ -42,6 +42,72 @@ each enabled side uses `--kui-pane-separator-width` (1px) and
|
|
|
42
42
|
`--kui-pane-separator-color` (`--kui-color-neutral-border-normal`). Logical sides keep pane
|
|
43
43
|
boundaries correct in both left-to-right and right-to-left layouts.
|
|
44
44
|
|
|
45
|
+
### Scroll dividers
|
|
46
|
+
|
|
47
|
+
Toolbars draw no divider by default. The line between pinned chrome and the
|
|
48
|
+
content that scrolls beside it is scroll state, not decoration: it shows only
|
|
49
|
+
while content is scrolled away from that edge, the way platform navigation bars
|
|
50
|
+
gain a hairline once content moves beneath them.
|
|
51
|
+
|
|
52
|
+
- A near edge (top, left) hides at the scroll start.
|
|
53
|
+
- A far edge (bottom, right) hides at the scroll end, and whenever the content
|
|
54
|
+
fits and nothing scrolls.
|
|
55
|
+
|
|
56
|
+
Call `wireScrollDividers` from `@kerfjs/ui/wire-scroll-dividers` once at the
|
|
57
|
+
application root and keep its disposer:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { wireScrollDividers } from "@kerfjs/ui/wire-scroll-dividers";
|
|
61
|
+
|
|
62
|
+
const stop = wireScrollDividers(appRoot);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
It covers, by structure, every `Pane` below the root (the header's bottom line
|
|
66
|
+
and the footer's top line, whatever the chrome holds — a `Toolbar`, a
|
|
67
|
+
`mainHeader` list, a `TabBar`) and every `TabBar` strip (a line on each side
|
|
68
|
+
whose tabs are scrolled out of view). That includes the panes a `Workbench`,
|
|
69
|
+
`CollapsiblePanel`, or `Catalog` renders; `wireCatalog` installs it for its
|
|
70
|
+
own root. It also covers every `NavStack` (the top chrome's bottom line and the
|
|
71
|
+
bottom toolbar's top line, around the active view) and every `TabScaffold`
|
|
72
|
+
(the bar's top line, over the active scene). The layout keys on whichever
|
|
73
|
+
element actually scrolls there: the view or scene itself, or, through a sole
|
|
74
|
+
child with no chrome of its own on that edge, a `Pane`'s content or a nested
|
|
75
|
+
`NavStack`'s active view. A sole `Pane` fills its view or scene, so its content
|
|
76
|
+
scrolls under its pinned header; with a header it draws the line under that
|
|
77
|
+
header itself, so the stack's chrome never doubles it. It follows re-renders: panes that appear later are paired, and an
|
|
78
|
+
attribute a morph drops returns before paint.
|
|
79
|
+
|
|
80
|
+
The wiring only reports state; every component draws its own line. It writes
|
|
81
|
+
`data-scroll-overflow` (the edges with content hidden beyond them, in canonical
|
|
82
|
+
`t`/`r`/`b`/`l` order) on each scroller and `data-scroll-divider` (the sides to
|
|
83
|
+
draw) on each piece of chrome, and the Pane, NavStack, TabScaffold, TabBar,
|
|
84
|
+
Toolbar, and List stylesheets draw from those. The line is an inset shadow or a pseudo-element
|
|
85
|
+
inside the component, so no state ever moves the chrome, the content, or a tab.
|
|
86
|
+
Never write a border onto a component to show one.
|
|
87
|
+
|
|
88
|
+
Configure a pane with `chromeDividers`: `scroll` (the default) follows the
|
|
89
|
+
scroll state and draws nothing until the wiring runs; `always` keeps both lines;
|
|
90
|
+
`none` drops them. Layouts forward it through `PaneConfig`
|
|
91
|
+
(`mainPane.chromeDividers`, a panel's `pane.chromeDividers`). A `NavStack` and a
|
|
92
|
+
`TabScaffold` take the same `chromeDividers` for their own chrome (the stack's
|
|
93
|
+
top chrome and bottom toolbar, the scaffold's bar), and a `SplitView` forwards
|
|
94
|
+
it to its compact stack through `compactStack`.
|
|
95
|
+
|
|
96
|
+
For an app-owned arrangement outside a `Pane`, name the scroller and its chrome
|
|
97
|
+
by `id` in `targets`; a `Toolbar` or `List` named as chrome draws the divider
|
|
98
|
+
on its side facing the scroller:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
wireScrollDividers(appRoot, {
|
|
102
|
+
targets: [{ scroller: "results", top: "results-toolbar", bottom: "status" }],
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
A CSS-only version is not used: scroll-driven animations are not available in
|
|
107
|
+
Firefox, scroll-state container queries only in Chromium, and neither lets
|
|
108
|
+
the pinned chrome — a sibling of the scroller — read the scroller's state on
|
|
109
|
+
its own. One wiring keeps the behavior identical in every engine.
|
|
110
|
+
|
|
45
111
|
A pane is safe-area aware. Its background and separators paint through a
|
|
46
112
|
device's unsafe areas while its header, content, and footer pad for each side
|
|
47
113
|
the pane still reaches; the content's block insets are scroll padding, so its
|
|
@@ -107,9 +173,22 @@ The rendered classes — `.kui-content-item`, `.kui-content-item--framed`, and
|
|
|
107
173
|
`.kui-content-item--pill` — stay public for the rare element that must carry the
|
|
108
174
|
geometry itself (for example a `<ul>` list or a `Text` paragraph in an
|
|
109
175
|
application-owned adapter). Prefer `ContentItem` everywhere else so the framing
|
|
110
|
-
choice is typed.
|
|
111
|
-
|
|
112
|
-
|
|
176
|
+
choice is typed. A plain `<div class="kui-content-item">` is exactly what
|
|
177
|
+
`ContentItem` renders, so the catalog records that element
|
|
178
|
+
(`rootElement: "div"`): `eslint-plugin-kerfjs`'s `ui-public-boundaries` reports
|
|
179
|
+
it in application code as `KUI-L103` ("render `ContentItem`"), and
|
|
180
|
+
`npm run check:guidance` derives the same boundary from the catalog to reject it
|
|
181
|
+
in the package's examples, browser fixtures, and UX catalog.
|
|
182
|
+
|
|
183
|
+
These classes, the layout utilities (`.kui-content`, `.kui-scroll-owner`,
|
|
184
|
+
`.kui-control-cluster`, `.kui-inline-metadata`), and `.kui-app-root` are the
|
|
185
|
+
catalog's `boundaries.placeableClasses`: the only public classes an application
|
|
186
|
+
writes onto its own elements. Every other public class is a component's
|
|
187
|
+
rendered anatomy — render `Pane` rather than writing `.kui-pane` /
|
|
188
|
+
`.kui-pane__content` onto an `<aside>` — and `eslint-plugin-kerfjs`'s
|
|
189
|
+
`ui-public-boundaries` reports it on an application-owned element as
|
|
190
|
+
`KUI-L103`. Selecting those classes in CSS to place your own content in a
|
|
191
|
+
component's context stays allowed (see `KUI-L019`).
|
|
113
192
|
|
|
114
193
|
## Public roles and tokens
|
|
115
194
|
|
package/docs/nav-stack.md
CHANGED
|
@@ -5,14 +5,19 @@ and out over one another while the top chrome settles. A **single-pane layout is
|
|
|
5
5
|
a `NavStack` with one entry**. It is one of the opt-in app layouts (see
|
|
6
6
|
[`../../docs/23-app-layouts.md`](../../docs/23-app-layouts.md)).
|
|
7
7
|
|
|
8
|
-
Import the component and its
|
|
8
|
+
Import the component and its wiring helper:
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { NavStack, type NavStackView } from "@kerfjs/ui/nav-stack";
|
|
12
12
|
import { wireNavStack } from "@kerfjs/ui/wire-nav-stack";
|
|
13
|
-
import "@kerfjs/ui/nav-stack.css";
|
|
14
13
|
```
|
|
15
14
|
|
|
15
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
16
|
+
webpack do by default), the import above also
|
|
17
|
+
loads NavStack's stylesheet and those of the components it renders internally
|
|
18
|
+
(`Toolbar`, `ToolbarControlGroup`, `ToolbarText`, `LucideIcon`). Without that condition, import the manual stylesheets instead:
|
|
19
|
+
`@kerfjs/ui/nav-stack.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
|
+
|
|
16
21
|
## State lives in the app
|
|
17
22
|
|
|
18
23
|
Like every `@kerfjs/ui` component, `NavStack` is declarative: the app owns the
|
|
@@ -87,7 +92,7 @@ Configure the toolbar with `toolbarConfig` instead of styling it:
|
|
|
87
92
|
`label` (the toolbar's accessible name), `titleSize` (the title's
|
|
88
93
|
`ToolbarText` size, default `large`), and `headingLevel` (expose the title as
|
|
89
94
|
a heading; default a plain span). The defaults keep the stack's own chrome:
|
|
90
|
-
no divider,
|
|
95
|
+
no divider, the standard Toolbar height (a 44px control band with 8px above and below), and the top and side safe-area edges
|
|
91
96
|
claimed.
|
|
92
97
|
- `backIcon` replaces the default chevron-left icon. `backText` adds visible
|
|
93
98
|
text beside it (for example, the previous view's title); visible text names
|
|
@@ -109,6 +114,31 @@ When a remembered control was removed during the controlled rerender, the same
|
|
|
109
114
|
fallback order applies. Disposing the helper stops future transitions and
|
|
110
115
|
cleans up any temporary fallback `tabindex` it added.
|
|
111
116
|
|
|
117
|
+
## Scroll dividers
|
|
118
|
+
|
|
119
|
+
The stack draws no permanent line between its chrome and the view. With
|
|
120
|
+
`wireScrollDividers(appRoot)` installed (see
|
|
121
|
+
[Layout › Scroll dividers](layout.md#scroll-dividers)), the top chrome shows a
|
|
122
|
+
line along its bottom edge only while the active view's content is scrolled
|
|
123
|
+
beneath it, and the bottom toolbar a line along its top edge only while more
|
|
124
|
+
content lies below it — neither when the content fits. The line follows the
|
|
125
|
+
active view across a push or pop. The chrome's line is overlaid on its bottom
|
|
126
|
+
edge and the bottom toolbar's is its always-present 1px top border, colored
|
|
127
|
+
only while shown, so neither ever moves the chrome or the content. When the view's only child is a `Pane`,
|
|
128
|
+
the line keys on whichever actually scrolls — the view, or the Pane's content —
|
|
129
|
+
and a Pane header or footer draws its own boundary instead. An explicit
|
|
130
|
+
`toolbarConfig.dividerSides` still draws a permanent Toolbar edge.
|
|
131
|
+
|
|
132
|
+
`chromeDividers` configures both lines, with the same values as a `Pane`'s:
|
|
133
|
+
`scroll` (the default) follows the scroll state above and draws nothing until
|
|
134
|
+
the wiring runs; `always` keeps both lines, with or without the wiring; `none`
|
|
135
|
+
drops them even when the wiring reports scroll state. It does not change the
|
|
136
|
+
top Toolbar's own `dividerSides`.
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
<NavStack id="settings" label="Settings" views={views.value} chromeDividers="always" />
|
|
140
|
+
```
|
|
141
|
+
|
|
112
142
|
## Safe areas
|
|
113
143
|
|
|
114
144
|
The stack paints through a device's unsafe areas. Its chrome pads for the top
|
package/docs/split-view.md
CHANGED
|
@@ -8,11 +8,16 @@ on compact ones. One of the opt-in app layouts (see
|
|
|
8
8
|
```ts
|
|
9
9
|
import { SplitView } from "@kerfjs/ui/split-view";
|
|
10
10
|
import { deviceClass } from "@kerfjs/ui/device-class";
|
|
11
|
-
|
|
12
|
-
// plus nav-stack.css when the compact path is reachable, and
|
|
13
|
-
// wireResizableRegions / wireNavStack for the interactive behavior.
|
|
11
|
+
// plus wireResizableRegions / wireNavStack for the interactive behavior.
|
|
14
12
|
```
|
|
15
13
|
|
|
14
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
15
|
+
webpack do by default), the import above also
|
|
16
|
+
loads SplitView's stylesheet and those of the components it renders internally
|
|
17
|
+
(its compact `NavStack`, `ResizableRegion`, and the toolbar
|
|
18
|
+
components). Without that condition, import the manual stylesheets instead:
|
|
19
|
+
`@kerfjs/ui/split-view.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
|
+
|
|
16
21
|
## Safe areas
|
|
17
22
|
|
|
18
23
|
The list pane grows by the inline-start unsafe inset and pads for the edges it
|
|
@@ -75,8 +80,8 @@ resizable={{
|
|
|
75
80
|
```
|
|
76
81
|
|
|
77
82
|
`compactStack` configures the compact `NavStack`: `toolbarConfig`, `backIcon`,
|
|
78
|
-
`backText`, `hideToolbar`,
|
|
79
|
-
stack, and `list` / `detail` give each view its own top-toolbar groups
|
|
83
|
+
`backText`, `hideToolbar`, the persistent `bottomToolbar`, and `chromeDividers`
|
|
84
|
+
forward to the stack, and `list` / `detail` give each view its own top-toolbar groups
|
|
80
85
|
(`leading`, `center`, trailing `toolbar`) and `bottomToolbar`:
|
|
81
86
|
|
|
82
87
|
```tsx
|
package/docs/tab-scaffold.md
CHANGED
|
@@ -9,9 +9,14 @@ It is distinct from `TabBar` (document-oriented, reorderable strips).
|
|
|
9
9
|
```ts
|
|
10
10
|
import { TabScaffold } from "@kerfjs/ui/tab-scaffold";
|
|
11
11
|
import { wireTabScaffold } from "@kerfjs/ui/wire-tab-scaffold";
|
|
12
|
-
import "@kerfjs/ui/tab-scaffold.css";
|
|
13
12
|
```
|
|
14
13
|
|
|
14
|
+
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
15
|
+
webpack do by default), the import above also
|
|
16
|
+
loads TabScaffold's stylesheet and those of the components it renders internally
|
|
17
|
+
(the tab `Badge`). Without that condition, import the manual stylesheets instead:
|
|
18
|
+
`@kerfjs/ui/tab-scaffold.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
19
|
+
|
|
15
20
|
## Controlled selection
|
|
16
21
|
|
|
17
22
|
The app owns the active tab (a signal); `TabScaffold` renders every tab's scene
|
|
@@ -54,6 +59,23 @@ truncate horizontally with an ellipsis when a destination name exceeds its
|
|
|
54
59
|
share of the bar. On larger device classes, promote the tab set to a
|
|
55
60
|
`Workbench` rail or a persistent sidebar instead of a bottom bar.
|
|
56
61
|
|
|
62
|
+
## Scroll divider
|
|
63
|
+
|
|
64
|
+
The bar has no permanent top border. With `wireScrollDividers(appRoot)`
|
|
65
|
+
installed (see [Layout › Scroll dividers](layout.md#scroll-dividers)), it shows
|
|
66
|
+
a line along its top edge only while the active scene's content continues below
|
|
67
|
+
it — not at the scroll end and not when the content fits. The line keys on
|
|
68
|
+
whatever actually scrolls in the scene: the scene itself or, through a sole
|
|
69
|
+
child, a `NavStack`'s active view or a `Pane`'s content. A `NavStack` with its
|
|
70
|
+
own bottom toolbar sits between them, so that toolbar's line applies instead.
|
|
71
|
+
The line is the bar's always-present 1px top border, colored only while shown,
|
|
72
|
+
so it never moves the bar or a tab.
|
|
73
|
+
|
|
74
|
+
`chromeDividers` configures it, with the same values as a `Pane`'s: `scroll`
|
|
75
|
+
(the default) follows the scroll state and draws nothing until the wiring runs;
|
|
76
|
+
`always` keeps the line, with or without the wiring; `none` drops it even when
|
|
77
|
+
the wiring reports content below.
|
|
78
|
+
|
|
57
79
|
## Tab badges
|
|
58
80
|
|
|
59
81
|
Give a tab a `badge` (a count or short string such as `3`, `"99+"`, or
|
package/docs/type-contracts.md
CHANGED
|
@@ -113,9 +113,10 @@ move errors into casts without making the integration safer.
|
|
|
113
113
|
`{ keyboard: { removeAdjacentToken: false } }` when only caret navigation is
|
|
114
114
|
wanted.
|
|
115
115
|
- Add `wrap: true` anywhere `ToolbarText.maxLines` is used.
|
|
116
|
-
- Replace `Toolbar({ divider: false })` with `dividerSides: ''
|
|
117
|
-
|
|
118
|
-
`
|
|
116
|
+
- Replace `Toolbar({ divider: false })` with `dividerSides: ''`, which is now
|
|
117
|
+
the default (a toolbar pinned over scrolling content gets its divider from
|
|
118
|
+
`wireScrollDividers` through its `Pane`); canonical combinations such as `b`,
|
|
119
|
+
`tr`, and `trbl` select permanent physical edges.
|
|
119
120
|
- Replace raw `List.gap` strings with a direct spacing shorthand (`"xs"`,
|
|
120
121
|
`"m"`) or a complete value from `@kerfjs/ui/css-values`. Replace
|
|
121
122
|
`gap="0.25rem"` with `gap={rem(0.25)}` and wrap sums with `calc(plus(...))`.
|
package/docs/ui-analyzer.md
CHANGED
|
@@ -61,7 +61,7 @@ policy, or analysis inputs to the containing application.
|
|
|
61
61
|
| `KUI-L002` | error | A stylesheet references an unknown or private `--kui-*` token. |
|
|
62
62
|
| `KUI-L003` | error | One element combines public classes that claim the same geometry. |
|
|
63
63
|
| `KUI-L004` | review | Nested literal classes both add a content inset. |
|
|
64
|
-
| `KUI-L005` |
|
|
64
|
+
| `KUI-L005` | — | Retired; folded into `KUI-L019` (see below). |
|
|
65
65
|
| `KUI-L006` | review | Literal spacing falls outside Kerf's approved scale. |
|
|
66
66
|
| `KUI-L007` | error | A declared scroll owner is nested inside another scroll owner. |
|
|
67
67
|
| `KUI-L008` | review | A dynamic class expression cannot be classified soundly. |
|
|
@@ -75,6 +75,10 @@ policy, or analysis inputs to the containing application.
|
|
|
75
75
|
| `KUI-L016` | error | A removed declaration-list escape hatch is used. |
|
|
76
76
|
| `KUI-L017` | review | A valid but exceptional off-scale shorthand needs justification. |
|
|
77
77
|
| `KUI-L018` | review | A loud fill override lacks a governing `on-loud`, or the literal pair is below 4.5:1. |
|
|
78
|
+
| `KUI-L019` | error | A rule's subject is another package's component (class, `data-component`, or tag). |
|
|
79
|
+
| `KUI-L020` | error | CSS reads or writes another component's private `--_*` variable. |
|
|
80
|
+
| `KUI-L021` | error | CSS overrides a component token that a typed prop sets. |
|
|
81
|
+
| `KUI-L022` | error | A class placed on a component's root is styled by the application (a hook class). |
|
|
78
82
|
|
|
79
83
|
Errors are provable contract violations and make the command exit 1. Review
|
|
80
84
|
findings are deliberately heuristic and do not fail by default; pass
|
|
@@ -92,9 +96,10 @@ CSS extension points. A component catalog may additionally list shadow-part
|
|
|
92
96
|
names in `boundaries.publicParts`; all other `::part()` targets are private.
|
|
93
97
|
Part names are scoped to that entry's `boundaries.rootClass`, so an extension
|
|
94
98
|
point on one component does not authorize the same-named part on another.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
Selectors for application-owned content remain allowed, including in a
|
|
100
|
+
component's context (`.kui-pane > .my-content`): a public class is an
|
|
101
|
+
extension point for naming a context, not for restyling the component itself,
|
|
102
|
+
which `KUI-L019` reports.
|
|
98
103
|
|
|
99
104
|
Catalog entries may also publish `cssValueProps`. Each path names its grammar,
|
|
100
105
|
finite shorthands, canonical and exceptional scale steps, accepted typed
|
|
@@ -103,6 +108,94 @@ uses that same metadata for direct component calls and JSX, including nested
|
|
|
103
108
|
paths such as `choices[].color`; consumer catalogs receive identical checks.
|
|
104
109
|
Dynamic values remain a type-system responsibility rather than being guessed.
|
|
105
110
|
|
|
111
|
+
## Component ownership (`KUI-L019`–`KUI-L022`)
|
|
112
|
+
|
|
113
|
+
Components own their styles and are configured, never overridden. These
|
|
114
|
+
diagnostics apply the package's own `check:css-ownership` rules to
|
|
115
|
+
applications and component packages; the selector parsing is the same module
|
|
116
|
+
(`analyzer/selectors.mjs`), so the package rule and the consumer rule agree on
|
|
117
|
+
which element a selector styles.
|
|
118
|
+
|
|
119
|
+
- **`KUI-L019` — a rule restyles a cataloged component.** The rule's subject
|
|
120
|
+
(the rightmost compound of each selector, ignoring `:has()` and `:not()`
|
|
121
|
+
arguments) names a public class of a cataloged component (`.kui-toolbar`,
|
|
122
|
+
`.kui-list-item__label`, `.acme-meter`), its `[data-component="…"]` root, or
|
|
123
|
+
a Web Awesome tag the package themes (`wa-button`, `wa-select`), and the rule
|
|
124
|
+
sets at least one ordinary property. A `::part()` subject is left to
|
|
125
|
+
`KUI-L011`; a rule that only sets custom properties is configuration, judged
|
|
126
|
+
by the token rules. Forcing a component's dimensions is one such restyle
|
|
127
|
+
and reports here once: `.kui-pane { width: 300px }`.
|
|
128
|
+
- **`KUI-L020` — another component's private variable.** CSS reads or writes a
|
|
129
|
+
`--_<root>-*` variable of a cataloged component (`--_kui-list-gap`), or any
|
|
130
|
+
`--_kui-*` variable.
|
|
131
|
+
- **`KUI-L021` — a token a typed prop sets.** CSS assigns `--<root>-<prop>`
|
|
132
|
+
where the component has that typed prop (`--kui-list-gap` is `List gap`,
|
|
133
|
+
`--kui-floating-toolbar-inset` is `FloatingToolbar inset`). The message
|
|
134
|
+
quotes the prop's cataloged example.
|
|
135
|
+
- **`KUI-L022` — a hook class on a component's root.** A literal class on an
|
|
136
|
+
imported component's JSX (`<Toolbar className="header" />`) is the subject
|
|
137
|
+
of a rule in a stylesheet that file imports, so the application restyles the
|
|
138
|
+
component through it. The evidence names the stylesheet, line, and selector.
|
|
139
|
+
|
|
140
|
+
Every message names the configuration to use (the component's typed props,
|
|
141
|
+
public tokens, and variants from its catalog entry) and ends with the same
|
|
142
|
+
route for a real need that has none: report the component gap to the owning
|
|
143
|
+
package (open a feature request) instead of overriding it.
|
|
144
|
+
|
|
145
|
+
What stays allowed mirrors the package rule, where a child styles itself in a
|
|
146
|
+
parent's context:
|
|
147
|
+
|
|
148
|
+
```css
|
|
149
|
+
/* Your own element in a component's context. */
|
|
150
|
+
.kui-toolbar > .my-widget {
|
|
151
|
+
margin-inline-start: auto;
|
|
152
|
+
}
|
|
153
|
+
/* Keying your own element on a component's state. */
|
|
154
|
+
.shell:has(.kui-select[open]) .my-status {
|
|
155
|
+
opacity: 0.5;
|
|
156
|
+
}
|
|
157
|
+
/* Configuring a component through a public token with no typed prop. */
|
|
158
|
+
.kui-list {
|
|
159
|
+
--kui-list-divider-color: var(--kui-color-neutral-border-quiet);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* KUI-L019, KUI-L020, KUI-L021. */
|
|
163
|
+
.kui-toolbar {
|
|
164
|
+
padding: 0;
|
|
165
|
+
}
|
|
166
|
+
.app {
|
|
167
|
+
--_kui-list-gap: 2px;
|
|
168
|
+
--kui-list-gap: 4px;
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Ownership is decided per package: a stylesheet belongs to the package whose
|
|
173
|
+
`package.json` is nearest it, and only other packages' catalog entries are
|
|
174
|
+
foreign to it. A component package built on Kerf UI therefore styles its own
|
|
175
|
+
cataloged components (including `.kui-toolbar > .acme-meter` from its own
|
|
176
|
+
stylesheet) without findings, while an application that restyles
|
|
177
|
+
`.acme-meter` is reported against `@acme/widgets`. All four ids are
|
|
178
|
+
ownership-boundary diagnostics, so `--adoption` reports them as review
|
|
179
|
+
findings. `eslint-plugin-kerfjs`'s `ui-component-ownership` rule reports
|
|
180
|
+
`KUI-L020` and `KUI-L021` in JavaScript and TypeScript (style strings, style
|
|
181
|
+
objects, and `style.setProperty()`), where this analyzer reads only CSS.
|
|
182
|
+
|
|
183
|
+
### Retired: `KUI-L005` (forced component dimension)
|
|
184
|
+
|
|
185
|
+
`KUI-L005` used to report, as a review finding, any `width`/`height`/`min-*`/
|
|
186
|
+
`max-*` declaration in a rule that mentioned a public component class
|
|
187
|
+
anywhere in its selector. `KUI-L019` now reports every restyle whose subject is
|
|
188
|
+
a cataloged component — dimensions included — so the subject case was
|
|
189
|
+
double-reported (an error and a review finding for one declaration). Its only
|
|
190
|
+
other shape, a public class as an ancestor
|
|
191
|
+
(`.kui-pane .app-sidebar { width: 240px }`), sizes the application's own
|
|
192
|
+
element in the component's context, which the ownership rules explicitly
|
|
193
|
+
allow. With no unique true positive left,
|
|
194
|
+
the rule was retired rather than narrowed. The analyzer no longer emits it;
|
|
195
|
+
the id stays in `ai/application-ui-diagnostic-ids-v1.json` (listed under
|
|
196
|
+
`retired`) so a profile exception that already names it still loads. Remove
|
|
197
|
+
such exceptions at your convenience.
|
|
198
|
+
|
|
106
199
|
## Loud fill / on-loud pairing (`KUI-L018`)
|
|
107
200
|
|
|
108
201
|
The shipped Web Awesome theme pairs every `--wa-color-{tone}-fill-loud` with a
|
|
@@ -207,6 +300,7 @@ validator.
|
|
|
207
300
|
|
|
208
301
|
Review findings remain visible until explicitly suppressed. Avoid suppressing
|
|
209
302
|
`KUI-L001`, `KUI-L002`, `KUI-L003`, `KUI-L007`, `KUI-L009`, `KUI-L010`,
|
|
210
|
-
`KUI-L011`, `KUI-L012`, `KUI-L013`, `KUI-L014`, `KUI-L015`,
|
|
303
|
+
`KUI-L011`, `KUI-L012`, `KUI-L013`, `KUI-L014`, `KUI-L015`, `KUI-L016`,
|
|
304
|
+
`KUI-L019`, `KUI-L020`, `KUI-L021`, or `KUI-L022`:
|
|
211
305
|
those indicate a
|
|
212
306
|
definite boundary or parsing failure rather than an aesthetic judgment.
|
package/docs/ui-doctor.md
CHANGED
|
@@ -30,6 +30,16 @@ that lacks a governing `--wa-color-{tone}-on-loud` (in the same or an ancestor
|
|
|
30
30
|
scope, in any stylesheet the same entry loads), or whose literal pair measures
|
|
31
31
|
below 4.5:1 (see [the analyzer rule](./ui-analyzer.md#loud-fill--on-loud-pairing-kui-l018)).
|
|
32
32
|
|
|
33
|
+
Component ownership is part of the same loop. The analyzer stage reports
|
|
34
|
+
application or third-party CSS that restyles another package's component
|
|
35
|
+
(`KUI-L019`), touches its private `--_*` variables (`KUI-L020`), overrides a
|
|
36
|
+
token a typed prop sets (`KUI-L021`), or styles it through a hook class on its
|
|
37
|
+
root (`KUI-L022`); the ESLint stage's `ui-component-ownership` rule reports
|
|
38
|
+
`KUI-L020` / `KUI-L021` in script. Each finding's `action` points at the
|
|
39
|
+
component's configuration, and its message routes a need with no prop to a
|
|
40
|
+
component-gap report instead of an override (see
|
|
41
|
+
[the analyzer rule](./ui-analyzer.md#component-ownership-kui-l019kui-l022)).
|
|
42
|
+
|
|
33
43
|
The browser evaluator is different: it runs the application and is disabled by default. It only runs when configuration supplies `browser.url` or the command receives `--browser-url`. Start and authorize the target application separately.
|
|
34
44
|
|
|
35
45
|
An unavailable or failed stage does not prevent independent stages from reporting. Its final exit is still a configuration failure, so a partial run cannot appear clean.
|