@kerfjs/ui 5.0.0-beta.77 → 5.0.0-beta.79
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 +9 -4
- package/ai/application-ui-diagnostic-ids-v1.json +4 -0
- package/ai/compile-time-contracts-v1.json +3 -3
- package/ai/component-catalog.json +152 -31
- package/ai/component-composition-rules.json +6 -14
- package/ai/component-composition.json +123 -29
- package/ai/components/README.md +1 -1
- package/ai/components/document-baseline.md +1 -1
- package/ai/components/nav-stack.md +6 -6
- package/ai/components/pane.md +3 -1
- package/ai/components/surface-scaffold.md +11 -2
- package/ai/components/{tab-scaffold.md → tab-navigator.md} +14 -14
- package/ai/components/token-search-field.md +1 -0
- package/ai/components/toolbar-control-group.md +2 -0
- package/ai/components/toolbar-text.md +2 -0
- package/ai/components/toolbar.md +6 -8
- package/ai/public-api-signatures-v1.md +68 -140
- package/ai/skill.md +15 -4
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/browser/nav-stack.js +2 -0
- package/dist/browser/split-view.js +2 -0
- package/dist/browser/tab-navigator.js +4 -0
- package/dist/catalog-resources.d.ts +3 -3
- package/dist/catalog.d.ts +3 -3
- package/dist/catalog.js +3 -3
- package/dist/{chunk-WJN3V2H5.js → chunk-2GOCOLQL.js} +18 -4
- package/dist/chunk-2GOCOLQL.js.map +1 -0
- package/dist/{chunk-QYXKMLHO.js → chunk-3CXRQAYT.js} +2 -2
- package/dist/chunk-3CXRQAYT.js.map +1 -0
- package/dist/{chunk-G4VKQP7B.js → chunk-3SXWV2IR.js} +5 -1
- package/dist/chunk-3SXWV2IR.js.map +1 -0
- package/dist/{chunk-VLPE6OPN.js → chunk-62VMNBV2.js} +6 -2
- package/dist/chunk-62VMNBV2.js.map +1 -0
- package/dist/{chunk-XIZRXI7N.js → chunk-A7DYEERU.js} +13 -1
- package/dist/chunk-A7DYEERU.js.map +1 -0
- package/dist/{chunk-6VQPLV3O.js → chunk-DSLRNR43.js} +9 -8
- package/dist/chunk-DSLRNR43.js.map +1 -0
- package/dist/{chunk-AOAW55JN.js → chunk-DXQZ3BEO.js} +4 -1
- package/dist/chunk-DXQZ3BEO.js.map +1 -0
- package/dist/chunk-IKCUPTR2.js +170 -0
- package/dist/chunk-IKCUPTR2.js.map +1 -0
- package/dist/{chunk-Z6PE5T7N.js → chunk-JL4BBZP4.js} +4 -3
- package/dist/chunk-JL4BBZP4.js.map +1 -0
- package/dist/collapsible-panel.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/nav-stack-B1Qc2e5q.d.ts +101 -0
- package/dist/nav-stack.d.ts +11 -93
- package/dist/nav-stack.js +5 -1
- package/dist/pane.d.ts +5 -2
- package/dist/pane.js +1 -1
- package/dist/split-view.d.ts +9 -4
- package/dist/split-view.js +7 -3
- package/dist/split-view.js.map +1 -1
- package/dist/styles/components/actions/toolbar/toolbar.css +7 -14
- package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +63 -13
- package/dist/styles/components/actions/toolbar-text/toolbar-text.css +8 -1
- package/dist/styles/components/forms/token-search-field/token-search-field.css +12 -1
- package/dist/styles/components/layout/pane/pane.css +18 -1
- package/dist/styles/components/navigation/nav-stack/nav-stack.css +6 -12
- package/dist/styles/components/navigation/tab-scaffold/tab-scaffold.css +18 -1
- package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +55 -0
- package/dist/styles/nav-stack.css +6 -12
- package/dist/styles/pane.css +18 -1
- package/dist/styles/surface-scaffold.css +55 -0
- package/dist/styles/{tab-scaffold.css → tab-navigator.css} +18 -1
- package/dist/styles/token-search-field.css +12 -1
- package/dist/styles/toolbar-control-group.css +63 -13
- package/dist/styles/toolbar-text.css +8 -1
- package/dist/styles/toolbar.css +7 -14
- package/dist/surface-scaffold-register.d.ts +4 -0
- package/dist/surface-scaffold-register.js +59 -0
- package/dist/surface-scaffold-register.js.map +1 -0
- package/dist/surface-scaffold.d.ts +10 -2
- package/dist/surface-scaffold.js +1 -1
- package/dist/{tab-scaffold.d.ts → tab-navigator.d.ts} +12 -10
- package/dist/{tab-scaffold.js → tab-navigator.js} +4 -3
- package/dist/tab-navigator.js.map +1 -0
- package/dist/token-search-field.js +1 -1
- package/dist/wire-catalog.js +1 -1
- package/dist/wire-scroll-dividers.d.ts +3 -3
- package/dist/wire-scroll-dividers.js +1 -1
- package/dist/wire-tab-navigator.d.ts +11 -0
- package/dist/{wire-tab-scaffold.js → wire-tab-navigator.js} +3 -3
- package/dist/wire-tab-navigator.js.map +1 -0
- package/dist/wire-token-search-fields.js +1 -1
- package/dist/wire-toolbar-visibility.js +1 -1
- package/dist/workbench.d.ts +5 -13
- package/dist/workbench.js +1 -1
- package/docs/app-layouts.md +44 -11
- package/docs/component-contract.md +9 -2
- package/docs/component-selection.md +17 -15
- package/docs/design/templates/token-search-field/empty-dark.svg +1 -1
- package/docs/design/templates/token-search-field/empty.svg +1 -1
- package/docs/design/templates/token-search-field-dark.svg +1 -1
- package/docs/design/templates/token-search-field.svg +1 -1
- package/docs/design/templates.md +1 -1
- package/docs/examples/application-ui-profile.json +4 -4
- package/docs/layout.md +31 -8
- package/docs/nav-stack.md +30 -18
- package/docs/recipes.md +6 -2
- package/docs/split-view.md +7 -4
- package/docs/surface-scaffold.md +46 -0
- package/docs/{tab-scaffold.md → tab-navigator.md} +83 -11
- package/docs/type-contracts.md +3 -3
- package/docs/ui-analyzer.md +5 -0
- package/docs/ui-doctor.md +33 -0
- package/docs/workbench.md +3 -2
- package/doctor/component-style-checks.mjs +457 -0
- package/doctor/index.mjs +43 -13
- package/llms.txt +18 -6
- package/package.json +16 -11
- package/ux-demo/recipes/list-detail-dialog.tsx +4 -0
- package/ux-demo/recipes/navigation-stack.tsx +2 -2
- package/dist/browser/tab-scaffold.js +0 -4
- package/dist/chunk-6VQPLV3O.js.map +0 -1
- package/dist/chunk-AOAW55JN.js.map +0 -1
- package/dist/chunk-G4VKQP7B.js.map +0 -1
- package/dist/chunk-QYXKMLHO.js.map +0 -1
- package/dist/chunk-VLPE6OPN.js.map +0 -1
- package/dist/chunk-WJN3V2H5.js.map +0 -1
- package/dist/chunk-XIZRXI7N.js.map +0 -1
- package/dist/chunk-Z4EPMX25.js +0 -123
- package/dist/chunk-Z4EPMX25.js.map +0 -1
- package/dist/chunk-Z6PE5T7N.js.map +0 -1
- package/dist/tab-scaffold.js.map +0 -1
- package/dist/wire-tab-scaffold.d.ts +0 -11
- package/dist/wire-tab-scaffold.js.map +0 -1
|
@@ -171,10 +171,10 @@ beside a `ContentItem` value, and connect its id to the preview group's
|
|
|
171
171
|
| Inset bare text — `ListInsetText` | A plain string or inline content with no margin, border, or padding of its own must sit in a `.kui-content` list with its text edge aligned to the bordered items around it. | Do not use it to wrap a component that already owns content-item geometry (`ListItem`, `StateBanner`, a `.kui-content-item`) — that double-insets it. Do not hand-roll the 8px margin / 1px border / 8px padding. | Pass the text or inline `SafeHtml` as children; it supplies the 8px inline margin, 1px transparent border, and 8px padding so the text edge lands at the standard 17px inset. Pass `sides="rl"` to keep that horizontal inset but drop the vertical margin, border, and padding for tight text layout. | The text, copy, and localization. | `@kerfjs/ui/list-inset-text` | [Pane geometry](../README.md#component-subpaths) |
|
|
172
172
|
| Self-contained content child — `ContentItem` | An ordinary surface-like child of a `Pane` or `.kui-content` stack needs the shared 8px margin / 1px border / 8px padding geometry; pass `frame="framed"` only when it marks a real distinction, `appearance="surface"` or a semantic appearance for coordinated surface colors, and `shape="pill"` for the 22px radius. | Do not wrap a component that already owns content-item geometry (`ListItem`, `ListHeader`, `StateBanner`, `Toolbar`, `ValueTable`) or pad around it — that double-insets. Do not frame an item only to make it look contained. Use `SunkenPanel` for a lowered inset stack and `ListInsetText` for bare text that only needs to align. | Pass the item content as children; choose `appearance` (`transparent` default, `surface`, or a semantic status), `frame`, and `shape` instead of writing CSS. Put safe `data-*` metadata in `rootAttributes`; `ariaLabel` names a distinct region and `focusTarget` makes it a programmatic focus target. | The content, surface or status appearance, and whether it marks a distinction worth a visible frame. | `@kerfjs/ui/content-item` | [Content items](./layout.md#content-items) |
|
|
173
173
|
| Application column — `Pane` | A sidebar, main area, inspector, or dialog needs shared vertical header/content/footer organization, one scroll owner, and optional edge separators. | Do not pad the pane shell, wrap child-owned geometry in competing insets, invent unrelated centered measures, or leave an icon-only rail for a hidden pane. | Import `Pane`, use `children` for its homogeneous primary content and the named `SafeHtml` prop slots `header`/`footer` for optional fixed chrome, then opt into only the needed logical-edge separators; add `ContentItem` children as needed. A visible pane owns collapse in its toolbar; move a hidden inline-start pane's restore control to the main toolbar leading edge and an inline-end pane's restore control to its trailing edge. | Layout hierarchy, reading width, responsive relocation, pane visibility state, slot semantics, labels, and separator placement. | `@kerfjs/ui/pane` | [Pane anatomy](./layout.md#anatomy) |
|
|
174
|
-
| Scroll dividers — `wireScrollDividers` | Pinned chrome (a `Pane` header or footer, a `NavStack` top chrome or bottom toolbar, a `
|
|
175
|
-
| One-pane navigation — `NavStack` | A compact flow pushes into details while keeping earlier views mounted, or a single-pane screen needs the same stable layout contract. | Do not use it when list and detail should remain visible together; use `SplitView`. Do not use it alone for co-equal top-level destinations; use one stack per `
|
|
174
|
+
| Scroll dividers — `wireScrollDividers` | Pinned chrome (a `Pane` header or footer, a `NavStack` top chrome or bottom toolbar, a `TabNavigator` bar, the sides of a `TabBar` strip, or app-owned chrome around a scroller) needs a divider only while content is scrolled away beneath it. | Do not keep a static toolbar divider to fake it or write a border onto another component; each component draws its own line from the wiring's state. | Call `wireScrollDividers` once at the app root and retain the disposer; it covers every `Pane`, `NavStack`, `TabNavigator`, and `TabBar` below it. Name app-owned arrangements in `targets` by id; a `Toolbar` or `List` named as chrome draws its facing side. Configure a pane with `chromeDividers` (`scroll` default, `always`, `none`). | Which panes follow the scroll, app-owned targets, and the disposer. | `@kerfjs/ui/wire-scroll-dividers` | [Scroll dividers](./layout.md#scroll-dividers) |
|
|
175
|
+
| One-pane navigation — `NavStack` | A compact flow pushes into details while keeping earlier views mounted, or a single-pane screen needs the same stable layout contract. | Do not use it when list and detail should remain visible together; use `SplitView`. Do not use it alone for co-equal top-level destinations; use one stack per `TabNavigator` tab. | Keep the ordered view array controlled, put view-specific bottom chrome on each view (or use the component fallback), import its CSS explicitly, and call `wireNavStack` for back delegation, content-slide/chrome-cross-fade transitions, and focus move/restore. Mark a preferred initial target with `data-nav-focus` when DOM order is insufficient. | View keys/content/titles, push and pop actions, preferred initial focus targets, and per-view or persistent bottom toolbar content. | `@kerfjs/ui/nav-stack` | [App-layout decision matrix](./app-layouts.md#decision-matrix) |
|
|
176
176
|
| Responsive list-detail — `SplitView` | A primary list and related detail belong together on roomy devices but become a one-pane drill-down on compact devices. | Do not use it for a single linear flow or a multi-panel editor shell. | Provide controlled selection/detail state and device class; opt into resize wiring only when the separator is user adjustable. | Selection, detail content, compact back action, device policy, and optional persisted width. | `@kerfjs/ui/split-view` | [App-layout decision matrix](./app-layouts.md#decision-matrix) |
|
|
177
|
-
| Compact top-level destinations — `
|
|
177
|
+
| Compact top-level destinations — `TabNavigator` | A handset or portrait-tablet app has two to five co-equal destinations whose scenes and nested navigation must remain mounted across switches. | Do not use it for document tabs, reorderable work items, or a desktop navigation rail. | Keep the active id controlled, import its CSS explicitly, and call `wireTabNavigator`; commonly place one `NavStack` in each tab scene. | Destination definitions, active id, routing, persistence, and roomy-device replacement. | `@kerfjs/ui/tab-navigator` | [App-layout decision matrix](./app-layouts.md#decision-matrix) |
|
|
178
178
|
| Desktop multi-panel workspace — `Workbench` | A desktop-class tool needs a central work area plus independently collapsible navigator, inspector, or console regions. | Do not shrink the full shell onto compact devices or use it for one standalone panel. | Render only the required rails/drawer, keep collapse state controlled, and replace peripheral regions with stacks or overlays below desktop sizes. Opt a panel into drag/keyboard resizing with `resizable` and call `wireWorkbench` with its size signal. | Panel presence/content, collapsed states, sizes, persistence, responsive replacement, and controls. | `@kerfjs/ui/workbench` | [Workbench](./workbench.md) |
|
|
179
179
|
| Standalone rail or drawer — `CollapsiblePanel` | One left/right rail or bottom drawer needs controlled collapse without adopting the complete `Workbench` shell. | Do not use it for several coordinated workspace panels or retain an empty icon-only rail while collapsed. | Pair it with `CollapsiblePanelToggle`; call `wireSidebar` for focus transfer, Escape/backdrop dismissal, compact overlay trapping, and persistence integration. | Panel content/size, collapsed state, toggle placement, persistence, and compact policy. | `@kerfjs/ui/collapsible-panel` | [App-layout decision matrix](./app-layouts.md#decision-matrix) |
|
|
180
180
|
| Lowered content surface — `SunkenPanel` | A main work area or nested content group needs one visually lowered surface with a compact inset and vertical stack. | Do not use it merely to add padding, as a replacement for `Pane` anatomy, or around children that already own the same outer surface. | Compose the application-owned content as children, choose the default `rounded` shape or `square` for a flush edge-to-edge area, and pass `ariaLabel` only when the surface is a distinct named region. | Region semantics, accessible name, shape, scroll ownership, child ordering, and content. | `@kerfjs/ui/sunken-panel` | [SunkenPanel](./sunken-panel.md) |
|
|
@@ -183,7 +183,7 @@ beside a `ContentItem` value, and connect its id to the preview group's
|
|
|
183
183
|
| One application tab — `AppTab` | A controlled app tab needs selection, close, drag, leading/trailing anatomy, compact/segmented/icon-only presentation, label truncation, safe domain metadata, or a product-specific close glyph. | Do not render it alone or use it for a small settings choice; compose in `TabBar`, or use `SegmentedControl`. Keep `closeIcon` noninteractive. | Compose in `TabBar`; let `wireTabBars` manage interaction. Put only domain `data-*` values in `rootAttributes`; use typed appearance props instead of descendant CSS. | Tab identity, order, selection, close policy, content, domain metadata values, and outer placement. | `@kerfjs/ui/app-tab` | [Tabs contract](./accessibility.md#tabs) |
|
|
184
184
|
| Application tab strip — `TabBar`, `wireTabBars`, `reorderTabs` | Tabs switch page regions and may overflow, close, reorder, fill a segmented inspector strip, sit beside a trailing action, or keep that adjacent action distinct from a far-edge end action. | Do not use it for a compact local view toggle; use `SegmentedControl`. Do not use it for a long choice list; use `Select`. Prefer it over Web Awesome `wa-tab-group`, `wa-tab`, and `wa-tab-panel` for Kerf app tabs. | Call `wireTabBars` once, retain the disposer, and apply `onReorder` synchronously; `reorderTabs` is the default array helper. Combine `trailingPlacement="adjacent"` with `end` for split actions; TabBar owns the shrinking/scrolling tab geometry and keeps both actions visible. Choose typed presentation/allocation props while the parent owns outer placement. | Ordered tabs, selection, panels, routing, closing, persistence, action content, and outer placement. | `@kerfjs/ui/tab-bar` plus `@kerfjs/ui/wire-tab-bars` | [Tabs contract](./accessibility.md#tabs) |
|
|
185
185
|
| Panel, dialog, or page heading — `Toolbar` + `ToolbarText` | A panel, dialog, or page needs an extra-large title, optional icon, grouped trailing actions, and optional supporting copy. | Do not add a private heading wrapper or bespoke layout. The toolbar supplies structure, not modal behavior; use an application overlay or Web Awesome `wa-dialog` for that behavior. In a narrow peripheral rail or drawer, where xlarge would truncate at the panel's minimum size, use the default `ToolbarText` size as pane identity. | Connect title/supporting-copy ids to the host, group controls, and delegate actions. **For a page or view title set `headingLevel` (usually `1`)** on `ToolbarText`; omit it for a dialog title referenced by `aria-labelledby`. | Open state, focus lifecycle, dismissal, controls, ids, copy, and heading level. | `@kerfjs/ui/toolbar` + `@kerfjs/ui/toolbar-text` | [Toolbar headings](./accessibility.md#toolbar-headings) |
|
|
186
|
-
| Dialog or popup geometry — `DialogSurface`, `PopupSurface` | Recurring Web Awesome dialogs need standard sizes/presentations/body/footer insets, or dropdown menus need list-compatible inset ownership.
|
|
186
|
+
| Dialog or popup geometry — `DialogSurface`, `PopupSurface` | Recurring Web Awesome dialogs need standard sizes/presentations/body/footer insets and typed modal viewport bounds, or dropdown menus need list-compatible inset ownership. | Do not use these wrappers as generic layout or to replace native dialog/dropdown behavior. Avoid consumer `::part()` overrides and do not stack a dialog body inset around list-owned child geometry. | Wrap one `wa-dialog` or `wa-dropdown`; choose the typed geometry while retaining native labeling, open state, focus, dismissal, and menu semantics. Compose a dialog body as a `List` by default, use `bodyInset="none"` when its children own list geometry, and wrap bare prose in `ListInsetText`. | State, focus lifecycle, dismissal, labels, content, and outer placement. | `@kerfjs/ui/surface-scaffold` | [Surface scaffolds](./surface-scaffold.md) |
|
|
187
187
|
| Key/value facts — `ValueTable`, `ValueTableRow` | Read-only labels and values form a semantic definition list, optionally with a leading icon. | Do not use it for editable form fields or a row/column data grid; use native form or table semantics. | Compose typed `ValueTableRow` entries; pass `icon` when a 24px leading icon adds useful context. | Values, formatting, icon meaning, and empty/loading policy. | `@kerfjs/ui/value-table` | [Component ownership](./component-contract.md#ownership-boundaries) |
|
|
188
188
|
| Indeterminate activity — `LoadingSpinner` | A Kerf surface needs compact, labeled or decorative indeterminate progress. | Do not use it for known progress; use Web Awesome `wa-progress-bar` or `wa-progress-ring`. Direct Web Awesome UI may use `wa-spinner`; do not mix spinner systems within one surface. | Pass a label when the spinner conveys status; use size for a named icon step or positive pixel size. | Loading lifecycle and adjacent status copy. | `@kerfjs/ui/loading-spinner` | [Accessibility](./accessibility.md#shared-rules) |
|
|
189
189
|
| Loading placeholder — `Skeleton` + a component's `placeholder` prop | A value or a whole component is still loading and should hold its space as a subtle, unanimated block, keeping the layout stable — an inspector or detail view rendering its real chrome with per-record values absent. | Do not use it for known progress (use `LoadingSpinner`), do not animate it, and do not hand-rebuild a component's empty state — set `placeholder` on the component instead. Prefer it over `wa-skeleton`, which the pure-Kerf primitives avoid to stay Web-Awesome-free. | Set `placeholder` on a value-bearing component (`Select`, `ListHeader`, `ListItem`, `ValueTableRow`, `SegmentedControl`, `StateBanner`, `AppTab`, `ToolbarText`, `ListActionRow`) to render skeletons in its value slots with interactivity disabled; use the standalone `Skeleton` for a custom slot. | Loading lifecycle, which slots are unknown, and announcing the loading region. | `@kerfjs/ui/skeleton` | [Accessibility](./accessibility.md#shared-rules) |
|
|
@@ -405,22 +405,24 @@ A `FloatingToolbar` accepts `ToolbarControlGroup` directly as its children in
|
|
|
405
405
|
both floating and inline placement. Name the toolbar with `label`; group its
|
|
406
406
|
controls as you would in a `Toolbar` zone.
|
|
407
407
|
|
|
408
|
-
A `Toolbar` has three zones — `leading`, `center`, and `trailing`.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
408
|
+
A `Toolbar` has three zones — `leading`, `center`, and `trailing`. Each accepts
|
|
409
|
+
`KerfUiContent` directly, including a status `Chip`, a native control, or
|
|
410
|
+
application markup. `ToolbarText` is the standard identity/title; use
|
|
411
|
+
`ToolbarControlGroup` when related controls should share its chrome, sizing,
|
|
412
|
+
hover treatment, or overflow behavior. A standalone primary `wa-button` keeps
|
|
413
|
+
its own Web Awesome chrome and fits naturally in the trailing zone. Bare
|
|
414
|
+
controls retain their own styling and accessibility responsibilities; the
|
|
415
|
+
toolbar only positions them within the zone.
|
|
414
416
|
For a title that opens an editor, set `action` on a direct `ToolbarText`: it
|
|
415
417
|
renders a native button that keeps its content width when possible and
|
|
416
418
|
ellipsizes before an adjacent status chip when the leading zone narrows. The
|
|
417
419
|
application handles the delegated action and replaces it with its own input
|
|
418
420
|
while editing. Use a separate heading landmark if the view needs one.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
421
|
+
For a search or cluster that needs shared toolbar geometry, place
|
|
422
|
+
`SegmentedControl`, `Select`, or `TokenSearchField` inside a
|
|
423
|
+
`ToolbarControlGroup`. The ToolbarText catalog's actionable-title example
|
|
424
|
+
places its status `Chip` directly beside the title while the search uses a
|
|
425
|
+
group. For a page, panel, or
|
|
424
426
|
dialog heading, put an extra-large `ToolbarText` directly in the leading zone,
|
|
425
427
|
optionally preceded by a grouped icon, and group trailing actions. Keep supporting
|
|
426
428
|
copy below as app-owned content. Size the title to its track: a narrow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 100" width="560" height="100"><defs><clipPath id="cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g clip-path="url(#cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 100" width="560" height="100"><defs><clipPath id="cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments" role="img" aria-label="Search tickets"><g/><g transform="translate(53 46.547)"><text x="0" y="0" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(174, 174, 178)">Search tickets</text></g></g><g clip-path="url(#cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 100" width="560" height="100"><defs><clipPath id="cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g clip-path="url(#cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 100" width="560" height="100"><defs><clipPath id="cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments" role="img" aria-label="Search tickets"><g/><g transform="translate(53 46.547)"><text x="0" y="0" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(110, 110, 115)">Search tickets</text></g></g><g clip-path="url(#cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 592 292" width="592" height="292"><defs><clipPath id="cp0"><rect x="16" y="38" width="560" height="100"/></clipPath><clipPath id="cp1"><rect x="16" y="176" width="560" height="100"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="560" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="560" height="100" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="154" width="560" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="176" width="560" height="100" rx="0"/></clipPath></defs><rect x="0" y="0" width="592" height="292" 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)">Text with atomic tokens</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="560" height="100"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="29" y="34" width="16" height="16"/></clipPath><clipPath id="svgimg4ct2"><rect x="53" y="32.5" width="66.8" height="17"/></clipPath><clipPath id="svgimg4ct3"><rect x="129" y="33.9" width="41.1" height="18"/></clipPath><clipPath id="svgimg4cp4"><rect x="175" y="37" width="11.3" height="11.5"/></clipPath><clipPath id="svgimg4ct6"><rect x="191.7" y="32.5" width="50.7" height="17"/></clipPath><clipPath id="svgimg4cp7"><rect x="512" y="35" width="14" height="14"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g clip-path="url(#svgimg4cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg4svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg4svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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><text x="53" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(245,245,247)">payments </text><rect x="121.8" y="33.9" width="67.9" height="18" rx="9" fill="rgb(40,57,66)"/><text x="129" y="46.86" font-family="system-ui, "-apple-system", sans-serif" font-size="12" fill="rgb(138,203,255)">is:open</text><g clip-path="url(#svgimg4cp4)"><g color="rgb(138, 203, 255)"><clipPath id="svgimg4svgic5"><rect x="175.1" y="37.3" width="11.2" height="11.2"/></clipPath><g clip-path="url(#svgimg4svgic5)"><g transform="translate(175.094 37.266)scale(.46615)"><path d="M18 6 6 18" 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="m6 6 12 12" 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><text x="191.69" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(245,245,247)">is:open </text><g clip-path="url(#svgimg4cp7)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg4svgic8"><rect x="512.2" y="35.2" width="13.6" height="13.6"/></clipPath><g clip-path="url(#svgimg4svgic8)"><g transform="translate(512.203 35.203)scale(.5664)"><path d="M18 6 6 18" 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="m6 6 12 12" 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></g></g></g><text x="16" y="166" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Empty, expanded</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="176" width="560" height="100"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 176)"><defs><clipPath id="svgimg7cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g clip-path="url(#svgimg7cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg7svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg7svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></g></g></g></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 592 292" width="592" height="292"><defs><clipPath id="cp0"><rect x="16" y="38" width="560" height="100"/></clipPath><clipPath id="cp1"><rect x="16" y="176" width="560" height="100"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="560" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="560" height="100" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="154" width="560" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="176" width="560" height="100" rx="0"/></clipPath></defs><rect x="0" y="0" width="592" height="292" 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)">Text with atomic tokens</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="560" height="100"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="29" y="34" width="16" height="16"/></clipPath><clipPath id="svgimg4ct2"><rect x="53" y="32.5" width="66.8" height="17"/></clipPath><clipPath id="svgimg4ct3"><rect x="129" y="33.9" width="41.1" height="18"/></clipPath><clipPath id="svgimg4cp4"><rect x="175" y="37" width="11.3" height="11.5"/></clipPath><clipPath id="svgimg4ct6"><rect x="191.7" y="32.5" width="50.7" height="17"/></clipPath><clipPath id="svgimg4cp7"><rect x="512" y="35" width="14" height="14"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g clip-path="url(#svgimg4cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg4svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg4svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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><text x="53" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(245,245,247)">payments </text><rect x="121.8" y="33.9" width="67.9" height="18" rx="9" fill="rgb(40,57,66)"/><text x="129" y="46.86" font-family="system-ui, "-apple-system", sans-serif" font-size="12" fill="rgb(138,203,255)">is:open</text><g clip-path="url(#svgimg4cp4)"><g color="rgb(138, 203, 255)"><clipPath id="svgimg4svgic5"><rect x="175.1" y="37.3" width="11.2" height="11.2"/></clipPath><g clip-path="url(#svgimg4svgic5)"><g transform="translate(175.094 37.266)scale(.46615)"><path d="M18 6 6 18" 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="m6 6 12 12" 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><text x="191.69" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(245,245,247)">is:open </text><g clip-path="url(#svgimg4cp7)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg4svgic8"><rect x="512.2" y="35.2" width="13.6" height="13.6"/></clipPath><g clip-path="url(#svgimg4svgic8)"><g transform="translate(512.203 35.203)scale(.5664)"><path d="M18 6 6 18" 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="m6 6 12 12" 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></g></g></g><text x="16" y="166" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(174,174,178)">Empty, expanded</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="176" width="560" height="100"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 176)"><defs><clipPath id="svgimg7cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(28,28,30)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(253,253,255,0.196)" stroke-width="1"/><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments" role="img" aria-label="Search tickets"><g/><g transform="translate(53 46.547)"><text x="0" y="0" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(174, 174, 178)">Search tickets</text></g></g><g clip-path="url(#svgimg7cp0)"><g color="rgb(174, 174, 178)"><clipPath id="svgimg7svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg7svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></g></g></g></svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 592 292" width="592" height="292"><defs><clipPath id="cp0"><rect x="16" y="38" width="560" height="100"/></clipPath><clipPath id="cp1"><rect x="16" y="176" width="560" height="100"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="560" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="560" height="100" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="154" width="560" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="176" width="560" height="100" rx="0"/></clipPath></defs><rect x="0" y="0" width="592" height="292" 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)">Text with atomic tokens</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="560" height="100"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="29" y="34" width="16" height="16"/></clipPath><clipPath id="svgimg4ct2"><rect x="53" y="32.5" width="66.8" height="17"/></clipPath><clipPath id="svgimg4ct3"><rect x="129" y="33.9" width="41.1" height="18"/></clipPath><clipPath id="svgimg4cp4"><rect x="175" y="37" width="11.3" height="11.5"/></clipPath><clipPath id="svgimg4ct6"><rect x="191.7" y="32.5" width="50.7" height="17"/></clipPath><clipPath id="svgimg4cp7"><rect x="512" y="35" width="14" height="14"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g clip-path="url(#svgimg4cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg4svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg4svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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><text x="53" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(29,29,31)">payments </text><rect x="121.8" y="33.9" width="67.9" height="18" rx="9" fill="rgb(214,233,249)"/><text x="129" y="46.86" font-family="system-ui, "-apple-system", sans-serif" font-size="12" fill="rgb(12,98,243)">is:open</text><g clip-path="url(#svgimg4cp4)"><g color="rgb(12, 98, 243)"><clipPath id="svgimg4svgic5"><rect x="175.1" y="37.3" width="11.2" height="11.2"/></clipPath><g clip-path="url(#svgimg4svgic5)"><g transform="translate(175.094 37.266)scale(.46615)"><path d="M18 6 6 18" 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="m6 6 12 12" 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><text x="191.69" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(29,29,31)">is:open </text><g clip-path="url(#svgimg4cp7)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg4svgic8"><rect x="512.2" y="35.2" width="13.6" height="13.6"/></clipPath><g clip-path="url(#svgimg4svgic8)"><g transform="translate(512.203 35.203)scale(.5664)"><path d="M18 6 6 18" 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="m6 6 12 12" 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></g></g></g><text x="16" y="166" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Empty, expanded</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="176" width="560" height="100"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 176)"><defs><clipPath id="svgimg7cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g clip-path="url(#svgimg7cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg7svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg7svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></g></g></g></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 592 292" width="592" height="292"><defs><clipPath id="cp0"><rect x="16" y="38" width="560" height="100"/></clipPath><clipPath id="cp1"><rect x="16" y="176" width="560" height="100"/></clipPath><clipPath id="ct2"><rect x="16" y="16" width="560" height="22"/></clipPath><clipPath id="irc3"><rect x="16" y="38" width="560" height="100" rx="0"/></clipPath><clipPath id="ct5"><rect x="16" y="154" width="560" height="22"/></clipPath><clipPath id="irc6"><rect x="16" y="176" width="560" height="100" rx="0"/></clipPath></defs><rect x="0" y="0" width="592" height="292" 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)">Text with atomic tokens</text><g clip-path="url(#cp0)"><g clip-path="url(#irc3)"><clipPath id="svgimg4vclip"><rect x="16" y="38" width="560" height="100"/></clipPath><g clip-path="url(#svgimg4vclip)"><g transform="translate(16 38)"><defs><clipPath id="svgimg4cp0"><rect x="29" y="34" width="16" height="16"/></clipPath><clipPath id="svgimg4ct2"><rect x="53" y="32.5" width="66.8" height="17"/></clipPath><clipPath id="svgimg4ct3"><rect x="129" y="33.9" width="41.1" height="18"/></clipPath><clipPath id="svgimg4cp4"><rect x="175" y="37" width="11.3" height="11.5"/></clipPath><clipPath id="svgimg4ct6"><rect x="191.7" y="32.5" width="50.7" height="17"/></clipPath><clipPath id="svgimg4cp7"><rect x="512" y="35" width="14" height="14"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g clip-path="url(#svgimg4cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg4svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg4svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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><text x="53" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(29,29,31)">payments </text><rect x="121.8" y="33.9" width="67.9" height="18" rx="9" fill="rgb(214,233,249)"/><text x="129" y="46.86" font-family="system-ui, "-apple-system", sans-serif" font-size="12" fill="rgb(12,98,243)">is:open</text><g clip-path="url(#svgimg4cp4)"><g color="rgb(12, 98, 243)"><clipPath id="svgimg4svgic5"><rect x="175.1" y="37.3" width="11.2" height="11.2"/></clipPath><g clip-path="url(#svgimg4svgic5)"><g transform="translate(175.094 37.266)scale(.46615)"><path d="M18 6 6 18" 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="m6 6 12 12" 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><text x="191.69" y="46.55" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(29,29,31)">is:open </text><g clip-path="url(#svgimg4cp7)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg4svgic8"><rect x="512.2" y="35.2" width="13.6" height="13.6"/></clipPath><g clip-path="url(#svgimg4svgic8)"><g transform="translate(512.203 35.203)scale(.5664)"><path d="M18 6 6 18" 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="m6 6 12 12" 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></g></g></g><text x="16" y="166" font-family="system-ui, "-apple-system", sans-serif" font-size="12" font-weight="600" fill="rgb(110,110,115)">Empty, expanded</text><g clip-path="url(#cp1)"><g clip-path="url(#irc6)"><clipPath id="svgimg7vclip"><rect x="16" y="176" width="560" height="100"/></clipPath><g clip-path="url(#svgimg7vclip)"><g transform="translate(16 176)"><defs><clipPath id="svgimg7cp0"><rect x="29" y="34" width="16" height="16"/></clipPath></defs><rect x="20" y="20" width="520" height="44" rx="22" fill="rgb(255,255,255)"/><rect x="20.5" y="20.5" width="519" height="43" rx="21.5" fill="none" stroke="rgba(0,0,28,0.18)" stroke-width="1"/><g data-domotion-pseudo-source="blink-pseudo-fragment-v1" data-domotion-pseudo="::before" data-domotion-pseudo-owner="source-fragments" role="img" aria-label="Search tickets"><g/><g transform="translate(53 46.547)"><text x="0" y="0" font-family="system-ui, "-apple-system", sans-serif" font-size="14" fill="rgb(110, 110, 115)">Search tickets</text></g></g><g clip-path="url(#svgimg7cp0)"><g color="rgb(110, 110, 115)"><clipPath id="svgimg7svgic1"><rect x="29" y="34" width="16" height="16"/></clipPath><g clip-path="url(#svgimg7svgic1)"><g transform="translate(29 34)scale(.66667)"><path d="m21 21-4.3-4.3" 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"/><circle cx="11" cy="11" r="8" 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></g></g></g></svg>
|
package/docs/design/templates.md
CHANGED
|
@@ -19,7 +19,7 @@ picture): `Select` renders a Web Awesome custom element that needs its runtime
|
|
|
19
19
|
registered, so it has no faithful static capture; `LucideIcon` and
|
|
20
20
|
`DisclosureArrow` are decorative primitives best seen inside the components that
|
|
21
21
|
use them; `ResizableRegion` and the whole-screen layouts (`NavStack`,
|
|
22
|
-
`SplitView`, `Workbench`, `
|
|
22
|
+
`SplitView`, `Workbench`, `TabNavigator`) and the `Catalog` shell are
|
|
23
23
|
interaction-/viewport-driven screens rather than component cards — the live UX
|
|
24
24
|
catalog and the app-layouts docs cover those.
|
|
25
25
|
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
},
|
|
52
52
|
"exceptions": [
|
|
53
53
|
{
|
|
54
|
-
"id": "legacy-
|
|
55
|
-
"rules": ["KUI-
|
|
56
|
-
"target": "src/features/legacy-report/report-
|
|
57
|
-
"rationale": "The
|
|
54
|
+
"id": "legacy-list-header",
|
|
55
|
+
"rules": ["KUI-C103"],
|
|
56
|
+
"target": "src/features/legacy-report/report-list-header.tsx",
|
|
57
|
+
"rationale": "The legacy report adapter owns disclosure content and its expanded state."
|
|
58
58
|
}
|
|
59
59
|
]
|
|
60
60
|
}
|
package/docs/layout.md
CHANGED
|
@@ -36,6 +36,26 @@ size) tall, and below that lets the whole pane scroll as one column, header,
|
|
|
36
36
|
content, and footer together, so the content keeps its natural height. The
|
|
37
37
|
default `fixed` always pins them.
|
|
38
38
|
|
|
39
|
+
### Deep content inset
|
|
40
|
+
|
|
41
|
+
Set `deepInset` on a `Pane` to add one 8px inline gutter to its scrolling
|
|
42
|
+
content. A `ContentItem` or `ListItem` that normally sits 8px from the pane
|
|
43
|
+
edge then sits 16px from it. The default is `false`. This extra gutter adds
|
|
44
|
+
to any device safe-area inset, while the pane's header, footer, background,
|
|
45
|
+
and separators still reach their usual edges.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<Pane deepInset>
|
|
49
|
+
<ContentItem>Project Atlas</ContentItem>
|
|
50
|
+
</Pane>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The pane leaves `--kui-layout-inline-margin` at its normal 8px value. Nested
|
|
54
|
+
`Row`, `List`, and `Grid` therefore keep their usual item spacing; they do
|
|
55
|
+
not inherit a doubled margin. `PaneConfig.deepInset` forwards through
|
|
56
|
+
Workbench `mainPane`, panel `pane`, CollapsiblePanel `pane`, and a
|
|
57
|
+
`NavStackView.pane`.
|
|
58
|
+
|
|
39
59
|
### Lowered work surfaces
|
|
40
60
|
|
|
41
61
|
Set `appearance="sunken"` when the work area itself should use the lowered
|
|
@@ -60,7 +80,7 @@ on the Pane; it defaults to `--kui-color-surface`.
|
|
|
60
80
|
`PaneConfig.appearance` forwards through Workbench `mainPane`, panel `pane`,
|
|
61
81
|
and CollapsiblePanel `pane`. Workbench also applies that choice to its main or
|
|
62
82
|
panel region when it renders no Pane chrome. Set `appearance: "sunken"` on a
|
|
63
|
-
`NavStackView` or `
|
|
83
|
+
`NavStackView` or `TabNavigatorTab` when its view or scene owns scrolling.
|
|
64
84
|
For a `SplitView`, put a `Pane` in the list or detail region and set its
|
|
65
85
|
appearance; SplitView only arranges the regions and does not own their scroll.
|
|
66
86
|
Choose the innermost owner when composing layouts.
|
|
@@ -102,7 +122,7 @@ and the footer's top line, whatever the chrome holds — a `Toolbar`, a
|
|
|
102
122
|
whose tabs are scrolled out of view). That includes the panes a `Workbench`,
|
|
103
123
|
`CollapsiblePanel`, or `Catalog` renders; `wireCatalog` installs it for its
|
|
104
124
|
own root. It also covers every `NavStack` (the top chrome's bottom line and the
|
|
105
|
-
bottom toolbar's top line, around the active view) and every `
|
|
125
|
+
bottom toolbar's top line, around the active view) and every `TabNavigator`
|
|
106
126
|
(the bar's top line, over the active scene). The layout keys on whichever
|
|
107
127
|
element actually scrolls there: the view or scene itself, or, through a sole
|
|
108
128
|
child with no chrome of its own on that edge, a `Pane`'s content or a nested
|
|
@@ -120,7 +140,7 @@ for a root already has scroll dividers there and does not need another call.
|
|
|
120
140
|
The wiring only reports state; every component draws its own line. It writes
|
|
121
141
|
`data-scroll-overflow` (the edges with content hidden beyond them, in canonical
|
|
122
142
|
`t`/`r`/`b`/`l` order) on each scroller and `data-scroll-divider` (the sides to
|
|
123
|
-
draw) on each piece of chrome, and the Pane, NavStack,
|
|
143
|
+
draw) on each piece of chrome, and the Pane, NavStack, TabNavigator, TabBar,
|
|
124
144
|
Toolbar, and List stylesheets draw from those. The line is an inset shadow or a pseudo-element
|
|
125
145
|
inside the component, so no state ever moves the chrome, the content, or a tab.
|
|
126
146
|
Never write a border onto a component to show one.
|
|
@@ -130,7 +150,7 @@ the scroll state and draws nothing until the wiring runs; `always` (the sunken
|
|
|
130
150
|
pane default) keeps both lines; `none` drops them. Explicit values override
|
|
131
151
|
either default. Layouts forward it through `PaneConfig`
|
|
132
152
|
(`mainPane.chromeDividers`, a panel's `pane.chromeDividers`). A `NavStack` and a
|
|
133
|
-
`
|
|
153
|
+
`TabNavigator` take the same `chromeDividers` for their own chrome (the stack's
|
|
134
154
|
top chrome and bottom toolbar, the scaffold's bar), and a `SplitView` forwards
|
|
135
155
|
it to its compact stack through `compactStack`.
|
|
136
156
|
|
|
@@ -295,10 +315,13 @@ inset. Most interactive rows and toolbar groups are 44px tall.
|
|
|
295
315
|
Toolbar groups reserve a real 1px outer border around a 42px inner area, even
|
|
296
316
|
when their border and background are transparent.
|
|
297
317
|
A `Toolbar` lays its zones out against one 44px control band at its top: an
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
318
|
+
ordinary `ToolbarText`, `ToolbarControlGroup`, or standalone trailing
|
|
319
|
+
`wa-button` no taller than the band is centered in it by its own size, and a
|
|
320
|
+
taller one (a wrapped title, a second trailing row) starts at the band's top
|
|
321
|
+
and grows down, so it never moves the other controls. A wrapped `ToolbarText`
|
|
322
|
+
centers its first line in the band. Other direct zone content centers against
|
|
323
|
+
the zone's full height by default, including when a sibling makes that zone
|
|
324
|
+
taller than the control band.
|
|
302
325
|
The leading zone clips a shrinking title but reserves 4px of paint overflow
|
|
303
326
|
for the focus outline of a control at its edge. Focus rings in all three zones
|
|
304
327
|
remain visible at narrow and wide widths.
|
package/docs/nav-stack.md
CHANGED
|
@@ -15,7 +15,7 @@ import { wireNavStack } from "@kerfjs/ui/wire-nav-stack";
|
|
|
15
15
|
In a browser bundler that honors the `browser` export condition (Vite, esbuild, and
|
|
16
16
|
webpack do by default), the import above also
|
|
17
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:
|
|
18
|
+
(`Toolbar`, `ToolbarControlGroup`, `ToolbarText`, `Pane`, `List`, `LucideIcon`). Without that condition, import the manual stylesheets instead:
|
|
19
19
|
`@kerfjs/ui/nav-stack.css` plus those components' CSS, or `@kerfjs/ui/styles.css`.
|
|
20
20
|
|
|
21
21
|
## State lives in the app
|
|
@@ -28,9 +28,12 @@ stack as a `signal<NavStackView[]>`, `NavStack({ views })` renders it, and
|
|
|
28
28
|
const views = signal<NavStackView[]>([
|
|
29
29
|
{
|
|
30
30
|
key: "inbox",
|
|
31
|
-
title: "Inbox",
|
|
31
|
+
toolbar: { title: "Inbox" },
|
|
32
32
|
content: <InboxView />,
|
|
33
|
-
bottomToolbar:
|
|
33
|
+
bottomToolbar: {
|
|
34
|
+
label: "Inbox status",
|
|
35
|
+
leading: <InboxStatus />,
|
|
36
|
+
},
|
|
34
37
|
},
|
|
35
38
|
]);
|
|
36
39
|
|
|
@@ -47,35 +50,39 @@ const dispose = wireNavStack(root, {
|
|
|
47
50
|
// push / pop by editing the signal:
|
|
48
51
|
views.value = [
|
|
49
52
|
...views.value,
|
|
50
|
-
{ key: id, title: "Message", content: <MessageView id={id} /> },
|
|
53
|
+
{ key: id, toolbar: { title: "Message" }, content: <MessageView id={id} /> },
|
|
51
54
|
];
|
|
52
55
|
```
|
|
53
56
|
|
|
54
57
|
`NavStack` renders every entry stacked, the last one active and the rest kept
|
|
55
58
|
mounted (so their DOM state survives) but hidden. Each entry carries a
|
|
56
|
-
`key` (stable identity), `content`, an optional `title`,
|
|
57
|
-
`leading`, `center`, and trailing
|
|
58
|
-
|
|
59
|
+
`key` (stable identity), `content`, an optional `toolbar` object with `title`,
|
|
60
|
+
`leading`, `center`, and `trailing` groups, and an optional structured
|
|
61
|
+
`bottomToolbar`. The component-level structured
|
|
59
62
|
`bottomToolbar` remains a persistent fallback for views that do not provide one.
|
|
60
|
-
Each view can also provide `header`,
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
Each view can also provide `header`, `footer`, `headerList`, `footerList`, and
|
|
64
|
+
`pane` configuration, as a `WorkbenchStaticPanel` does. With any of these,
|
|
65
|
+
the view renders a `Pane`: its header and footer stay pinned around the view's
|
|
66
|
+
scrolling content, and slide with that view during navigation. The header and
|
|
67
|
+
footer list configuration forwards to their `List`s; `pane` forwards
|
|
68
|
+
`contentElement`, `contentLabel`, `separators`, `safeAreaEdges`,
|
|
69
|
+
`chromeDividers`, and `appearance` to the Pane. Without those fields, the view
|
|
70
|
+
keeps its simple direct scroll area. Use `pane: { appearance: "sunken" }` for a
|
|
71
|
+
lowered scrolling work surface.
|
|
63
72
|
The back control appears automatically once the stack has more than one entry;
|
|
64
73
|
`wireNavStack`'s `onBack` is where the app pops its own signal.
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
view holds a `Pane` as its only child, set the appearance on the Pane instead
|
|
69
|
-
if its content owns scrolling. See [Lowered work surfaces](layout.md#lowered-work-surfaces).
|
|
75
|
+
See [Lowered work surfaces](layout.md#lowered-work-surfaces) for nested Pane
|
|
76
|
+
and layout content.
|
|
70
77
|
|
|
71
78
|
## The top toolbar
|
|
72
79
|
|
|
73
80
|
The top chrome is a real `Toolbar`, so it follows the same zone,
|
|
74
81
|
group, and responsive rules as every other toolbar. Its leading zone holds the
|
|
75
82
|
back control (a borderless `ToolbarControlGroup`, shown once the stack has
|
|
76
|
-
depth), then
|
|
77
|
-
`
|
|
78
|
-
|
|
83
|
+
depth), then `toolbar.leading`, then `toolbar.title` as a `ToolbarText`.
|
|
84
|
+
`toolbar.center` fills the center zone and `toolbar.trailing` fills the
|
|
85
|
+
trailing zone. Give each zone `ToolbarControlGroup`s or `ToolbarText`,
|
|
79
86
|
as in any toolbar.
|
|
80
87
|
|
|
81
88
|
Configure the toolbar with `toolbarConfig` instead of styling it:
|
|
@@ -95,7 +102,12 @@ Configure the toolbar with `toolbarConfig` instead of styling it:
|
|
|
95
102
|
/>
|
|
96
103
|
```
|
|
97
104
|
|
|
98
|
-
- `
|
|
105
|
+
- Each view's `toolbar` can forward the `Toolbar` configuration (`dividerSides`,
|
|
106
|
+
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`) and its `label`,
|
|
107
|
+
`titleSize`, and `headingLevel`. A view value overrides the corresponding
|
|
108
|
+
`toolbarConfig` default. Its `bottomToolbar` forwards the same `Toolbar`
|
|
109
|
+
configuration and has a required accessible `label`.
|
|
110
|
+
- `toolbarConfig` supplies stack-wide defaults (`dividerSides`,
|
|
99
111
|
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`) and adds
|
|
100
112
|
`label` (the toolbar's accessible name), `titleSize` (the title's
|
|
101
113
|
`ToolbarText` size, default `large`), and `headingLevel` (expose the title as
|
package/docs/recipes.md
CHANGED
|
@@ -88,7 +88,11 @@ its label still names the modal — and the close button uses
|
|
|
88
88
|
`data-dialog="close"`. Web Awesome keeps modal focus and Escape, and the thin
|
|
89
89
|
recipe adapter restores the invoking control after the hide event.
|
|
90
90
|
`DialogSurface` chooses the large modal with no body inset, because the panes
|
|
91
|
-
own their geometry.
|
|
91
|
+
own their geometry. Its explicit 16px `viewportGutter` and `maxHeight="viewport"`
|
|
92
|
+
bound the roomy modal to the dynamic viewport; the compact fullscreen
|
|
93
|
+
presentation retains its existing geometry. Application render state chooses
|
|
94
|
+
the presentation and can likewise choose gutter/cap values for a compact modal.
|
|
95
|
+
On compact devices the dialog becomes a full-screen sheet
|
|
92
96
|
with its own labeled header and footer actions, and `SplitView` becomes a
|
|
93
97
|
`NavStack` drill-down whose back control the application pops. The
|
|
94
98
|
application owns open state, selection, the pushed detail, dismissal policy,
|
|
@@ -146,7 +150,7 @@ pushes/pops it, `NavStack` renders it, and `wireNavStack` slides the content and
|
|
|
146
150
|
settles the chrome (reduced motion collapses the slide to instant). See the
|
|
147
151
|
layout guide
|
|
148
152
|
[`app-layouts.md`](app-layouts.md) for choosing among `NavStack`, `SplitView`,
|
|
149
|
-
`Workbench`, and `
|
|
153
|
+
`Workbench`, and `TabNavigator`.
|
|
150
154
|
|
|
151
155
|
## Loading inspector
|
|
152
156
|
|
package/docs/split-view.md
CHANGED
|
@@ -86,15 +86,18 @@ resizable={{
|
|
|
86
86
|
|
|
87
87
|
`compactStack` configures the compact `NavStack`: `toolbarConfig`, `backIcon`,
|
|
88
88
|
`backText`, `hideToolbar`, the persistent `bottomToolbar`, and `chromeDividers`
|
|
89
|
-
forward to the stack, and `list` / `detail` give each view its own
|
|
90
|
-
(`leading`, `center`, trailing
|
|
89
|
+
forward to the stack, and `list` / `detail` give each view its own structured
|
|
90
|
+
top `toolbar` (`leading`, `center`, `trailing`) and `bottomToolbar`:
|
|
91
91
|
|
|
92
92
|
```tsx
|
|
93
93
|
compactStack={{
|
|
94
94
|
backText: "Threads",
|
|
95
95
|
toolbarConfig: { headingLevel: 1 },
|
|
96
|
-
list: { toolbar: <ComposeGroup /> },
|
|
97
|
-
detail: {
|
|
96
|
+
list: { toolbar: { trailing: <ComposeGroup /> } },
|
|
97
|
+
detail: {
|
|
98
|
+
toolbar: { trailing: <ReplyGroup /> },
|
|
99
|
+
bottomToolbar: { label: "Message actions", leading: <MessageActions /> },
|
|
100
|
+
},
|
|
98
101
|
}}
|
|
99
102
|
```
|
|
100
103
|
|
package/docs/surface-scaffold.md
CHANGED
|
@@ -12,6 +12,50 @@ Wrap one `wa-dialog` with `DialogSurface`. Choose `size` (`small`, `medium`, or
|
|
|
12
12
|
`bodyInset` / `footerInset` (`none`, `compact`, or `comfortable`). The defaults
|
|
13
13
|
match Kerf's medium modal, 8px body, and 16px footer rhythm.
|
|
14
14
|
|
|
15
|
+
The modal size presets have preferred widths of 400px, 560px, and 800px,
|
|
16
|
+
respectively, before the viewport width cap. Set `preferredWidth` to a branded
|
|
17
|
+
`CssLength` when the desktop shell needs another width. It takes precedence over
|
|
18
|
+
`size`, while the viewport cap still applies. For example, 832px and 480px
|
|
19
|
+
desktop preferences can share the same responsive dialog without changing its
|
|
20
|
+
resource tracks or preview aspect sizing.
|
|
21
|
+
|
|
22
|
+
### Modal viewport bounds
|
|
23
|
+
|
|
24
|
+
`viewportGutter` accepts a branded `CssLength` from `@kerfjs/ui/css-values`.
|
|
25
|
+
It sets the minimum horizontal clearance; `preferredWidth` overrides the `size`
|
|
26
|
+
preset when supplied. `maxHeight` accepts a branded length or `"viewport"`; explicit caps are
|
|
27
|
+
clamped to the dynamic viewport height minus twice the gutter (16px per edge
|
|
28
|
+
when the gutter is omitted). Negative gutters/caps clamp to zero. Omitting
|
|
29
|
+
both options preserves Web Awesome's existing width and phone height caps.
|
|
30
|
+
These options apply only to `presentation="modal"`; side sheets and fullscreen
|
|
31
|
+
surfaces keep their own geometry.
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
import '@kerfjs/ui/surface-scaffold/register';
|
|
35
|
+
import { remify } from '@kerfjs/ui/css-values';
|
|
36
|
+
import { DialogSurface } from '@kerfjs/ui/surface-scaffold';
|
|
37
|
+
|
|
38
|
+
<DialogSurface preferredWidth={remify(832)} viewportGutter={remify(8)} maxHeight="viewport" bodyInset="none">
|
|
39
|
+
<wa-dialog label="Close workspace">{/* Application-owned content and footer */}</wa-dialog>
|
|
40
|
+
</DialogSurface>;
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This gives a desktop modal an 832px preferred width and a phone modal an 8px edge gutter with a `calc(100dvh - 16px)` height
|
|
44
|
+
cap without application selectors on Kerf roots or Web Awesome parts. A cap
|
|
45
|
+
is not a fixed height: short content stays naturally sized, and taller content
|
|
46
|
+
scrolls in Web Awesome's body while its header/footer remain outside that
|
|
47
|
+
scroll owner. Choosing a larger cap cannot guarantee that arbitrary content
|
|
48
|
+
fits without scrolling; preview tracks, canvas aspect ratios and content sizing
|
|
49
|
+
remain application-owned.
|
|
50
|
+
|
|
51
|
+
Responsive policy is explicit application state: read `deviceClass()` during
|
|
52
|
+
the render to choose the gutter, cap or presentation. For example use
|
|
53
|
+
`viewportGutter={remify(device.value.handset ? 8 : 16)}` with `maxHeight="viewport"`.
|
|
54
|
+
The scaffold introduces no hidden breakpoint or automatic fullscreen switch.
|
|
55
|
+
An application can configure device-class breakpoints when its phone policy
|
|
56
|
+
differs from the default. Prefer a typed cap such as `maxHeight={remify(640)}`
|
|
57
|
+
when the modal should stop growing before the viewport bound.
|
|
58
|
+
|
|
15
59
|
Treat a dialog body as a `List` by default. When its rows or sections own their
|
|
16
60
|
standard list geometry, set `bodyInset="none"` so the dialog does not add a
|
|
17
61
|
second inset. Bare prose is still a list child: wrap it in `ListInsetText` so its
|
|
@@ -26,3 +70,5 @@ padding for a child that already owns row insets, `compact` uses 4px, and
|
|
|
26
70
|
preserve `data-morph-skip-children` when its upgraded light-DOM items must retain
|
|
27
71
|
identity across Kerf rerenders. Import `@kerfjs/ui/popup-menu/register` once for
|
|
28
72
|
the focus handoff fix when wrapping a raw `wa-dropdown`.
|
|
73
|
+
|
|
74
|
+
Import `@kerfjs/ui/surface-scaffold/register` once when using `DialogSurface`: it registers `wa-dialog` and repairs Web Awesome 3.12 native dialog names before the first modal opening. Headed dialogs reference the rendered title, including live slotted labels; headerless dialogs use the public `label`. Explicit host `aria-label` and pre-existing native names are preserved. Geometry-only markup stays CSS-free and does not register Web Awesome implicitly.
|