@kerfjs/ui 5.0.0-beta.61 → 5.0.0-beta.63
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 +4 -0
- package/ai/component-catalog-extension.schema.json +13 -0
- package/ai/component-catalog.json +20 -7
- package/ai/component-composition.json +17 -3
- package/ai/components/list-item.md +1 -1
- package/ai/components/pane.md +3 -2
- package/ai/components/select.md +1 -0
- package/ai/components/toolbar-text.md +2 -1
- package/ai/components/workbench.md +3 -2
- package/ai/public-api-signatures-v1.md +162 -48
- package/ai/skill.md +11 -5
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/analyzer/index.mjs +3 -2
- package/catalog-projection-cli.mjs +96 -0
- package/catalog-projection.d.mts +55 -0
- package/catalog-projection.mjs +62 -0
- package/dist/browser/catalog.js +1 -1
- package/dist/browser/collapsible-panel.js +2 -0
- package/dist/browser/nav-stack.js +1 -0
- package/dist/browser/split-view.js +1 -0
- package/dist/browser/toolbar-control-group.js +1 -0
- package/dist/browser/workbench.js +1 -0
- package/dist/catalog-resources.d.ts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +11 -10
- package/dist/catalog.js.map +1 -1
- package/dist/chip.d.ts +9 -3
- package/dist/chip.js +1 -1
- package/dist/{chunk-EZVNC4J6.js → chunk-3BYFWTP3.js} +7 -3
- package/dist/chunk-3BYFWTP3.js.map +1 -0
- package/dist/{chunk-5Q3N6EV7.js → chunk-5IJ6UGNZ.js} +3 -3
- package/dist/{chunk-5Q3N6EV7.js.map → chunk-5IJ6UGNZ.js.map} +1 -1
- package/dist/chunk-7AKGPBCC.js +76 -0
- package/dist/chunk-7AKGPBCC.js.map +1 -0
- package/dist/{chunk-KROD7KZK.js → chunk-AUVG54KC.js} +2 -2
- package/dist/{chunk-KROD7KZK.js.map → chunk-AUVG54KC.js.map} +1 -1
- package/dist/{chunk-AUKT3KMG.js → chunk-CQHN45XR.js} +17 -2
- package/dist/chunk-CQHN45XR.js.map +1 -0
- package/dist/{chunk-SWVW56CV.js → chunk-EN4LDR5Y.js} +2 -2
- package/dist/{chunk-SWVW56CV.js.map → chunk-EN4LDR5Y.js.map} +1 -1
- package/dist/{chunk-TEYARRAK.js → chunk-F7OCOBTG.js} +5 -2
- package/dist/chunk-F7OCOBTG.js.map +1 -0
- package/dist/{chunk-5PESG2VP.js → chunk-HXCMWANP.js} +6 -5
- package/dist/chunk-HXCMWANP.js.map +1 -0
- package/dist/{chunk-NYL63PSD.js → chunk-IA4D5XNT.js} +61 -10
- package/dist/chunk-IA4D5XNT.js.map +1 -0
- package/dist/{chunk-F4QMLOXJ.js → chunk-IAOAZUOO.js} +2 -2
- package/dist/{chunk-F4QMLOXJ.js.map → chunk-IAOAZUOO.js.map} +1 -1
- package/dist/{chunk-Y74NWGQW.js → chunk-KFYANKJI.js} +66 -22
- package/dist/chunk-KFYANKJI.js.map +1 -0
- package/dist/chunk-MOSIE4Z2.js +51 -0
- package/dist/chunk-MOSIE4Z2.js.map +1 -0
- package/dist/{chunk-7JUBXOIV.js → chunk-NXWE5S57.js} +25 -6
- package/dist/chunk-NXWE5S57.js.map +1 -0
- package/dist/{chunk-NNMLEDMD.js → chunk-OBAFAH5B.js} +36 -8
- package/dist/chunk-OBAFAH5B.js.map +1 -0
- package/dist/{chunk-A3CKOW2R.js → chunk-R75GGNWY.js} +123 -20
- package/dist/chunk-R75GGNWY.js.map +1 -0
- package/dist/chunk-RGS4WX2M.js +44 -0
- package/dist/chunk-RGS4WX2M.js.map +1 -0
- package/dist/{chunk-N3GKMPDW.js → chunk-RKTTF3L4.js} +3 -1
- package/dist/chunk-RKTTF3L4.js.map +1 -0
- package/dist/{chunk-RRB26JRJ.js → chunk-RTJNJTG3.js} +2 -2
- package/dist/{chunk-RRB26JRJ.js.map → chunk-RTJNJTG3.js.map} +1 -1
- package/dist/{chunk-EAC4CDY7.js → chunk-SMZGAPCU.js} +15 -2
- package/dist/chunk-SMZGAPCU.js.map +1 -0
- package/dist/{chunk-C4OYOKWX.js → chunk-UA6JW52D.js} +36 -2
- package/dist/chunk-UA6JW52D.js.map +1 -0
- package/dist/{chunk-3SXMEK3B.js → chunk-V3DX3K65.js} +1 -1
- package/dist/chunk-V3DX3K65.js.map +1 -0
- package/dist/{chunk-6ZXOQEAN.js → chunk-WF75U3V4.js} +7 -1
- package/dist/chunk-WF75U3V4.js.map +1 -0
- package/dist/{chunk-VCBTX62E.js → chunk-ZRWXFDDS.js} +2 -2
- package/dist/chunk-ZRWXFDDS.js.map +1 -0
- package/dist/collapsible-panel.d.ts +18 -7
- package/dist/collapsible-panel.js +19 -3
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/content-item.d.ts +36 -5
- package/dist/content-item.js +1 -1
- package/dist/disclosure-arrow.js +2 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +22 -22
- package/dist/list-action-row.js +1 -1
- package/dist/list-header.js +1 -1
- package/dist/list-item.js +1 -1
- package/dist/lucide-icon.d.ts +5 -2
- package/dist/lucide-icon.js +2 -1
- package/dist/nav-stack.d.ts +3 -1
- package/dist/nav-stack.js +2 -1
- package/dist/pane.d.ts +10 -4
- package/dist/pane.js +1 -1
- package/dist/{panel-toolbar-DqwtBxQL.d.ts → panel-toolbar-DDKh4uKd.d.ts} +11 -2
- package/dist/popup-menu-register.js +38 -1
- package/dist/popup-menu-register.js.map +1 -1
- package/dist/popup-menu.d.ts +2 -2
- package/dist/popup-menu.js +1 -1
- package/dist/select.d.ts +2 -0
- package/dist/select.js +1 -1
- package/dist/split-view.d.ts +1 -1
- package/dist/split-view.js +2 -1
- package/dist/split-view.js.map +1 -1
- package/dist/styles/app-tab.css +84 -0
- package/dist/styles/chip.css +14 -0
- package/dist/styles/content-item.css +36 -0
- package/dist/styles/list-action-row.css +4 -3
- package/dist/styles/list-header.css +4 -3
- package/dist/styles/list-item.css +21 -11
- package/dist/styles/lucide-icon.css +5 -0
- package/dist/styles/nav-stack.css +13 -0
- package/dist/styles/pane.css +36 -2
- package/dist/styles/popup-menu.css +15 -10
- package/dist/styles/resizable-region.css +9 -0
- package/dist/styles/select.css +26 -0
- package/dist/styles/split-view.css +6 -0
- package/dist/styles/sunken-panel.css +7 -0
- package/dist/styles/tab-bar.css +3 -0
- package/dist/styles/tab-scaffold.css +13 -0
- package/dist/styles/text.css +29 -0
- package/dist/styles/token-search-field.css +29 -6
- package/dist/styles/toolbar-control-group.css +35 -0
- package/dist/styles/toolbar-text.css +15 -6
- package/dist/styles/toolbar.css +7 -0
- package/dist/styles/workbench.css +260 -90
- package/dist/sunken-panel.d.ts +6 -1
- package/dist/sunken-panel.js +1 -1
- package/dist/tab-bar.d.ts +6 -2
- package/dist/tab-bar.js +1 -1
- package/dist/tab-scaffold.d.ts +3 -0
- package/dist/tab-scaffold.js +1 -0
- package/dist/tab-scaffold.js.map +1 -1
- package/dist/text.d.ts +14 -3
- package/dist/text.js +1 -1
- package/dist/token-search-field.js +2 -1
- package/dist/toolbar-control-group.d.ts +5 -1
- package/dist/toolbar-control-group.js +2 -1
- package/dist/toolbar-text.d.ts +1 -1
- package/dist/toolbar-text.js +1 -1
- package/dist/toolbar.d.ts +7 -4
- package/dist/toolbar.js +1 -1
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-content-items.d.ts +9 -0
- package/dist/wire-content-items.js +62 -0
- package/dist/wire-content-items.js.map +1 -0
- package/dist/wire-tab-bars.js +1 -1
- package/dist/wire-token-search-fields.js +2 -1
- package/dist/wire-workbench.d.ts +7 -0
- package/dist/wire-workbench.js +1 -1
- package/dist/workbench.d.ts +24 -8
- package/dist/workbench.js +2 -1
- package/docs/accessibility.md +21 -5
- package/docs/catalog.md +36 -0
- package/docs/collapsible-panel.md +12 -4
- package/docs/component-contract.md +10 -4
- package/docs/component-selection.md +65 -15
- 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-dark.svg +1 -1
- package/docs/design/templates/toolbar.svg +1 -1
- package/docs/examples/component-catalog-extension.json +6 -0
- package/docs/layout.md +61 -3
- package/docs/nav-stack.md +5 -0
- package/docs/split-view.md +5 -0
- package/docs/sunken-panel.md +30 -1
- package/docs/tab-scaffold.md +5 -0
- package/docs/ui-analyzer.md +4 -0
- package/docs/webawesome-theme.md +36 -6
- package/docs/workbench.md +60 -14
- package/llms.txt +12 -4
- package/package.json +16 -2
- package/scripts/component-catalog-extension-validation.mjs +28 -0
- package/dist/chunk-3SXMEK3B.js.map +0 -1
- package/dist/chunk-4R777DUZ.js +0 -34
- package/dist/chunk-4R777DUZ.js.map +0 -1
- package/dist/chunk-5PESG2VP.js.map +0 -1
- package/dist/chunk-6ZXOQEAN.js.map +0 -1
- package/dist/chunk-7JUBXOIV.js.map +0 -1
- package/dist/chunk-A3CKOW2R.js.map +0 -1
- package/dist/chunk-AUKT3KMG.js.map +0 -1
- package/dist/chunk-C4OYOKWX.js.map +0 -1
- package/dist/chunk-EAC4CDY7.js.map +0 -1
- package/dist/chunk-EZVNC4J6.js.map +0 -1
- package/dist/chunk-MA73TA6D.js +0 -42
- package/dist/chunk-MA73TA6D.js.map +0 -1
- package/dist/chunk-MERWRTBG.js +0 -45
- package/dist/chunk-MERWRTBG.js.map +0 -1
- package/dist/chunk-N3GKMPDW.js.map +0 -1
- package/dist/chunk-NNMLEDMD.js.map +0 -1
- package/dist/chunk-NYL63PSD.js.map +0 -1
- package/dist/chunk-TEYARRAK.js.map +0 -1
- package/dist/chunk-VCBTX62E.js.map +0 -1
- package/dist/chunk-Y74NWGQW.js.map +0 -1
package/ai/skill.md
CHANGED
|
@@ -70,8 +70,12 @@ Before choosing or aligning components, look for a consumer-owned catalog that
|
|
|
70
70
|
conforms to `./component-catalog-extension.schema.json`. Treat its entries as a
|
|
71
71
|
second, package-qualified input beside `./component-catalog.json`: search both,
|
|
72
72
|
preserve their source identity, and use the shared `geometry` vocabulary across
|
|
73
|
-
their composition boundary.
|
|
74
|
-
|
|
73
|
+
their composition boundary. An extension entry's optional `uses` ids resolve
|
|
74
|
+
against both catalogs; its `source` and `demoSource` are repository-relative
|
|
75
|
+
files for consumer catalog links. When a consuming project has reusable visual
|
|
76
|
+
components, derive demo rows with `@kerfjs/ui/catalog-projection` or
|
|
77
|
+
`kerf-catalog-demo --write`, then guard drift with `--check`; see
|
|
78
|
+
`../docs/catalog.md`. Prefer its generated `component-composition.json`. A package
|
|
75
79
|
scaffolded by `create-kerf-component` owns the decisions in
|
|
76
80
|
`kerf.components.json`; run `npm run catalog:check` before using its output. If
|
|
77
81
|
no generated extension exists, start from the checked examples and require the
|
|
@@ -195,7 +199,7 @@ Hard rules:
|
|
|
195
199
|
4. Wire `data-action` hooks from one stable root with `delegate()` or `delegateActions()` and retain disposers.
|
|
196
200
|
5. Configure components through their typed props; components own their own styles (see "Components own their styles; configure, never override" above). Use the opinionated `--kui-color-*` semantic ramps for theming, not to reshape a component. Use `pop` only for attractive non-status emphasis such as featured, novel, or celebratory content; never substitute it for info, success, warning, or danger. Set a theme token only at the narrowest useful scope, and never where an equivalent prop exists. `publicClasses` exist for diagnostics, tooling, tests, and package-owned composition, not application styling. Never target a Kerf or Web Awesome component from application CSS; add missing configuration to the owner.
|
|
197
201
|
6. `Select` is pure until the app explicitly imports `@kerfjs/ui/select/register`; once registered, an icon-only `Select` (and, via `@kerfjs/ui/popup-menu/register`, an icon-only `PopupMenu`) shows an `aria-hidden` help tag repeating its accessible name (and a Select's current choice) on hover and keyboard focus, hidden while its popup is open — never add a `title` or your own tooltip to these triggers. The same installer tags an icon-only `<button>` or link in a `ToolbarControlGroup` named by `aria-label` (no visible text, no `title`); a toolbar with such buttons but no registered Select or PopupMenu imports `@kerfjs/ui/help-tags/register` once. Name those buttons with `aria-label`, not `title`: a `title` keeps the browser tooltip and skips the tag. Do not import Web Awesome's full registration bundle. When an app writes direct `wa-*` JSX, add `import type {} from '@kerfjs/ui/webawesome'` for the catalog-supported intrinsic-element declarations, import the CSS-only `@kerfjs/ui/webawesome.css` theme once, and keep importing individual Web Awesome component modules so their JavaScript remains tree-shakeable. The type boundary emits no code and registers nothing. Pass icon-bearing `choices` and `renderSelected` content normally: `Select` preserves its slotted option icons across Kerf rerenders and keys selected content by the controlled value, so app wrappers must not add competing morph-control attributes. Give it a visible `label` or an `ariaLabel` for a visually hidden name; the nonempty visible label takes precedence and the package names the actual shadow combobox, including `renderSelected`, without adding label geometry. Use `hint` for persistent supporting text below the control and `placeholderText` only for the empty value inside the closed control; loading placeholders retain the hint. For any number of choices set `multiple` with an array `value`: the popup stays open while choices toggle and closes on an outside press or Escape, the closed control summarizes the chosen labels, and `change` reports the value array; do not add app code to keep it open or to render tags. For a toolbar filter menu, add `selectedPresentation="icon-only"` plus a fixed `triggerIcon` (such as a funnel `LucideIcon`): the trigger shows that icon, a count badge while any choice is chosen, and ends its accessible name with the chosen labels ("Filter by label: Bug, Docs"); do not render your own count badge or rewrite the name. When testing name or description, target the element with the `combobox` role rather than the `wa-select` wrapper. Web Awesome's hint attribute and explicit hint slot both describe that shadow combobox across supported engines; do not add an `aria-description` mirror or application shadow-DOM patch.
|
|
198
|
-
7. Decorative icons are hidden; controls are named; focus is visible; state never relies on color alone; reduced motion and increased contrast remain usable. `DisclosureArrow` defaults to an 18px root-scaled visual; size it with its typed `size` prop (`size={remify(24)}`); it never becomes the interaction or accessible-name owner. Put it in an owning native control with a stable accessible name and controlled `aria-expanded`. `ListHeader` toggle mode supplies it when `actionIcon` is omitted, but the app must reveal matching content; a custom icon replaces it. Author replacement icon content facing right before its configured direction transform is applied. Direction changes take the shortest rotation path, with counterclockwise chosen for a 180-degree closed-to-open tie. Kerf `Select` separately keeps its intrinsic Web Awesome expand glyph at `--kui-disclosure-icon-scale: .5
|
|
202
|
+
7. Decorative icons are hidden; controls are named; focus is visible; state never relies on color alone; reduced motion and increased contrast remain usable. `DisclosureArrow` defaults to an 18px root-scaled visual; size it with its typed `size` prop (`size={remify(24)}`); it never becomes the interaction or accessible-name owner. Put it in an owning native control with a stable accessible name and controlled `aria-expanded`. `ListHeader` toggle mode supplies it when `actionIcon` is omitted, but the app must reveal matching content; a custom icon replaces it. Author replacement icon content facing right before its configured direction transform is applied. Direction changes take the shortest rotation path, with counterclockwise chosen for a 180-degree closed-to-open tie. Kerf `Select` separately keeps its intrinsic Web Awesome expand glyph at `--kui-disclosure-icon-scale: .5`; an icon-only toolbar Select may set `caret={false}` for a round trigger while preserving its help tag and keyboard listbox, and a custom `renderSelected` icon stays centered.
|
|
199
203
|
8. `ResizableRegion` uses `wireResizableRegions()` for Arrow, Shift+Arrow, Home/End, and pointer behavior. The app owns size persistence. `handleIcon` replaces decorative dormant glyph content only. Set `responsiveFillAt="narrow"` or `"compact"` when a responsive composition exposes the pane as its only inline track; the component fills that track and hides its dormant separator. For compact overlays, set `presentation="overlay"` and the overlay maximum variables. A lone child (normally a `Pane`) fills the region and owns scrolling; several children stack at natural height. Do not add descendant width/height overrides.
|
|
200
204
|
9. Use controlled `SegmentedControl` for a small exclusive choice set. Select `appearance="toolbar"` when nesting it inside `ToolbarControlGroup`; use rounded or pill shapes for standalone contexts. The package derives inset hover/selection radii from the owning outer shape through `--kui-layout-highlight-inset`; do not restyle an inner highlight to an independent radius. Handle its action, update `value`, keep meaningful choice labels, and preserve every enabled native button in sequential Tab order.
|
|
201
205
|
10. Compose `AppTab` inside controlled `TabBar`; call `wireTabBars()` once and retain its disposer. It owns same-bar drag mechanics, including proximity-based horizontal edge autoscroll, while the app applies `onReorder` and owns order, selection, panels, close policy, routing, and persistence. For a tab-local action followed by a separately pinned workspace action, set `trailingPlacement="adjacent"`, put the local action in `trailing`, and the workspace action in `end`; TabBar owns the shrinking/scrolling tabs and fixed action geometry, so do not add descendant flex overrides. Arrow/Home/End select on move by default and restore focus by bar/tab identity when controlled activation replaces the strip; pass `activation: 'manual'` (or `TabBar activation="manual"` per strip) so arrow keys move focus only and the user selects with Enter/Space/click — use it when selecting a tab is a heavy action. Use runtime-filtered `rootAttributes` for domain metadata and keep an optional `closeIcon` decorative and noninteractive.
|
|
@@ -207,8 +211,10 @@ Hard rules:
|
|
|
207
211
|
15. Build sidebars, main areas, inspectors, and dialogs by rendering `Pane` (`@kerfjs/ui/pane`): an unpadded `.kui-pane` root, an optional `header`, one scrolling `.kui-pane__content`, and an optional `footer`; pick landmarks with `element` / `contentElement`. Never write a component's anatomy classes (`kui-pane`, `kui-toolbar`, `kui-list-item`, …) onto your own element to recreate it — render the component (`KUI-L103`). Only the catalog's `placeableClasses` (the `.kui-content` / `.kui-scroll-owner` / `.kui-control-cluster` / `.kui-inline-metadata` layout utilities, `.kui-app-root`, and `.kui-content-item` geometry on a non-div carrier) belong on elements you write. Use `Row` instead of a hand-written flex-row wrapper, `List` instead of a hand-written flex-column wrapper, and `Grid` instead of repeated equal-track CSS when children need a fixed positive count of evenly distributed columns. `Row` defaults to left/full with an `xs` gap and no wrapping; Grid defaults to an `xs` gap and keeps each track at `minmax(0, 1fr)`; List retains full/top and zero-gap defaults. The app owns Grid's responsive column-count changes. When a Row, List, or Grid is the layout root of a definite-height parent (an app root or a fixed-height frame), pass `fill` so it takes that full height, and put route/test/recipe `data-*` markers in its `rootAttributes`; never wrap a layout in a frame `Pane` just for height or a root attribute, because its content slot becomes a scroll owner that never scrolls. Inside a flex layout use `flex`, not `fill`. Use `List` when rows or sections also need flex growth, one vertical scroll owner, or physical-edge dividers. `dividerSides`, `textInsets`, and `controlInsets` use canonical physical `t`/`r`/`b`/`l` order; text geometry wins where text and control selections overlap. `ListInsetText` and `ListInsetControl` inset all four sides by default and accept the same `sides` grammar for selective edges. A dialog body is generally a `List`: set `DialogSurface bodyInset="none"` when its list children own geometry, and wrap bare dialog prose in `ListInsetText` so it aligns with bordered siblings without a second inset. Add `.kui-content` for 24px major vertical separation and render each ordinary surface-like child as `ContentItem` (`@kerfjs/ui/content-item`) for a child-owned 8px inline margin, 1px border, 8px padding, and 12px radius. Choose `frame="framed"` (neutral border in the always-reserved 1px, same geometry) only for a real distinction and `shape="pill"` for 22px; do not hand-write `<div class="kui-content-item">` or its modifier classes. There is no filled variant: a lowered filled surface is `SunkenPanel`. Do not pad pane shells, duplicate item geometry in wrappers, or create nested scroll owners. Align text to text and icons to icons across a pane — a title, a row label, and bare prose share the same text column (`ListInsetText` puts bare text on it); a border is decoration and never the alignment anchor, so a bordered surface extends to the pane gutter instead of being indented to line its border up with a heading's text.
|
|
208
212
|
15a. Use `Text` from `@kerfjs/ui/text` for ordinary headings, paragraphs, and inline secondary text outside toolbar title zones. Omit `variant` for the default `p`, pass `h1`–`h6` according to the document outline, or use `variant="span"` inside a row, label, or table cell; ordinary native attributes pass through. Express supporting, error, compact, or code text with the independent finite `tone="quiet|danger"`, `size="compact"`, and `font="monospace"` props instead of global utility classes or appearance-only heading choices. Block Text variants own a transparent 1px border and the standard item padding; `span` owns no box geometry. Keep toolbar identity/title content on `ToolbarText` and list-aligned bare prose on `ListInsetText`. `ToolbarText` below `xlarge` is intentionally quiet identity text with no tone option; a normal-color subsection title is `Text` with an `h2`–`h6` variant (or `ListHeader` for a list or menu section), never a recolored `ToolbarText`.
|
|
209
213
|
16. Keep a visible collapsible pane's collapse control in its own toolbar. When hidden, move its restore control into the adjacent main toolbar on the corresponding logical edge: leading for an inline-start sidebar and trailing for an inline-end inspector. Collapse the pane completely; do not preserve an empty icon-only rail.
|
|
210
|
-
16a. Dividers between pinned chrome and scrolling content are
|
|
214
|
+
16a. Dividers between pinned chrome and scrolling content are component chrome: a `Toolbar` draws none by default (`dividerSides` is for a permanent edge only). Call `wireScrollDividers(appRoot)` from `@kerfjs/ui/wire-scroll-dividers` once and retain its disposer; a plain `Pane` with `chromeDividers="scroll"` draws the line under its header only while content is scrolled beneath it and over its footer only while more content lies below (never when the content fits), every `NavStack`'s top chrome and bottom toolbar and every `TabScaffold` bar do the same around the active view or scene (keyed on whatever actually scrolls there, including a sole `Pane`'s content), and every `TabBar` marks each side of its strip with tabs scrolled out of view. Configure a pane with `chromeDividers` (`scroll` by default for plain panes, `always` by default for sunken panes, or explicit `scroll`, `always`, `none`, also via `PaneConfig`); `always` draws both lines even when content fits. A `NavStack` or `TabScaffold` has its own `chromeDividers` (same values: `always` draws the chrome lines without the wiring, `none` never, even when wired; a `SplitView` forwards it through `compactStack`); a `toolbarConfig.dividerSides` edge stays the Toolbar's own. Name app-owned chrome by id in `targets`. The wiring writes only `data-scroll-overflow` / `data-scroll-divider` state; never write a border onto a component to show a divider.
|
|
211
215
|
17. The only direct children of a `Toolbar` zone (`leading`/`center`/`trailing`) are `ToolbarText` (identity/title text) and `ToolbarControlGroup`; never drop bare buttons, inputs, links, or arbitrary markup straight into a zone. Put identity/title text directly in the zone as `ToolbarText`; wrap interactive controls and icon tiles in `ToolbarControlGroup`. `SegmentedControl`, `Select`, a collapsible `TokenSearchField`, and Web Awesome controls all live inside a group. Configure zone behavior with `Toolbar.centerAlign` and its `responsive` / `responsiveAt` policy instead of selecting toolbar zone classes. No policy clips an action: trailing (and stacked center) zones wrap whole groups onto another row, and the center zone never compresses below its content (a leading title too long for the row truncates with an ellipsis instead), so never hide or shrink a toolbar control to make it fit; use `responsive="wrap"` for a heading whose title must stay whole, and move genuinely lower-priority commands into an app-owned "More" popup menu. For an ordinary icon/action control inside a group, use a plain `<button>` (the group styles `> button` fully) — that is the default; reach for `wa-button` only when you need a Web Awesome feature. A popup menu in a toolbar is a `PopupMenu` (`@kerfjs/ui/popup-menu`, registered once via `@kerfjs/ui/popup-menu/register`) in a `single` group with `nestedDropdown` and a `menuInset`: give it typed `items` (commands with `action`s, `heading`s, `divider`s) and a trigger `icon` plus visible `text` or an accessible `label`; never hand-write `wa-dropdown` / `wa-dropdown-item` markup for a menu. Let the group size that trigger from its icon, localized text, and caret; do not force a width on the menu or button. Nothing wraps inside a group: an icon sits beside its label on one row and a group's controls never break onto a second line — the group sizes to its content, so if it does not fit, the toolbar's `responsive` policy relocates whole groups. A `ToolbarText` is one line ending in an ellipsis by default; opt into `wrap` (capped by `maxLines`) or `ellipsis={false}` deliberately. Inside a group, a `Select` or `PopupMenu` trigger drops its focus ring while its popup is open (the open popup and its current row show where focus is) and the ring returns when the popup closes; a ring follows the control's shape (a pill for an icon-and-caret trigger, a circle for a compact icon button) — set `focusRingOwner="group"` on a Select whose group paints the composed ring, and never add CSS to show, hide, or reshape a ring. For a compact mixed group, keep the standard item padding and raised selected chrome; the selected item paints over the outer border without an internal separator. For an avatar control, set `content="avatar"` and `avatarImage` on the group instead of inserting an `img`: a lone control paints the contained image on the outer group and a multi-button group paints it only on the pressed selection highlight. Compose panel/dialog/page headings with a direct extra-large `ToolbarText`, optional grouped icon, grouped trailing controls, and app-owned supporting copy below. A non-interactive heading icon is an icon tile: put the `LucideIcon` directly in its `ToolbarControlGroup` (it takes an icon button's 40px slot and centers), never inside a `<button>` that does nothing. A group remains 44px outside (`calc(2px + remify(42px))`) when its border/background are transparent; use 8px between groups and inside items. Each zone item sits in the toolbar's top 44px control band, centered by its own size; a taller item (a wrapped title, a second trailing row) starts at the band's top and grows down without moving the others, so a wrapped `ToolbarText` keeps trailing controls beside its first line — do not add alignment CSS for this. Split dormant and interactive regions: `ListHeader` fills the available inline width by default; set `width="content"` to shrink-wrap while retaining its normal geometry, or `inline` when it belongs in surrounding text without outer margin, border, or padding. It keeps its label and mutually exclusive semantic count or non-count `badge` together, with an independent logical-end action unless disclosure mode makes the title cluster the button. Its action visual defaults to 18px through `--kui-list-header-action-icon-size` inside a fitted 36px hover square whose transparent hit layer keeps the pointer target at least 44px (44px wide by the 36px row in `density="compact"`); never shrink the target to match the visual, and never force the button to 44px. Pass every non-negative safe-integer section quantity through `count` with a localized full spoken `countLabel`; never concatenate it into `label` or put a number in `badge`. `ListItem.trailing` is dormant; use `ListActionRow` when primary and trailing actions need sibling native buttons. Its `label`, `icon`, and `trailingActionIcon` slots are also dormant and cannot contain controls. Let panes relocate at narrow widths instead of shrinking targets. Dividers are chrome and earn their place: a `Toolbar` draws none by default, and the line between pinned chrome and scrolling content comes from scroll state (rule 16a), so never add a border, a permanent `dividerSides`, or a margin to fake or adjust one.
|
|
216
|
+
For a toolbar heading that must remain at the 20px `--kui-font-l` step, use `ToolbarText size="xlarge-fixed"`; `xlarge` retains the responsive page-title clamp. Pass `headingLevel` when it is a section landmark.
|
|
217
|
+
|
|
212
218
|
18. When a recurring concept has no matching export or production recipe, keep its semantics in a thin application adapter while reusing the public layout vocabulary. The composer recipe uses one visible form surface, toolbar title/supporting-copy ids, shared 8px field/action gutters, 24px major rhythm, and a conditional StateBanner as its only nested semantic surface; do not turn every section into a card or double-inset intrinsically bordered controls. For multi-line banner copy use `copyLayout="stacked"`; use `actionPlacement="below"` for an action on its own trailing row. The application-local `../docs/examples/command-palette-adapter.tsx` is reference source for one such missing concept, not an `@kerfjs/ui` runtime export or catalog recipe. The application owns its registration, ranking, history, permissions, availability, shortcut policy, focus policy, dispatch, and copy. If a missing concept recurs across products, open an upstream component or recipe request.
|
|
213
219
|
|
|
214
220
|
For compact `Select` triggers, set `triggerWidth` to `fit-content`, `max-content`,
|
|
@@ -228,7 +234,7 @@ Use `--kui-resizable-region-background` for a region surface and `contentOverflo
|
|
|
228
234
|
|
|
229
235
|
Use `ListItem density="spacious"` for larger option rows, `multiline` plus `multilineIconAlign="center"` when its icon should center on wrapped copy, `divider` for row separators, and `state="drag-target"` for the drop target treatment. Public `--kui-list-item-*` tokens adjust row, icon, label, and trailing geometry and color; ListHeader height, title padding, and border tokens adjust section density.
|
|
230
236
|
|
|
231
|
-
For a filled command list, scope `--kui-list-item-background`, `--kui-list-item-border`, `--kui-list-item-hover-border`, and `--kui-list-item-selected-border` at the List or ListItem boundary. Keep global neutral and brand border colors semantic.
|
|
237
|
+
For a filled command list, scope `--kui-list-item-background`, `--kui-list-item-color`, `--kui-list-item-border`, `--kui-list-item-hover-background`, `--kui-list-item-hover-border`, `--kui-list-item-selected-background`, `--kui-list-item-selected-color`, and `--kui-list-item-selected-border` at the List or ListItem boundary. Keep global neutral and brand border colors semantic.
|
|
232
238
|
|
|
233
239
|
Use `Toolbar responsive="trailing-priority"` when an expanded trailing search needs a full second row below its heading at `responsiveAt`. Configure a leading minimum width, trailing gap and justification, or zone inline padding with the public `--kui-toolbar-*` tokens rather than selectors into toolbar zones.
|
|
234
240
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web Awesome JSX signatures for the UI authoring corpus
|
|
2
2
|
|
|
3
|
-
Generated from the emitted `@kerfjs/ui@5.0.0-beta.
|
|
3
|
+
Generated from the emitted `@kerfjs/ui@5.0.0-beta.63` declaration boundary. Import `@kerfjs/ui/webawesome` for type effects when authoring direct `wa-*` JSX. The module emits no runtime behavior and does not register custom elements.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
6
|
import { KerfCustomElement } from 'kerfjs/jsx-runtime';
|
package/analyzer/index.mjs
CHANGED
|
@@ -540,6 +540,7 @@ async function inspectCss(
|
|
|
540
540
|
siblingOnLoud,
|
|
541
541
|
);
|
|
542
542
|
root.walkRules((rule) => {
|
|
543
|
+
const subjects = subjectClasses(rule.selector);
|
|
543
544
|
inspectComponentOwnership(
|
|
544
545
|
file,
|
|
545
546
|
rule,
|
|
@@ -549,7 +550,7 @@ async function inspectCss(
|
|
|
549
550
|
isForeign,
|
|
550
551
|
);
|
|
551
552
|
if (!inKeyframes(rule) && restylingDeclarations(rule).length > 0)
|
|
552
|
-
for (const className of
|
|
553
|
+
for (const className of subjects) {
|
|
553
554
|
const record = cssFacts.get(className) ?? {
|
|
554
555
|
scroll: false,
|
|
555
556
|
inset: false,
|
|
@@ -678,7 +679,7 @@ async function inspectCss(
|
|
|
678
679
|
},
|
|
679
680
|
),
|
|
680
681
|
);
|
|
681
|
-
for (const className of
|
|
682
|
+
for (const className of subjects) {
|
|
682
683
|
const record = cssFacts.get(className) ?? {
|
|
683
684
|
scroll: false,
|
|
684
685
|
inset: false,
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
import { projectConsumerCatalog } from './catalog-projection.mjs';
|
|
8
|
+
|
|
9
|
+
const usage =
|
|
10
|
+
'Usage: kerf-catalog-demo --extension <catalog.json> --out <catalog.generated.ts> --repo-base <blob-url> [--kerf-catalog <catalog.json>] [--category <name>] [--source-template <path>] [--demo-template <path>] [--documentation-template <path>] [--design-template <path>] (--write|--check)';
|
|
11
|
+
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
const options = {};
|
|
14
|
+
const values = new Map([
|
|
15
|
+
['--extension', 'extension'],
|
|
16
|
+
['--out', 'out'],
|
|
17
|
+
['--repo-base', 'repoBase'],
|
|
18
|
+
['--kerf-catalog', 'kerfCatalog'],
|
|
19
|
+
['--category', 'category'],
|
|
20
|
+
['--source-template', 'sourceTemplate'],
|
|
21
|
+
['--demo-template', 'demoTemplate'],
|
|
22
|
+
['--documentation-template', 'documentationTemplate'],
|
|
23
|
+
['--design-template', 'designTemplate'],
|
|
24
|
+
]);
|
|
25
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
26
|
+
const arg = argv[index];
|
|
27
|
+
if (arg === '--check' || arg === '--write') {
|
|
28
|
+
if (options.mode)
|
|
29
|
+
throw new Error('Choose exactly one of --write or --check');
|
|
30
|
+
options.mode = arg;
|
|
31
|
+
} else if (values.has(arg)) {
|
|
32
|
+
const value = argv[++index];
|
|
33
|
+
if (!value || value.startsWith('--'))
|
|
34
|
+
throw new Error(`${arg} needs a value`);
|
|
35
|
+
options[values.get(arg)] = value;
|
|
36
|
+
} else {
|
|
37
|
+
throw new Error(`Unknown option ${arg}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (!options.mode || !options.extension || !options.out || !options.repoBase)
|
|
41
|
+
throw new Error(usage);
|
|
42
|
+
if (!/^https?:\/\//.test(options.repoBase))
|
|
43
|
+
throw new Error('--repo-base must be an HTTP(S) URL');
|
|
44
|
+
return options;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function renderConsumerCatalog(rows, repoBase) {
|
|
48
|
+
const base = repoBase.endsWith('/') ? repoBase : `${repoBase}/`;
|
|
49
|
+
return (
|
|
50
|
+
'// Generated by kerf-catalog-demo. Do not edit.\n' +
|
|
51
|
+
`export const catalogRepositoryBlobUrl = ${JSON.stringify(base)} as const;\n` +
|
|
52
|
+
`export const generatedConsumerCatalog = ${JSON.stringify(rows, null, 2)} as const;\n`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function runCatalogProjection(argv) {
|
|
57
|
+
const options = parseArgs(argv);
|
|
58
|
+
const extension = JSON.parse(
|
|
59
|
+
await readFile(resolve(options.extension), 'utf8'),
|
|
60
|
+
);
|
|
61
|
+
const kerfCatalog = JSON.parse(
|
|
62
|
+
await readFile(
|
|
63
|
+
options.kerfCatalog
|
|
64
|
+
? resolve(options.kerfCatalog)
|
|
65
|
+
: new URL('./ai/component-catalog.json', import.meta.url),
|
|
66
|
+
'utf8',
|
|
67
|
+
),
|
|
68
|
+
);
|
|
69
|
+
const rows = projectConsumerCatalog(extension, kerfCatalog, options);
|
|
70
|
+
const output = renderConsumerCatalog(rows, options.repoBase);
|
|
71
|
+
const outputPath = resolve(options.out);
|
|
72
|
+
if (options.mode === '--write') {
|
|
73
|
+
await writeFile(outputPath, output);
|
|
74
|
+
process.stdout.write(`Wrote ${outputPath}\n`);
|
|
75
|
+
} else {
|
|
76
|
+
let current;
|
|
77
|
+
try {
|
|
78
|
+
current = await readFile(outputPath, 'utf8');
|
|
79
|
+
} catch {
|
|
80
|
+
// A missing generated file is the same drift as stale content.
|
|
81
|
+
}
|
|
82
|
+
if (current !== output)
|
|
83
|
+
throw new Error(`${outputPath} is stale; run kerf-catalog-demo --write`);
|
|
84
|
+
process.stdout.write(`${outputPath} is in sync.\n`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (
|
|
89
|
+
process.argv[1] &&
|
|
90
|
+
resolve(process.argv[1]) === fileURLToPath(import.meta.url)
|
|
91
|
+
) {
|
|
92
|
+
runCatalogProjection(process.argv.slice(2)).catch((error) => {
|
|
93
|
+
process.stderr.write(`kerf-catalog-demo: ${error.message}\n`);
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface CatalogProjectionRow {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
category: string;
|
|
5
|
+
kind: string;
|
|
6
|
+
source: string;
|
|
7
|
+
description: string;
|
|
8
|
+
recommendation?: string;
|
|
9
|
+
uses: readonly string[];
|
|
10
|
+
demoSource: string;
|
|
11
|
+
componentSource?: string;
|
|
12
|
+
designTemplate?: string;
|
|
13
|
+
documentation?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CatalogProjectionEntry {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
kind: string;
|
|
20
|
+
purpose: string;
|
|
21
|
+
category?: string;
|
|
22
|
+
source?: string;
|
|
23
|
+
demoSource?: string;
|
|
24
|
+
documentation?: string;
|
|
25
|
+
recommendation?: string;
|
|
26
|
+
uses?: string[];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CatalogProjectionOptions {
|
|
30
|
+
identity?: (entry: CatalogProjectionEntry) => string;
|
|
31
|
+
category?: (entry: CatalogProjectionEntry) => string;
|
|
32
|
+
componentSource?: (entry: CatalogProjectionEntry) => string | undefined;
|
|
33
|
+
demoSource?: (entry: CatalogProjectionEntry) => string | undefined;
|
|
34
|
+
documentation?: (entry: CatalogProjectionEntry) => string | undefined;
|
|
35
|
+
designTemplate?: (entry: CatalogProjectionEntry) => string | undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface ConsumerProjectionOptions {
|
|
39
|
+
category?: string;
|
|
40
|
+
sourceTemplate?: string;
|
|
41
|
+
demoTemplate?: string;
|
|
42
|
+
documentationTemplate?: string;
|
|
43
|
+
designTemplate?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function projectCatalogEntries(
|
|
47
|
+
entries: readonly CatalogProjectionEntry[],
|
|
48
|
+
options?: CatalogProjectionOptions,
|
|
49
|
+
): CatalogProjectionRow[];
|
|
50
|
+
|
|
51
|
+
export function projectConsumerCatalog(
|
|
52
|
+
extension: { package: string; entries: CatalogProjectionEntry[] },
|
|
53
|
+
kerfCatalog: { entries: { id: string }[] },
|
|
54
|
+
options?: ConsumerProjectionOptions,
|
|
55
|
+
): CatalogProjectionRow[];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isRepositoryPath,
|
|
3
|
+
validateCatalogExtensionReferences,
|
|
4
|
+
} from './scripts/component-catalog-extension-validation.mjs';
|
|
5
|
+
|
|
6
|
+
const substitute = (template, entry, packageName) =>
|
|
7
|
+
template.replace(/\{(id|name|kind|package)\}/g, (_, field) =>
|
|
8
|
+
field === 'package' ? packageName : entry[field],
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
/** Project catalog entries into the row shape used by a UX demo. */
|
|
12
|
+
export function projectCatalogEntries(entries, options = {}) {
|
|
13
|
+
return entries.map((entry) => {
|
|
14
|
+
const componentSource = options.componentSource?.(entry);
|
|
15
|
+
const designTemplate = options.designTemplate?.(entry);
|
|
16
|
+
return {
|
|
17
|
+
id: entry.id,
|
|
18
|
+
name: entry.name,
|
|
19
|
+
category: options.category?.(entry) ?? entry.category ?? 'Application',
|
|
20
|
+
kind: entry.kind,
|
|
21
|
+
source: options.identity?.(entry) ?? entry.source ?? 'consumer',
|
|
22
|
+
description: entry.purpose,
|
|
23
|
+
...(entry.recommendation ? { recommendation: entry.recommendation } : {}),
|
|
24
|
+
uses: entry.uses ?? [],
|
|
25
|
+
demoSource: options.demoSource?.(entry) ?? entry.demoSource,
|
|
26
|
+
...(componentSource ? { componentSource } : {}),
|
|
27
|
+
...(designTemplate ? { designTemplate } : {}),
|
|
28
|
+
documentation: options.documentation?.(entry) ?? entry.documentation,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Project a validated consumer extension alongside Kerf's reference catalog. */
|
|
34
|
+
export function projectConsumerCatalog(extension, kerfCatalog, options = {}) {
|
|
35
|
+
const failures = validateCatalogExtensionReferences(extension, kerfCatalog);
|
|
36
|
+
if (failures.length) throw new Error(failures.join('\n'));
|
|
37
|
+
const fill = (template, entry) =>
|
|
38
|
+
template ? substitute(template, entry, extension.package) : undefined;
|
|
39
|
+
const rows = projectCatalogEntries(extension.entries, {
|
|
40
|
+
identity: () => 'consumer',
|
|
41
|
+
category: () => options.category ?? 'Application',
|
|
42
|
+
componentSource: (entry) =>
|
|
43
|
+
entry.source ?? fill(options.sourceTemplate, entry),
|
|
44
|
+
demoSource: (entry) =>
|
|
45
|
+
entry.demoSource ??
|
|
46
|
+
fill(options.demoTemplate ?? 'ux-demo/demos/{id}.tsx', entry),
|
|
47
|
+
documentation: (entry) =>
|
|
48
|
+
entry.documentation ?? fill(options.documentationTemplate, entry),
|
|
49
|
+
designTemplate: (entry) => fill(options.designTemplate, entry),
|
|
50
|
+
});
|
|
51
|
+
for (const row of rows) {
|
|
52
|
+
if (!isRepositoryPath(row.demoSource))
|
|
53
|
+
throw new Error(`${row.id} requires a repository-relative demoSource`);
|
|
54
|
+
if (row.componentSource && !isRepositoryPath(row.componentSource))
|
|
55
|
+
throw new Error(`${row.id} has an invalid repository-relative source`);
|
|
56
|
+
if (!row.documentation)
|
|
57
|
+
throw new Error(
|
|
58
|
+
`${row.id} requires documentation or documentationTemplate`,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return rows;
|
|
62
|
+
}
|
package/dist/browser/catalog.js
CHANGED
|
@@ -3,6 +3,7 @@ import '../styles/list.css';
|
|
|
3
3
|
import '../styles/list-inset-text.css';
|
|
4
4
|
import '../styles/lucide-icon.css';
|
|
5
5
|
import '../styles/text.css';
|
|
6
|
+
import '../styles/loading-spinner.css';
|
|
6
7
|
import '../styles/toolbar-control-group.css';
|
|
7
8
|
import '../styles/skeleton.css';
|
|
8
9
|
import '../styles/toolbar-text.css';
|
|
@@ -16,7 +17,6 @@ import '../styles/row.css';
|
|
|
16
17
|
import '../styles/badge.css';
|
|
17
18
|
import '../styles/disclosure-arrow.css';
|
|
18
19
|
import '../styles/list-header.css';
|
|
19
|
-
import '../styles/loading-spinner.css';
|
|
20
20
|
import '../styles/list-item.css';
|
|
21
21
|
import '../styles/catalog/components/catalog-stage.css';
|
|
22
22
|
import '../styles/catalog/components/catalog.css';
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import '../styles/foundation.css';
|
|
2
2
|
import '../styles/lucide-icon.css';
|
|
3
|
+
import '../styles/list.css';
|
|
3
4
|
import '../styles/pane.css';
|
|
4
5
|
import '../styles/toolbar.css';
|
|
6
|
+
import '../styles/loading-spinner.css';
|
|
5
7
|
import '../styles/toolbar-control-group.css';
|
|
6
8
|
import '../styles/collapsible-panel.css';
|
|
7
9
|
export * from '../collapsible-panel.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../styles/foundation.css';
|
|
2
2
|
import '../styles/lucide-icon.css';
|
|
3
3
|
import '../styles/toolbar.css';
|
|
4
|
+
import '../styles/loading-spinner.css';
|
|
4
5
|
import '../styles/toolbar-control-group.css';
|
|
5
6
|
import '../styles/skeleton.css';
|
|
6
7
|
import '../styles/toolbar-text.css';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import '../styles/foundation.css';
|
|
2
2
|
import '../styles/lucide-icon.css';
|
|
3
3
|
import '../styles/toolbar.css';
|
|
4
|
+
import '../styles/loading-spinner.css';
|
|
4
5
|
import '../styles/toolbar-control-group.css';
|
|
5
6
|
import '../styles/skeleton.css';
|
|
6
7
|
import '../styles/toolbar-text.css';
|
|
@@ -5,6 +5,7 @@ import '../styles/list.css';
|
|
|
5
5
|
import '../styles/pane.css';
|
|
6
6
|
import '../styles/lucide-icon.css';
|
|
7
7
|
import '../styles/toolbar.css';
|
|
8
|
+
import '../styles/loading-spinner.css';
|
|
8
9
|
import '../styles/toolbar-control-group.css';
|
|
9
10
|
import '../styles/workbench.css';
|
|
10
11
|
export * from '../workbench.js';
|
package/dist/catalog.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import './list.js';
|
|
|
11
11
|
import './css-values.js';
|
|
12
12
|
import './flex-alignment-4ms8ZbV8.js';
|
|
13
13
|
import './resizable-region.js';
|
|
14
|
-
import './panel-toolbar-
|
|
14
|
+
import './panel-toolbar-DDKh4uKd.js';
|
|
15
15
|
import './lucide-icon.js';
|
|
16
16
|
import 'lucide';
|
|
17
17
|
|
package/dist/catalog.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { Workbench } from './chunk-
|
|
1
|
+
import { Workbench } from './chunk-KFYANKJI.js';
|
|
2
2
|
|
|
3
|
-
import { PopupMenu } from './chunk-
|
|
3
|
+
import { PopupMenu } from './chunk-ZRWXFDDS.js';
|
|
4
4
|
|
|
5
5
|
import { Row } from './chunk-VZOFZPSO.js';
|
|
6
|
-
import { ListHeader } from './chunk-
|
|
7
|
-
import { Text } from './chunk-
|
|
6
|
+
import { ListHeader } from './chunk-5IJ6UGNZ.js';
|
|
7
|
+
import { Text } from './chunk-CQHN45XR.js';
|
|
8
8
|
import { ListInsetText } from './chunk-DG6G5EPF.js';
|
|
9
|
-
import { ListItem } from './chunk-
|
|
10
|
-
import {
|
|
9
|
+
import { ListItem } from './chunk-EN4LDR5Y.js';
|
|
10
|
+
import { ToolbarText } from './chunk-V3DX3K65.js';
|
|
11
11
|
|
|
12
|
-
import { ToolbarText } from './chunk-3SXMEK3B.js';
|
|
13
12
|
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
|
|
18
|
+
import { List } from './chunk-NAPE7WUS.js';
|
|
19
19
|
|
|
20
|
+
import { ToolbarControlGroup, ToolbarActionLink } from './chunk-NXWE5S57.js';
|
|
21
|
+
import { Toolbar } from './chunk-RGS4WX2M.js';
|
|
22
|
+
import { LucideIcon } from './chunk-MOSIE4Z2.js';
|
|
20
23
|
|
|
21
|
-
import { ToolbarControlGroup, ToolbarActionLink } from './chunk-7JUBXOIV.js';
|
|
22
|
-
import { Toolbar } from './chunk-MERWRTBG.js';
|
|
23
|
-
import { LucideIcon } from './chunk-4R777DUZ.js';
|
|
24
24
|
import { filterDataAttributes } from './chunk-SRSJO5QE.js';
|
|
25
25
|
|
|
26
26
|
import { Moon, Sun, Waypoints, ExternalLink } from 'lucide';
|
|
@@ -67,6 +67,7 @@ function CatalogResourceFooter({
|
|
|
67
67
|
/* @__PURE__ */ jsx(
|
|
68
68
|
Toolbar,
|
|
69
69
|
{
|
|
70
|
+
position: "footer",
|
|
70
71
|
label: `${name} resources`,
|
|
71
72
|
dividerSides: toolbar?.dividerSides,
|
|
72
73
|
centerAlign: toolbar?.centerAlign,
|