@kerfjs/ui 5.0.0-beta.71 → 5.0.0-beta.72

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.
@@ -1899,7 +1899,8 @@
1899
1899
  "ToolbarText"
1900
1900
  ],
1901
1901
  "useWhen": [
1902
- "Render toolbar identity or heading text at a supported hierarchy size; pass headingLevel for heading semantics."
1902
+ "Render toolbar identity or heading text at a supported hierarchy size; pass headingLevel for heading semantics.",
1903
+ "Use action for an editable toolbar title: it renders a native button that shrinks and ellipsizes beside sibling status chips."
1903
1904
  ],
1904
1905
  "avoidWhen": [
1905
1906
  "Do not omit headingLevel when the text is the page or section heading.",
@@ -1919,7 +1920,8 @@
1919
1920
  ],
1920
1921
  "appOwns": [
1921
1922
  "text",
1922
- "responsive priority"
1923
+ "responsive priority",
1924
+ "the delegated action handler and display-to-input editing swap"
1923
1925
  ],
1924
1926
  "variants": [
1925
1927
  "xlarge",
@@ -1931,7 +1933,8 @@
1931
1933
  "placeholder (loading)"
1932
1934
  ],
1933
1935
  "accessibility": [
1934
- "Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title."
1936
+ "Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title.",
1937
+ "Actionable text is a native button with its full text as its accessible name; action cannot be combined with headingLevel, placeholder, or wrap."
1935
1938
  ],
1936
1939
  "geometry": {
1937
1940
  "margin": "none",
@@ -1760,6 +1760,11 @@
1760
1760
  "id": "responsive priority",
1761
1761
  "owner": "application",
1762
1762
  "required": false
1763
+ },
1764
+ {
1765
+ "id": "the delegated action handler and display-to-input editing swap",
1766
+ "owner": "application",
1767
+ "required": false
1763
1768
  }
1764
1769
  ],
1765
1770
  "wiring": {
@@ -1775,7 +1780,8 @@
1775
1780
  },
1776
1781
  "accessibility": {
1777
1782
  "obligations": [
1778
- "Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title."
1783
+ "Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title.",
1784
+ "Actionable text is a native button with its full text as its accessible name; action cannot be combined with headingLevel, placeholder, or wrap."
1779
1785
  ]
1780
1786
  },
1781
1787
  "cssValueProps": [],
@@ -9,6 +9,7 @@
9
9
  Extra-large through extra-small toolbar identity text.
10
10
 
11
11
  - Render toolbar identity or heading text at a supported hierarchy size; pass headingLevel for heading semantics.
12
+ - Use action for an editable toolbar title: it renders a native button that shrinks and ellipsizes beside sibling status chips.
12
13
 
13
14
  **Not when:**
14
15
 
@@ -48,7 +49,7 @@ Exact prop names and types: [`@kerfjs/ui/toolbar-text`](../public-api-signatures
48
49
 
49
50
  ## State and wiring
50
51
 
51
- **The app owns:** text; responsive priority.
52
+ **The app owns:** text; responsive priority; the delegated action handler and display-to-input editing swap.
52
53
 
53
54
  No wiring helper.
54
55
 
@@ -59,6 +60,7 @@ Margin: none · border: none · padding: none (layout role: structure). `self` m
59
60
  ## Accessibility
60
61
 
61
62
  - Plain text is not a heading; pass headingLevel to expose role=heading + aria-level for a page/section title.
63
+ - Actionable text is a native button with its full text as its accessible name; action cannot be combined with headingLevel, placeholder, or wrap.
62
64
 
63
65
  ## Styling boundary
64
66
 
@@ -1,6 +1,6 @@
1
1
  # Public API signatures for the UI authoring corpus
2
2
 
3
- Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.71` and `kerfjs@5.0.0-beta.71`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
3
+ Generated from emitted declarations for `@kerfjs/ui@5.0.0-beta.72` and `kerfjs@5.0.0-beta.72`. This bounded reference covers only APIs used by the seven-task corpus. It is interface evidence, not an implementation or runtime guarantee.
4
4
 
5
5
  ## `@kerfjs/ui/css-values`
6
6
 
@@ -222,14 +222,6 @@ interface ToolbarTextBaseProps {
222
222
  className?: string;
223
223
  /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */
224
224
  id?: string;
225
- /**
226
- * Expose heading semantics (`role="heading"` + `aria-level`) so the text acts as
227
- * a heading landmark — e.g. a page's primary title. Omit to keep the plain span
228
- * (the default), which suits a dialog title referenced via `aria-labelledby`.
229
- */
230
- headingLevel?: HeadingLevel;
231
- /** Render the text as an unanimated loading skeleton instead of its value. */
232
- placeholder?: boolean;
233
225
  /**
234
226
  * Show a trailing ellipsis (…) where the text is truncated — on the single line
235
227
  * (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip
@@ -253,8 +245,21 @@ type ToolbarTextWrappingProps = {
253
245
  wrap?: false;
254
246
  maxLines?: never;
255
247
  };
256
- type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;
257
- declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, fill, slot, }: ToolbarTextProps): kerfjs.SafeHtml;
248
+ type ToolbarTextProps = ToolbarTextBaseProps & (({
249
+ action?: never;
250
+ /** Expose `role="heading"` and `aria-level` on read-only text. */
251
+ headingLevel?: HeadingLevel;
252
+ /** Render an unanimated loading skeleton instead of the text. */
253
+ placeholder?: boolean;
254
+ } & ToolbarTextWrappingProps) | {
255
+ /** Render a native button with this delegated action; the app owns editing. */
256
+ action: string;
257
+ headingLevel?: never;
258
+ placeholder?: never;
259
+ wrap?: never;
260
+ maxLines?: never;
261
+ });
262
+ declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, fill, slot, action, }: ToolbarTextProps): kerfjs.SafeHtml;
258
263
 
259
264
  export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
260
265
  ```
@@ -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.71` 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.
3
+ Generated from the emitted `@kerfjs/ui@5.0.0-beta.72` 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/dist/catalog.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Workbench } from './chunk-KCCEH7RF.js';
1
+ import { Workbench } from './chunk-3UE24JSC.js';
2
2
 
3
3
 
4
4
  import { PopupMenu } from './chunk-J3KGJ6P6.js';
@@ -8,7 +8,7 @@ import { ListHeader } from './chunk-M6DEEBEF.js';
8
8
  import { Text } from './chunk-YDGNU2OD.js';
9
9
  import { ListInsetText } from './chunk-DG6G5EPF.js';
10
10
  import { ListItem } from './chunk-NC4CFOID.js';
11
- import { ToolbarText } from './chunk-V3DX3K65.js';
11
+ import { ToolbarText } from './chunk-R5F5XUJ7.js';
12
12
 
13
13
 
14
14
 
@@ -1,5 +1,5 @@
1
1
  import { WORKBENCH_MAIN_MIN_SIZE, WORKBENCH_MAIN_MIN_HEIGHT, workbenchRegionId, WORKBENCH_RESIZE_DEFAULTS } from './chunk-PSHUSWQH.js';
2
- import { NavStack } from './chunk-DC6CN2DS.js';
2
+ import { NavStack } from './chunk-VLYIPBCQ.js';
3
3
  import { clampRegionSize, ResizeGrip } from './chunk-KLJKU6ZL.js';
4
4
  import { FloatingToolbar } from './chunk-I3Q7KKYM.js';
5
5
  import { panelToggleGroup, composedPanelBody, relocatedPanelGroups } from './chunk-RNQNEENY.js';
@@ -489,4 +489,4 @@ function Workbench({
489
489
 
490
490
  export { Workbench };
491
491
 
492
- //# sourceMappingURL=chunk-KCCEH7RF.js.map
492
+ //# sourceMappingURL=chunk-3UE24JSC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/workbench-toolbars.tsx","../src/workbench.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-KCCEH7RF.js","sourcesContent":["import {\n FloatingToolbar,\n type FloatingToolbarPosition,\n} from './floating-toolbar.js';\nimport { List, type ListConfig } from './list.js';\nimport { NavStack, type NavStackProps } from './nav-stack.js';\nimport { Pane, type PaneConfig } from './pane.js';\nimport {\n composedPanelBody,\n type PanelBottomToolbar,\n type PanelChromePlacement,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n panelToggleGroup,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport {\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\n\n/** The standard toggle a Workbench renders for a panel (see {@link PanelToggle}). */\nexport type WorkbenchPanelToggle = PanelToggle;\n\n/**\n * A Workbench panel's top toolbar, composed by the Workbench so its groups can\n * follow the panel's open state (see {@link PanelToolbar} for the roles).\n * A collapsed rail's marked groups and toggle go to the leading edge of\n * `mainToolbar` (left rail) or its trailing edge (right rail); a collapsed\n * drawer's go to the trailing edge of `mainBottomToolbar`, else to a\n * `FloatingToolbar` in the work area's bottom-end corner.\n */\nexport type WorkbenchPanelToolbar = PanelToolbar;\nexport type WorkbenchPanelBottomToolbar = PanelBottomToolbar;\n\n/**\n * The work area's top toolbar; collapsed rails add their groups to it. Its\n * configuration forwards to its `Toolbar`. It draws no divider of its own by\n * default: the work area's `Pane` draws one under its header chrome, wherever\n * that chrome ends, while `main` is scrolled (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainToolbar extends ToolbarConfig {\n label: string;\n /** The work area's title, usually an extra-large `ToolbarText`. */\n title?: KerfUiContent;\n /** Groups after the title. */\n leading?: KerfUiContent;\n center?: KerfUiContent;\n /** Groups at the trailing edge, before a collapsed right rail's groups. */\n trailing?: KerfUiContent;\n}\n\n/**\n * The work area's bottom toolbar; a collapsed drawer adds its groups to it.\n * Its configuration forwards to its `Toolbar`. It draws no divider of its own\n * by default: the work area's `Pane` draws one over its footer chrome while\n * more of `main` lies below (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainBottomToolbar extends ToolbarConfig {\n label: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\nconst SIDES: Record<WorkbenchPanelKey, PanelSide> = {\n leftRail: 'left',\n rightRail: 'right',\n bottomDrawer: 'bottom',\n};\n\n/** A panel as far as its toolbar is concerned. */\nexport interface WorkbenchToolbarPanel {\n toolbar?: WorkbenchPanelToolbar;\n navStack?: Omit<\n NavStackProps,\n 'panelToggle' | 'hideToolbar' | 'className' | 'slot'\n >;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: PanelChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: WorkbenchPanelBottomToolbar;\n footerPlacement?: PanelChromePlacement;\n /** Configuration for the `Pane` a `toolbar` panel's content renders in. */\n pane?: PaneConfig;\n content?: KerfUiContent;\n collapsed?: boolean;\n /** The corner a collapsed panel's restore controls float in. */\n restorePosition?: FloatingToolbarPosition;\n}\n\n/** A Workbench toggle's wiring hooks: its side, morph key, and panel. */\nconst toggleAttributes = (\n workbenchId: string,\n key: WorkbenchPanelKey,\n): PanelToggleAttributes => ({\n 'data-workbench-toggle': SIDES[key],\n // Keyed, so the morph removes a toggle that leaves a toolbar instead of\n // reusing its (possibly focused) button for a different control.\n 'data-key': `${workbenchRegionId(workbenchId, key)}-toggle`,\n 'aria-controls': workbenchRegionId(workbenchId, key),\n});\n\n/**\n * The groups a collapsed panel hands to the work area: its marked groups,\n * then its toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedGroups(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n): KerfUiContent[] {\n const active = panel?.navStack?.views.at(-1);\n const toolbar =\n active && panel?.toolbar\n ? {\n ...panel.toolbar,\n leading: active.leading,\n center: active.center,\n trailing: active.toolbar,\n }\n : panel?.toolbar;\n return relocatedPanelGroups(\n toolbar,\n SIDES[key],\n Boolean(panel?.collapsed),\n toggleAttributes(workbenchId, key),\n );\n}\n\n/**\n * A panel's content, wrapped in a `Pane` under its composed toolbar when it\n * has one (with its optional `footer` below). Without a toolbar the content\n * renders as given.\n */\nexport function panelBody(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel,\n) {\n const toolbar = panel.toolbar;\n if (panel.navStack) {\n const stack = panel.navStack;\n return NavStack({\n ...stack,\n toolbarConfig: {\n label: stack.toolbarConfig?.label ?? toolbar?.label,\n dividerSides:\n stack.toolbarConfig?.dividerSides ?? toolbar?.dividerSides,\n centerAlign: stack.toolbarConfig?.centerAlign ?? toolbar?.centerAlign,\n responsive: stack.toolbarConfig?.responsive ?? toolbar?.responsive,\n responsiveAt:\n stack.toolbarConfig?.responsiveAt ?? toolbar?.responsiveAt,\n safeAreaEdges:\n stack.toolbarConfig?.safeAreaEdges ?? toolbar?.safeAreaEdges,\n titleSize: stack.toolbarConfig?.titleSize,\n headingLevel: stack.toolbarConfig?.headingLevel,\n },\n panelToggle: toolbar?.toggle\n ? panelToggleGroup(\n SIDES[key],\n toolbar.toggle,\n Boolean(panel.collapsed),\n toggleAttributes(workbenchId, key),\n )\n : undefined,\n });\n }\n if (!toolbar) return panel.content;\n return composedPanelBody({\n toolbar,\n side: SIDES[key],\n collapsed: Boolean(panel.collapsed),\n attributes: toggleAttributes(workbenchId, key),\n pane: panel.pane,\n header: panel.header,\n headerList: panel.headerList,\n headerPlacement: panel.headerPlacement,\n footer: panel.footer,\n footerList: panel.footerList,\n bottomToolbar: panel.bottomToolbar,\n footerPlacement: panel.footerPlacement,\n content: panel.content ?? null,\n });\n}\n\n/**\n * The work area's `mainHeader` / `mainFooter` chrome in a `List` carrying the\n * app's configuration; an omitted or `undefined` field keeps the `List`\n * default (no divider: the work area's `Pane` draws its chrome dividers).\n */\nfunction chromeList(content: KerfUiContent, config: ListConfig | undefined) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/**\n * Whether the work area's header or footer chrome stays pinned (`fixed`),\n * scrolls away with the content (`scroll`), or stays pinned while the work\n * area is tall enough and scrolls with the content when it is short (`auto`,\n * the Pane's `chromePlacement=\"auto\"`; it applies to the pinned header and\n * footer together).\n */\nexport type WorkbenchChromePlacement = PanelChromePlacement;\n\n/**\n * The work area: the app's `main` in a `Pane` (configured by `mainPane`)\n * under `mainToolbar` and any `mainHeader` list, and above any `mainFooter`\n * list and `mainBottomToolbar` (the header and footer lists configured by\n * `mainHeaderList` / `mainFooterList`), with each collapsed panel's groups\n * added to the toolbar on its side. Without any of that chrome, `main`\n * renders as given; only `mainPane.appearance` applies to the Workbench's\n * own scroll region in that case.\n */\nexport function mainBody({\n workbenchId,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement = 'fixed',\n mainFooterPlacement = 'fixed',\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n}: {\n workbenchId: string;\n main: KerfUiContent;\n mainToolbar?: WorkbenchMainToolbar;\n mainHeader?: KerfUiContent;\n mainFooter?: KerfUiContent;\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n mainHeaderPlacement?: WorkbenchChromePlacement;\n mainFooterPlacement?: WorkbenchChromePlacement;\n mainPane?: PaneConfig;\n mainHeaderList?: ListConfig;\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchToolbarPanel;\n rightRail?: WorkbenchToolbarPanel;\n bottomDrawer?: WorkbenchToolbarPanel;\n}) {\n if (!mainToolbar && !mainBottomToolbar && !mainHeader && !mainFooter)\n return main;\n const left = relocatedGroups(workbenchId, 'leftRail', leftRail);\n const right = relocatedGroups(workbenchId, 'rightRail', rightRail);\n const drawer = mainBottomToolbar\n ? relocatedGroups(workbenchId, 'bottomDrawer', bottomDrawer)\n : [];\n // The Pane draws one divider under the header chrome and one over the\n // footer chrome, wherever that chrome ends, from the scroll state.\n const header =\n !mainToolbar && !mainHeader ? undefined : (\n <>\n {mainToolbar ? (\n <Toolbar\n label={mainToolbar.label}\n dividerSides={mainToolbar.dividerSides}\n centerAlign={mainToolbar.centerAlign}\n responsive={mainToolbar.responsive}\n responsiveAt={mainToolbar.responsiveAt}\n safeAreaEdges={mainToolbar.safeAreaEdges}\n leading={\n <>\n {left}\n {mainToolbar.title}\n {mainToolbar.leading}\n </>\n }\n center={mainToolbar.center}\n trailing={\n <>\n {mainToolbar.trailing}\n {right}\n </>\n }\n />\n ) : null}\n {mainHeader ? chromeList(mainHeader, mainHeaderList) : null}\n </>\n );\n const footer =\n !mainFooter && !mainBottomToolbar ? undefined : (\n <>\n {mainFooter ? chromeList(mainFooter, mainFooterList) : null}\n {mainBottomToolbar ? (\n <Toolbar\n position=\"footer\"\n label={mainBottomToolbar.label}\n dividerSides={mainBottomToolbar.dividerSides}\n centerAlign={mainBottomToolbar.centerAlign}\n responsive={mainBottomToolbar.responsive}\n responsiveAt={mainBottomToolbar.responsiveAt}\n safeAreaEdges={mainBottomToolbar.safeAreaEdges}\n leading={mainBottomToolbar.leading}\n center={mainBottomToolbar.center}\n trailing={\n <>\n {mainBottomToolbar.trailing}\n {drawer}\n </>\n }\n />\n ) : null}\n </>\n );\n const scrollHeader = mainHeaderPlacement === 'scroll';\n const scrollFooter = mainFooterPlacement === 'scroll';\n return (\n <Pane\n header={scrollHeader ? undefined : header}\n footer={scrollFooter ? undefined : footer}\n chromePlacement={\n mainHeaderPlacement === 'auto' || mainFooterPlacement === 'auto'\n ? 'auto'\n : 'fixed'\n }\n contentElement={mainPane?.contentElement}\n contentLabel={mainPane?.contentLabel}\n separators={mainPane?.separators}\n safeAreaEdges={mainPane?.safeAreaEdges}\n chromeDividers={mainPane?.chromeDividers}\n appearance={mainPane?.appearance}\n >\n {scrollHeader || scrollFooter ? (\n // Chrome that scrolls joins the content in one gapless column that\n // fills the scroller, so it scrolls away with the content.\n <List flex>\n {scrollHeader ? header : null}\n {main}\n {scrollFooter ? footer : null}\n </List>\n ) : (\n main\n )}\n </Pane>\n );\n}\n\n/**\n * A collapsed panel's groups when the work area has no toolbar on its side\n * to take them: a `FloatingToolbar` for the panel's restore corner, so the\n * panel can always be reopened.\n */\nexport function floatingRestore(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n hasTargetToolbar: boolean,\n) {\n if (hasTargetToolbar) return undefined;\n const groups = relocatedGroups(workbenchId, key, panel);\n if (groups.length === 0) return undefined;\n return (\n <FloatingToolbar\n label={panel!.toolbar!.label}\n position={\n panel!.restorePosition ??\n (key === 'leftRail' ? 'bottom-start' : 'bottom-end')\n }\n >\n {groups}\n </FloatingToolbar>\n );\n}\n","import type { SafeHtml } from 'kerfjs';\n\nimport type { ListConfig } from './list.js';\nimport type { NavStackProps } from './nav-stack.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n clampRegionSize,\n type ResizableRegionAxis,\n type ResizableRegionCollapseMotion,\n type ResizableRegionContentOverflow,\n type ResizableRegionEdge,\n type ResizableRegionPresentation,\n type ResizableRegionRestorePosition,\n type ResizableRegionSeparator,\n} from './resizable-region.js';\nimport { ResizeGrip } from './resize-grip.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport {\n WORKBENCH_MAIN_MIN_HEIGHT,\n WORKBENCH_MAIN_MIN_SIZE,\n WORKBENCH_RESIZE_DEFAULTS,\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\nimport {\n floatingRestore,\n mainBody,\n panelBody,\n type WorkbenchChromePlacement,\n type WorkbenchMainBottomToolbar,\n type WorkbenchMainToolbar,\n type WorkbenchPanelBottomToolbar,\n type WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\nexport type {\n WorkbenchChromePlacement,\n WorkbenchMainBottomToolbar,\n WorkbenchMainToolbar,\n WorkbenchPanelBottomToolbar,\n WorkbenchPanelToggle,\n WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\n/**\n * The Workbench container breakpoint below which a panel presents as an\n * overlay: `narrow` (704px or less) or `compact` (448px or less) — the same\n * breakpoints as `ResizableRegion`'s `responsiveFillAt` — or `never` to keep\n * it inline at every width.\n */\nexport type WorkbenchResponsiveOverlayAt =\n 'compact' | 'narrow' | 'never' | number;\n\n/**\n * How wide a rail's overlay is in a compact (448px or less) Workbench: `inset`\n * fills the Workbench less a dismiss margin on the side away from the rail's\n * edge, so a press beside it closes it; `full` fills the Workbench.\n */\nexport type WorkbenchCompactOverlay = 'inset' | 'full';\n\n/** Drag-resize limits for a resizable Workbench panel, in px. */\nexport interface WorkbenchPanelResizable {\n /** Smallest size (default 180 for a rail, 120 for the drawer). */\n min?: number;\n /** Largest size (default 480). */\n max?: number;\n}\n\n/** Region sizing, collapse, and presentation shared by either panel body. */\ninterface WorkbenchPanelBase {\n /** Whether the panel is currently collapsed (the app owns this). */\n collapsed?: boolean;\n /**\n * Rail width, or drawer height, in px. Overrides the CSS default. For a\n * resizable panel it is the current size (default 280 for a rail, 220 for\n * the drawer), clamped to the limits; the app owns it and `wireWorkbench`\n * reports each resize.\n */\n size?: number;\n /**\n * Opt in to drag and keyboard resizing on the panel's inner separator:\n * `true` for the default limits, or `{ min, max }`. Off by default. Pair it\n * with `wireWorkbench` from `@kerfjs/ui/wire-workbench`.\n */\n resizable?: boolean | WorkbenchPanelResizable;\n /** Accessible name for the panel region. */\n label?: string;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /**\n * Present the panel as an overlay, without a separator, below a Workbench\n * container breakpoint, and inline above it. `compact` and `narrow` use\n * CSS container queries; a positive number is a pixel threshold measured\n * by `wireWorkbench` and requires a `collapsed` signal. A rail overlays from its side at full\n * height, over the work area and an open drawer; the bottom drawer\n * overlays the bottom of the work-area column. Rails default to `narrow`\n * (pass `never` to keep one inline); the drawer defaults to inline.\n */\n responsiveOverlayAt?: WorkbenchResponsiveOverlayAt;\n /**\n * A rail's overlay width in a compact Workbench (default `inset`: the\n * Workbench less `--kui-workbench-overlay-dismiss-margin`, 44px). Ignored\n * by the drawer.\n */\n compactOverlay?: WorkbenchCompactOverlay;\n /**\n * Control shown while collapsed, in a safe-area-aware corner of the\n * Workbench (not the viewport); the bottom drawer's sits in the work-area\n * column. Prefer `toolbar.toggle`, which the Workbench relocates into the\n * work area's toolbar (or this corner when that toolbar is absent).\n */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n}\n\n/** The original static panel body: one toolbar, optional fixed chrome, and one Pane. */\nexport interface WorkbenchStaticPanel extends WorkbenchPanelBase {\n content: KerfUiContent;\n /** The composed toolbar; marked groups and its toggle relocate on collapse. */\n toolbar?: WorkbenchPanelToolbar;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: WorkbenchChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: WorkbenchPanelBottomToolbar;\n footerPlacement?: WorkbenchChromePlacement;\n /** Configuration for the static toolbar panel's Pane. */\n pane?: PaneConfig;\n navStack?: never;\n}\n\n/** A panel whose active NavStack view supplies the toolbar, fixed header, and scroll body. */\nexport interface WorkbenchNavigationPanel extends WorkbenchPanelBase {\n navStack: Omit<\n NavStackProps,\n 'panelToggle' | 'hideToolbar' | 'className' | 'slot'\n >;\n /** Supplies the standard toggle; active view groups precede it and may relocate on collapse. */\n toolbar: Omit<\n WorkbenchPanelToolbar,\n 'title' | 'leading' | 'center' | 'trailing'\n > & {\n toggle: NonNullable<WorkbenchPanelToolbar['toggle']>;\n };\n content?: never;\n header?: never;\n headerList?: never;\n headerPlacement?: never;\n footer?: never;\n footerList?: never;\n bottomToolbar?: never;\n footerPlacement?: never;\n pane?: never;\n}\n\n/** A collapsible Workbench side rail or bottom drawer. */\nexport type WorkbenchPanel = WorkbenchStaticPanel | WorkbenchNavigationPanel;\n\nexport interface WorkbenchProps {\n /**\n * The Workbench's `id`. Each panel's `id` derives from it —\n * `<id>-left-rail`, `<id>-right-rail`, `<id>-bottom-drawer` — so a toggle\n * can name the panel it shows and hides with `aria-controls`.\n */\n id: string;\n label: string;\n /** The central work area. */\n main: KerfUiContent;\n /**\n * The work area's top toolbar. A collapsed left rail's marked groups\n * and toggle lead it; a collapsed right rail's trail it. With it, `main`\n * renders in a `Pane` below the toolbar.\n */\n mainToolbar?: WorkbenchMainToolbar;\n /**\n * Fixed content under `mainToolbar` — supporting copy such as a\n * description — divided from the scrolling `main` below it.\n */\n mainHeader?: KerfUiContent;\n /**\n * Fixed content over `mainBottomToolbar` — a status line or a resource\n * toolbar — divided from the scrolling `main` above it.\n */\n mainFooter?: KerfUiContent;\n /**\n * The work area's bottom toolbar. A collapsed drawer's marked groups and\n * toggle trail it; without it they float in the work area's corner.\n */\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n /**\n * Whether `mainToolbar` and `mainHeader` stay pinned (`fixed`, default),\n * scroll away with `main` (`scroll`) — useful where large text would leave\n * pinned chrome little room — or stay pinned while the work area is tall\n * enough and scroll with `main` when it is short (`auto`).\n */\n mainHeaderPlacement?: WorkbenchChromePlacement;\n /** The same for `mainFooter` and `mainBottomToolbar` (default `fixed`). */\n mainFooterPlacement?: WorkbenchChromePlacement;\n /**\n * Configuration for the work area's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`), which it has whenever it\n * has a toolbar, `mainHeader`, or `mainFooter`; without that chrome, `main`\n * renders as given and this is ignored. Omitted or `undefined` fields keep\n * the `Pane` defaults.\n */\n mainPane?: PaneConfig;\n /**\n * Configuration for the `List` that holds `mainHeader` (`gap`, `hAlign`,\n * `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Omitted or\n * `undefined` fields keep the defaults (no divider: the work area's\n * `Pane` draws the line under its header chrome).\n */\n mainHeaderList?: ListConfig;\n /**\n * The same for the `List` that holds `mainFooter` (no divider by default:\n * the work area's `Pane` draws the line over its footer chrome).\n */\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchPanel;\n rightRail?: WorkbenchPanel;\n bottomDrawer?: WorkbenchPanel;\n /**\n * Minimum width, in px, the work area keeps beside the inline rails, fixed\n * or `resizable` (default 320; `0` turns it off). Resizing a rail stops\n * where the work area would drop below it, and inline rails shrink\n * proportionally when the Workbench gets narrower. Workbenches without a\n * rail ignore it.\n */\n mainMinSize?: number;\n /**\n * Minimum height, in px, the work area keeps above an inline bottom drawer,\n * fixed or `resizable` (default 120; `0` turns it off) — the drawer's\n * counterpart of `mainMinSize`. Resizing the drawer stops where the work\n * area would drop below it, and the drawer shrinks when the Workbench gets\n * shorter. Workbenches without a drawer ignore it.\n */\n mainMinHeight?: number;\n /** Dim the work area below any open overlay and absorb outside presses; off by default. */\n overlayBackdrop?: boolean;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ninterface ResolvedResize {\n regionId: string;\n axis: ResizableRegionAxis;\n edge: ResizableRegionEdge;\n size: number;\n min: number;\n max: number;\n}\n\n/**\n * Each panel's separator is its inner edge. Growing the left rail moves that\n * edge toward the inline end; growing the right rail or the drawer moves it\n * toward the start — the same edge vocabulary `ResizableRegion` uses.\n */\nconst EDGES: Record<WorkbenchPanelKey, ResizableRegionEdge> = {\n leftRail: 'end',\n rightRail: 'start',\n bottomDrawer: 'start',\n};\n\nconst DEFAULT_LABELS: Record<WorkbenchPanelKey, string> = {\n leftRail: 'left rail',\n rightRail: 'right rail',\n bottomDrawer: 'bottom drawer',\n};\n\nfunction resolveResize(\n id: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchPanel,\n): ResolvedResize | undefined {\n if (!panel.resizable) return undefined;\n const defaults = WORKBENCH_RESIZE_DEFAULTS[key];\n const limits = panel.resizable === true ? {} : panel.resizable;\n const min = limits.min ?? defaults.min;\n const max = Math.max(min, limits.max ?? defaults.max);\n return {\n regionId: workbenchRegionId(id, key),\n axis: key === 'bottomDrawer' ? 'vertical' : 'horizontal',\n edge: EDGES[key],\n size: clampRegionSize(panel.size ?? defaults.size, min, max),\n min,\n max,\n };\n}\n\n/** The attributes a resizable panel adds for the resize wiring to read. */\nconst resizeAttributes = (resize: ResolvedResize | undefined) =>\n resize\n ? {\n 'data-resizable': 'true',\n 'data-region-id': resize.regionId,\n 'data-axis': resize.axis,\n 'data-edge': resize.edge,\n }\n : {};\n\n/**\n * A resizable panel's size lives in the resize wiring's track property, so a\n * drag or key press resizes the panel before the app re-renders; the CSS maps\n * it onto the rail width or drawer height.\n */\nfunction panelStyle(\n panel: WorkbenchPanel,\n resize: ResolvedResize | undefined,\n sizeProperty: string,\n) {\n if (resize) return `--kui-resizable-region-size:${resize.size}px`;\n return panel.size ? `${sizeProperty}: ${panel.size}px` : undefined;\n}\n\n/**\n * The separator a resizable panel owns: the same focusable `role=\"separator\"`\n * contract a `ResizableRegion` handle carries, so one resize wiring drives\n * both. It leaves the tab order while the panel is collapsed or not inline.\n */\nfunction PanelHandle({\n panel,\n resize,\n label,\n}: {\n panel: WorkbenchPanel;\n resize: ResolvedResize;\n label: string;\n}) {\n const inert =\n Boolean(panel.collapsed) || (panel.presentation ?? 'inline') !== 'inline';\n return (\n <div\n class=\"kui-workbench__handle\"\n role=\"separator\"\n tabindex={inert ? '-1' : '0'}\n aria-label={`Resize ${label}`}\n aria-orientation={\n resize.axis === 'horizontal' ? 'vertical' : 'horizontal'\n }\n aria-valuemin={resize.min}\n aria-valuemax={resize.max}\n aria-valuenow={resize.size}\n aria-hidden={inert ? 'true' : undefined}\n data-kui-resize-handle\n data-region-id={resize.regionId}\n >\n <span class=\"kui-workbench__handle-icon\" aria-hidden=\"true\">\n <ResizeGrip axis={resize.axis} />\n </span>\n </div>\n );\n}\n\n/**\n * A collapsed panel leaves the accessibility tree as a whole, like a collapsed\n * `CollapsiblePanel`: its content and separator are already inert or hidden,\n * so the labeled landmark would otherwise stay behind, empty, for a screen\n * reader to land on. Its restore control renders outside it and stays\n * reachable.\n */\nfunction hiddenFromAccessibility(panel: WorkbenchPanel) {\n return panel.collapsed || panel.presentation === 'hidden'\n ? ('true' as const)\n : undefined;\n}\n\n/** A breakpoint's attribute value; `never` (or none) renders no attribute. */\nconst responsiveAt = (at: WorkbenchResponsiveOverlayAt | undefined) =>\n at === 'never' ? undefined : at;\n\nconst inline = (panel: WorkbenchPanel | undefined) =>\n Boolean(panel && (panel.presentation ?? 'inline') === 'inline');\n\nconst expanded = (panel: WorkbenchPanel | undefined) =>\n Boolean(panel && !panel.collapsed);\n\nconst responsiveRail = (panel: WorkbenchPanel | undefined) =>\n panel ? responsiveAt(panel.responsiveOverlayAt ?? 'narrow') : undefined;\n\nconst responsiveDrawer = (panel: WorkbenchPanel | undefined) =>\n panel ? responsiveAt(panel.responsiveOverlayAt) : undefined;\n\nfunction Rail({\n id,\n side,\n panel,\n}: {\n id: string;\n side: 'left' | 'right';\n panel: WorkbenchPanel;\n}) {\n const key: WorkbenchPanelKey = side === 'left' ? 'leftRail' : 'rightRail';\n const resize = resolveResize(id, key, panel);\n return (\n <aside\n id={workbenchRegionId(id, key)}\n class={`kui-workbench__rail kui-workbench__rail--${side}`}\n data-workbench-rail={side}\n data-appearance={\n !panel.toolbar && panel.pane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(\n panel.responsiveOverlayAt ?? 'narrow',\n )}\n data-compact-overlay={panel.compactOverlay ?? 'inset'}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-rail-width')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, key, panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS[key]}\n />\n )}\n </aside>\n );\n}\n\nfunction Drawer({ id, panel }: { id: string; panel: WorkbenchPanel }) {\n const resize = resolveResize(id, 'bottomDrawer', panel);\n return (\n <section\n id={workbenchRegionId(id, 'bottomDrawer')}\n class=\"kui-workbench__drawer\"\n data-workbench-drawer\n data-appearance={\n !panel.toolbar && panel.pane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(panel.responsiveOverlayAt)}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-drawer-height')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, 'bottomDrawer', panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS.bottomDrawer}\n />\n )}\n </section>\n );\n}\n\n/** A collapsed panel's restore control, outside the clipped panel. */\nfunction restore(\n panel: WorkbenchPanel | undefined,\n side: 'left' | 'right' | 'bottom',\n position: ResizableRegionRestorePosition,\n generated: SafeHtml | undefined,\n) {\n const control = panel?.restoreControl ?? generated;\n if (!panel?.collapsed || !control || panel.presentation === 'hidden')\n return '';\n return (\n <div\n class=\"kui-workbench__restore\"\n data-panel={side}\n data-position={panel.restorePosition ?? position}\n >\n {control}\n </div>\n );\n}\n\n/**\n * The Xcode-like multi-panel workspace: a collapsible left rail, right rail, and\n * bottom drawer around a central work area (any absent). Collapsing snaps the\n * panel's track to zero in one reflow while its fixed-size content slides out via\n * a composited transform — the instant-width / sliding-content technique, so the\n * work area relayouts once, not per frame. Bottom-drawer content stays anchored\n * to the shell's stable bottom edge throughout that transition. The app owns\n * each `collapsed` flag; the collapse is pure CSS. A collapsed panel renders\n * `inert` and `aria-hidden`, so neither Tab nor assistive technology reaches\n * controls that have slid out of view or an empty landmark (its restore control\n * lives outside it and stays reachable). A panel may opt in to drag and keyboard resizing with\n * `resizable`, which `wireWorkbench` drives. See `docs/23-app-layouts.md` §3.3.\n */\nexport function Workbench({\n id,\n label,\n main,\n leftRail,\n rightRail,\n bottomDrawer,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n mainMinSize = WORKBENCH_MAIN_MIN_SIZE,\n mainMinHeight = WORKBENCH_MAIN_MIN_HEIGHT,\n overlayBackdrop = false,\n className = '',\n slot,\n}: WorkbenchProps) {\n // Each work-area minimum applies only on an axis a panel shares with it:\n // the width beside a rail, the height above the drawer.\n const px = (value: number) => Math.max(0, Math.round(value));\n const mainMin = leftRail || rightRail ? px(mainMinSize) : undefined;\n const mainMinBlock = bottomDrawer ? px(mainMinHeight) : undefined;\n const style = [\n mainMin === undefined ? '' : `--_kui-workbench-main-min-width:${mainMin}px`,\n mainMinBlock === undefined\n ? ''\n : `--_kui-workbench-main-min-height:${mainMinBlock}px`,\n ]\n .filter(Boolean)\n .join(';');\n return (\n <section\n class={`kui-workbench ${className}`.trim()}\n id={id}\n data-component=\"workbench\"\n data-main-min-size={mainMin === undefined ? undefined : String(mainMin)}\n data-main-min-height={\n mainMinBlock === undefined ? undefined : String(mainMinBlock)\n }\n data-left-inline-expanded={\n inline(leftRail) && expanded(leftRail) ? 'true' : undefined\n }\n data-right-inline-expanded={\n inline(rightRail) && expanded(rightRail) ? 'true' : undefined\n }\n data-left-responsive-inline={\n inline(leftRail) ? responsiveRail(leftRail) : undefined\n }\n data-right-responsive-inline={\n inline(rightRail) ? responsiveRail(rightRail) : undefined\n }\n data-left-responsive-expanded={\n inline(leftRail) && expanded(leftRail)\n ? responsiveRail(leftRail)\n : undefined\n }\n data-right-responsive-expanded={\n inline(rightRail) && expanded(rightRail)\n ? responsiveRail(rightRail)\n : undefined\n }\n data-rail-overlay-expanded={\n (leftRail?.presentation === 'overlay' && expanded(leftRail)) ||\n (rightRail?.presentation === 'overlay' && expanded(rightRail))\n ? 'true'\n : undefined\n }\n data-drawer-overlay-expanded={\n bottomDrawer?.presentation === 'overlay' && expanded(bottomDrawer)\n ? 'true'\n : undefined\n }\n data-drawer-responsive-expanded={\n inline(bottomDrawer) && expanded(bottomDrawer)\n ? responsiveDrawer(bottomDrawer)\n : undefined\n }\n data-overlay-backdrop={overlayBackdrop ? 'true' : undefined}\n data-responsive-overlay={\n responsiveRail(leftRail) ||\n responsiveRail(rightRail) ||\n responsiveDrawer(bottomDrawer)\n ? 'true'\n : undefined\n }\n style={style || undefined}\n aria-label={label}\n slot={slot}\n >\n {leftRail && <Rail id={id} side=\"left\" panel={leftRail} />}\n {restore(\n leftRail,\n 'left',\n 'bottom-start',\n floatingRestore(id, 'leftRail', leftRail, Boolean(mainToolbar)),\n )}\n <div class=\"kui-workbench__center\">\n <div\n class=\"kui-workbench__main\"\n data-workbench-main\n data-drawer-inline-expanded={\n inline(bottomDrawer) && expanded(bottomDrawer) ? 'true' : undefined\n }\n data-drawer-responsive-inline={\n inline(bottomDrawer) ? responsiveDrawer(bottomDrawer) : undefined\n }\n data-appearance={\n !mainToolbar &&\n !mainBottomToolbar &&\n !mainHeader &&\n !mainFooter &&\n mainPane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n >\n {mainBody({\n workbenchId: id,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n })}\n </div>\n {bottomDrawer && <Drawer id={id} panel={bottomDrawer} />}\n {restore(\n bottomDrawer,\n 'bottom',\n 'bottom-end',\n floatingRestore(\n id,\n 'bottomDrawer',\n bottomDrawer,\n Boolean(mainBottomToolbar),\n ),\n )}\n </div>\n {rightRail && <Rail id={id} side=\"right\" panel={rightRail} />}\n {restore(\n rightRail,\n 'right',\n 'bottom-end',\n floatingRestore(id, 'rightRail', rightRail, Boolean(mainToolbar)),\n )}\n {overlayBackdrop ? (\n <div\n class=\"kui-workbench__backdrop\"\n data-workbench-backdrop\n aria-hidden=\"true\"\n />\n ) : null}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/workbench-toolbars.tsx","../src/workbench.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-3UE24JSC.js","sourcesContent":["import {\n FloatingToolbar,\n type FloatingToolbarPosition,\n} from './floating-toolbar.js';\nimport { List, type ListConfig } from './list.js';\nimport { NavStack, type NavStackProps } from './nav-stack.js';\nimport { Pane, type PaneConfig } from './pane.js';\nimport {\n composedPanelBody,\n type PanelBottomToolbar,\n type PanelChromePlacement,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n panelToggleGroup,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport {\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\n\n/** The standard toggle a Workbench renders for a panel (see {@link PanelToggle}). */\nexport type WorkbenchPanelToggle = PanelToggle;\n\n/**\n * A Workbench panel's top toolbar, composed by the Workbench so its groups can\n * follow the panel's open state (see {@link PanelToolbar} for the roles).\n * A collapsed rail's marked groups and toggle go to the leading edge of\n * `mainToolbar` (left rail) or its trailing edge (right rail); a collapsed\n * drawer's go to the trailing edge of `mainBottomToolbar`, else to a\n * `FloatingToolbar` in the work area's bottom-end corner.\n */\nexport type WorkbenchPanelToolbar = PanelToolbar;\nexport type WorkbenchPanelBottomToolbar = PanelBottomToolbar;\n\n/**\n * The work area's top toolbar; collapsed rails add their groups to it. Its\n * configuration forwards to its `Toolbar`. It draws no divider of its own by\n * default: the work area's `Pane` draws one under its header chrome, wherever\n * that chrome ends, while `main` is scrolled (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainToolbar extends ToolbarConfig {\n label: string;\n /** The work area's title, usually an extra-large `ToolbarText`. */\n title?: KerfUiContent;\n /** Groups after the title. */\n leading?: KerfUiContent;\n center?: KerfUiContent;\n /** Groups at the trailing edge, before a collapsed right rail's groups. */\n trailing?: KerfUiContent;\n}\n\n/**\n * The work area's bottom toolbar; a collapsed drawer adds its groups to it.\n * Its configuration forwards to its `Toolbar`. It draws no divider of its own\n * by default: the work area's `Pane` draws one over its footer chrome while\n * more of `main` lies below (`mainPane.chromeDividers`).\n */\nexport interface WorkbenchMainBottomToolbar extends ToolbarConfig {\n label: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\nconst SIDES: Record<WorkbenchPanelKey, PanelSide> = {\n leftRail: 'left',\n rightRail: 'right',\n bottomDrawer: 'bottom',\n};\n\n/** A panel as far as its toolbar is concerned. */\nexport interface WorkbenchToolbarPanel {\n toolbar?: WorkbenchPanelToolbar;\n navStack?: Omit<\n NavStackProps,\n 'panelToggle' | 'hideToolbar' | 'className' | 'slot'\n >;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: PanelChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: WorkbenchPanelBottomToolbar;\n footerPlacement?: PanelChromePlacement;\n /** Configuration for the `Pane` a `toolbar` panel's content renders in. */\n pane?: PaneConfig;\n content?: KerfUiContent;\n collapsed?: boolean;\n /** The corner a collapsed panel's restore controls float in. */\n restorePosition?: FloatingToolbarPosition;\n}\n\n/** A Workbench toggle's wiring hooks: its side, morph key, and panel. */\nconst toggleAttributes = (\n workbenchId: string,\n key: WorkbenchPanelKey,\n): PanelToggleAttributes => ({\n 'data-workbench-toggle': SIDES[key],\n // Keyed, so the morph removes a toggle that leaves a toolbar instead of\n // reusing its (possibly focused) button for a different control.\n 'data-key': `${workbenchRegionId(workbenchId, key)}-toggle`,\n 'aria-controls': workbenchRegionId(workbenchId, key),\n});\n\n/**\n * The groups a collapsed panel hands to the work area: its marked groups,\n * then its toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedGroups(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n): KerfUiContent[] {\n const active = panel?.navStack?.views.at(-1);\n const toolbar =\n active && panel?.toolbar\n ? {\n ...panel.toolbar,\n leading: active.leading,\n center: active.center,\n trailing: active.toolbar,\n }\n : panel?.toolbar;\n return relocatedPanelGroups(\n toolbar,\n SIDES[key],\n Boolean(panel?.collapsed),\n toggleAttributes(workbenchId, key),\n );\n}\n\n/**\n * A panel's content, wrapped in a `Pane` under its composed toolbar when it\n * has one (with its optional `footer` below). Without a toolbar the content\n * renders as given.\n */\nexport function panelBody(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel,\n) {\n const toolbar = panel.toolbar;\n if (panel.navStack) {\n const stack = panel.navStack;\n return NavStack({\n ...stack,\n toolbarConfig: {\n label: stack.toolbarConfig?.label ?? toolbar?.label,\n dividerSides:\n stack.toolbarConfig?.dividerSides ?? toolbar?.dividerSides,\n centerAlign: stack.toolbarConfig?.centerAlign ?? toolbar?.centerAlign,\n responsive: stack.toolbarConfig?.responsive ?? toolbar?.responsive,\n responsiveAt:\n stack.toolbarConfig?.responsiveAt ?? toolbar?.responsiveAt,\n safeAreaEdges:\n stack.toolbarConfig?.safeAreaEdges ?? toolbar?.safeAreaEdges,\n titleSize: stack.toolbarConfig?.titleSize,\n headingLevel: stack.toolbarConfig?.headingLevel,\n },\n panelToggle: toolbar?.toggle\n ? panelToggleGroup(\n SIDES[key],\n toolbar.toggle,\n Boolean(panel.collapsed),\n toggleAttributes(workbenchId, key),\n )\n : undefined,\n });\n }\n if (!toolbar) return panel.content;\n return composedPanelBody({\n toolbar,\n side: SIDES[key],\n collapsed: Boolean(panel.collapsed),\n attributes: toggleAttributes(workbenchId, key),\n pane: panel.pane,\n header: panel.header,\n headerList: panel.headerList,\n headerPlacement: panel.headerPlacement,\n footer: panel.footer,\n footerList: panel.footerList,\n bottomToolbar: panel.bottomToolbar,\n footerPlacement: panel.footerPlacement,\n content: panel.content ?? null,\n });\n}\n\n/**\n * The work area's `mainHeader` / `mainFooter` chrome in a `List` carrying the\n * app's configuration; an omitted or `undefined` field keeps the `List`\n * default (no divider: the work area's `Pane` draws its chrome dividers).\n */\nfunction chromeList(content: KerfUiContent, config: ListConfig | undefined) {\n return (\n <List\n dividerSides={config?.dividerSides}\n gap={config?.gap}\n hAlign={config?.hAlign}\n vAlign={config?.vAlign}\n textInsets={config?.textInsets}\n controlInsets={config?.controlInsets}\n >\n {content}\n </List>\n );\n}\n\n/**\n * Whether the work area's header or footer chrome stays pinned (`fixed`),\n * scrolls away with the content (`scroll`), or stays pinned while the work\n * area is tall enough and scrolls with the content when it is short (`auto`,\n * the Pane's `chromePlacement=\"auto\"`; it applies to the pinned header and\n * footer together).\n */\nexport type WorkbenchChromePlacement = PanelChromePlacement;\n\n/**\n * The work area: the app's `main` in a `Pane` (configured by `mainPane`)\n * under `mainToolbar` and any `mainHeader` list, and above any `mainFooter`\n * list and `mainBottomToolbar` (the header and footer lists configured by\n * `mainHeaderList` / `mainFooterList`), with each collapsed panel's groups\n * added to the toolbar on its side. Without any of that chrome, `main`\n * renders as given; only `mainPane.appearance` applies to the Workbench's\n * own scroll region in that case.\n */\nexport function mainBody({\n workbenchId,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement = 'fixed',\n mainFooterPlacement = 'fixed',\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n}: {\n workbenchId: string;\n main: KerfUiContent;\n mainToolbar?: WorkbenchMainToolbar;\n mainHeader?: KerfUiContent;\n mainFooter?: KerfUiContent;\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n mainHeaderPlacement?: WorkbenchChromePlacement;\n mainFooterPlacement?: WorkbenchChromePlacement;\n mainPane?: PaneConfig;\n mainHeaderList?: ListConfig;\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchToolbarPanel;\n rightRail?: WorkbenchToolbarPanel;\n bottomDrawer?: WorkbenchToolbarPanel;\n}) {\n if (!mainToolbar && !mainBottomToolbar && !mainHeader && !mainFooter)\n return main;\n const left = relocatedGroups(workbenchId, 'leftRail', leftRail);\n const right = relocatedGroups(workbenchId, 'rightRail', rightRail);\n const drawer = mainBottomToolbar\n ? relocatedGroups(workbenchId, 'bottomDrawer', bottomDrawer)\n : [];\n // The Pane draws one divider under the header chrome and one over the\n // footer chrome, wherever that chrome ends, from the scroll state.\n const header =\n !mainToolbar && !mainHeader ? undefined : (\n <>\n {mainToolbar ? (\n <Toolbar\n label={mainToolbar.label}\n dividerSides={mainToolbar.dividerSides}\n centerAlign={mainToolbar.centerAlign}\n responsive={mainToolbar.responsive}\n responsiveAt={mainToolbar.responsiveAt}\n safeAreaEdges={mainToolbar.safeAreaEdges}\n leading={\n <>\n {left}\n {mainToolbar.title}\n {mainToolbar.leading}\n </>\n }\n center={mainToolbar.center}\n trailing={\n <>\n {mainToolbar.trailing}\n {right}\n </>\n }\n />\n ) : null}\n {mainHeader ? chromeList(mainHeader, mainHeaderList) : null}\n </>\n );\n const footer =\n !mainFooter && !mainBottomToolbar ? undefined : (\n <>\n {mainFooter ? chromeList(mainFooter, mainFooterList) : null}\n {mainBottomToolbar ? (\n <Toolbar\n position=\"footer\"\n label={mainBottomToolbar.label}\n dividerSides={mainBottomToolbar.dividerSides}\n centerAlign={mainBottomToolbar.centerAlign}\n responsive={mainBottomToolbar.responsive}\n responsiveAt={mainBottomToolbar.responsiveAt}\n safeAreaEdges={mainBottomToolbar.safeAreaEdges}\n leading={mainBottomToolbar.leading}\n center={mainBottomToolbar.center}\n trailing={\n <>\n {mainBottomToolbar.trailing}\n {drawer}\n </>\n }\n />\n ) : null}\n </>\n );\n const scrollHeader = mainHeaderPlacement === 'scroll';\n const scrollFooter = mainFooterPlacement === 'scroll';\n return (\n <Pane\n header={scrollHeader ? undefined : header}\n footer={scrollFooter ? undefined : footer}\n chromePlacement={\n mainHeaderPlacement === 'auto' || mainFooterPlacement === 'auto'\n ? 'auto'\n : 'fixed'\n }\n contentElement={mainPane?.contentElement}\n contentLabel={mainPane?.contentLabel}\n separators={mainPane?.separators}\n safeAreaEdges={mainPane?.safeAreaEdges}\n chromeDividers={mainPane?.chromeDividers}\n appearance={mainPane?.appearance}\n >\n {scrollHeader || scrollFooter ? (\n // Chrome that scrolls joins the content in one gapless column that\n // fills the scroller, so it scrolls away with the content.\n <List flex>\n {scrollHeader ? header : null}\n {main}\n {scrollFooter ? footer : null}\n </List>\n ) : (\n main\n )}\n </Pane>\n );\n}\n\n/**\n * A collapsed panel's groups when the work area has no toolbar on its side\n * to take them: a `FloatingToolbar` for the panel's restore corner, so the\n * panel can always be reopened.\n */\nexport function floatingRestore(\n workbenchId: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchToolbarPanel | undefined,\n hasTargetToolbar: boolean,\n) {\n if (hasTargetToolbar) return undefined;\n const groups = relocatedGroups(workbenchId, key, panel);\n if (groups.length === 0) return undefined;\n return (\n <FloatingToolbar\n label={panel!.toolbar!.label}\n position={\n panel!.restorePosition ??\n (key === 'leftRail' ? 'bottom-start' : 'bottom-end')\n }\n >\n {groups}\n </FloatingToolbar>\n );\n}\n","import type { SafeHtml } from 'kerfjs';\n\nimport type { ListConfig } from './list.js';\nimport type { NavStackProps } from './nav-stack.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n clampRegionSize,\n type ResizableRegionAxis,\n type ResizableRegionCollapseMotion,\n type ResizableRegionContentOverflow,\n type ResizableRegionEdge,\n type ResizableRegionPresentation,\n type ResizableRegionRestorePosition,\n type ResizableRegionSeparator,\n} from './resizable-region.js';\nimport { ResizeGrip } from './resize-grip.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport {\n WORKBENCH_MAIN_MIN_HEIGHT,\n WORKBENCH_MAIN_MIN_SIZE,\n WORKBENCH_RESIZE_DEFAULTS,\n type WorkbenchPanelKey,\n workbenchRegionId,\n} from './workbench-resize.js';\nimport {\n floatingRestore,\n mainBody,\n panelBody,\n type WorkbenchChromePlacement,\n type WorkbenchMainBottomToolbar,\n type WorkbenchMainToolbar,\n type WorkbenchPanelBottomToolbar,\n type WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\nexport type {\n WorkbenchChromePlacement,\n WorkbenchMainBottomToolbar,\n WorkbenchMainToolbar,\n WorkbenchPanelBottomToolbar,\n WorkbenchPanelToggle,\n WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\n/**\n * The Workbench container breakpoint below which a panel presents as an\n * overlay: `narrow` (704px or less) or `compact` (448px or less) — the same\n * breakpoints as `ResizableRegion`'s `responsiveFillAt` — or `never` to keep\n * it inline at every width.\n */\nexport type WorkbenchResponsiveOverlayAt =\n 'compact' | 'narrow' | 'never' | number;\n\n/**\n * How wide a rail's overlay is in a compact (448px or less) Workbench: `inset`\n * fills the Workbench less a dismiss margin on the side away from the rail's\n * edge, so a press beside it closes it; `full` fills the Workbench.\n */\nexport type WorkbenchCompactOverlay = 'inset' | 'full';\n\n/** Drag-resize limits for a resizable Workbench panel, in px. */\nexport interface WorkbenchPanelResizable {\n /** Smallest size (default 180 for a rail, 120 for the drawer). */\n min?: number;\n /** Largest size (default 480). */\n max?: number;\n}\n\n/** Region sizing, collapse, and presentation shared by either panel body. */\ninterface WorkbenchPanelBase {\n /** Whether the panel is currently collapsed (the app owns this). */\n collapsed?: boolean;\n /**\n * Rail width, or drawer height, in px. Overrides the CSS default. For a\n * resizable panel it is the current size (default 280 for a rail, 220 for\n * the drawer), clamped to the limits; the app owns it and `wireWorkbench`\n * reports each resize.\n */\n size?: number;\n /**\n * Opt in to drag and keyboard resizing on the panel's inner separator:\n * `true` for the default limits, or `{ min, max }`. Off by default. Pair it\n * with `wireWorkbench` from `@kerfjs/ui/wire-workbench`.\n */\n resizable?: boolean | WorkbenchPanelResizable;\n /** Accessible name for the panel region. */\n label?: string;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /**\n * Present the panel as an overlay, without a separator, below a Workbench\n * container breakpoint, and inline above it. `compact` and `narrow` use\n * CSS container queries; a positive number is a pixel threshold measured\n * by `wireWorkbench` and requires a `collapsed` signal. A rail overlays from its side at full\n * height, over the work area and an open drawer; the bottom drawer\n * overlays the bottom of the work-area column. Rails default to `narrow`\n * (pass `never` to keep one inline); the drawer defaults to inline.\n */\n responsiveOverlayAt?: WorkbenchResponsiveOverlayAt;\n /**\n * A rail's overlay width in a compact Workbench (default `inset`: the\n * Workbench less `--kui-workbench-overlay-dismiss-margin`, 44px). Ignored\n * by the drawer.\n */\n compactOverlay?: WorkbenchCompactOverlay;\n /**\n * Control shown while collapsed, in a safe-area-aware corner of the\n * Workbench (not the viewport); the bottom drawer's sits in the work-area\n * column. Prefer `toolbar.toggle`, which the Workbench relocates into the\n * work area's toolbar (or this corner when that toolbar is absent).\n */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n}\n\n/** The original static panel body: one toolbar, optional fixed chrome, and one Pane. */\nexport interface WorkbenchStaticPanel extends WorkbenchPanelBase {\n content: KerfUiContent;\n /** The composed toolbar; marked groups and its toggle relocate on collapse. */\n toolbar?: WorkbenchPanelToolbar;\n header?: KerfUiContent;\n headerList?: ListConfig;\n headerPlacement?: WorkbenchChromePlacement;\n footer?: KerfUiContent;\n footerList?: ListConfig;\n bottomToolbar?: WorkbenchPanelBottomToolbar;\n footerPlacement?: WorkbenchChromePlacement;\n /** Configuration for the static toolbar panel's Pane. */\n pane?: PaneConfig;\n navStack?: never;\n}\n\n/** A panel whose active NavStack view supplies the toolbar, fixed header, and scroll body. */\nexport interface WorkbenchNavigationPanel extends WorkbenchPanelBase {\n navStack: Omit<\n NavStackProps,\n 'panelToggle' | 'hideToolbar' | 'className' | 'slot'\n >;\n /** Supplies the standard toggle; active view groups precede it and may relocate on collapse. */\n toolbar: Omit<\n WorkbenchPanelToolbar,\n 'title' | 'leading' | 'center' | 'trailing'\n > & {\n toggle: NonNullable<WorkbenchPanelToolbar['toggle']>;\n };\n content?: never;\n header?: never;\n headerList?: never;\n headerPlacement?: never;\n footer?: never;\n footerList?: never;\n bottomToolbar?: never;\n footerPlacement?: never;\n pane?: never;\n}\n\n/** A collapsible Workbench side rail or bottom drawer. */\nexport type WorkbenchPanel = WorkbenchStaticPanel | WorkbenchNavigationPanel;\n\nexport interface WorkbenchProps {\n /**\n * The Workbench's `id`. Each panel's `id` derives from it —\n * `<id>-left-rail`, `<id>-right-rail`, `<id>-bottom-drawer` — so a toggle\n * can name the panel it shows and hides with `aria-controls`.\n */\n id: string;\n label: string;\n /** The central work area. */\n main: KerfUiContent;\n /**\n * The work area's top toolbar. A collapsed left rail's marked groups\n * and toggle lead it; a collapsed right rail's trail it. With it, `main`\n * renders in a `Pane` below the toolbar.\n */\n mainToolbar?: WorkbenchMainToolbar;\n /**\n * Fixed content under `mainToolbar` — supporting copy such as a\n * description — divided from the scrolling `main` below it.\n */\n mainHeader?: KerfUiContent;\n /**\n * Fixed content over `mainBottomToolbar` — a status line or a resource\n * toolbar — divided from the scrolling `main` above it.\n */\n mainFooter?: KerfUiContent;\n /**\n * The work area's bottom toolbar. A collapsed drawer's marked groups and\n * toggle trail it; without it they float in the work area's corner.\n */\n mainBottomToolbar?: WorkbenchMainBottomToolbar;\n /**\n * Whether `mainToolbar` and `mainHeader` stay pinned (`fixed`, default),\n * scroll away with `main` (`scroll`) — useful where large text would leave\n * pinned chrome little room — or stay pinned while the work area is tall\n * enough and scroll with `main` when it is short (`auto`).\n */\n mainHeaderPlacement?: WorkbenchChromePlacement;\n /** The same for `mainFooter` and `mainBottomToolbar` (default `fixed`). */\n mainFooterPlacement?: WorkbenchChromePlacement;\n /**\n * Configuration for the work area's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`), which it has whenever it\n * has a toolbar, `mainHeader`, or `mainFooter`; without that chrome, `main`\n * renders as given and this is ignored. Omitted or `undefined` fields keep\n * the `Pane` defaults.\n */\n mainPane?: PaneConfig;\n /**\n * Configuration for the `List` that holds `mainHeader` (`gap`, `hAlign`,\n * `vAlign`, `dividerSides`, `textInsets`, `controlInsets`). Omitted or\n * `undefined` fields keep the defaults (no divider: the work area's\n * `Pane` draws the line under its header chrome).\n */\n mainHeaderList?: ListConfig;\n /**\n * The same for the `List` that holds `mainFooter` (no divider by default:\n * the work area's `Pane` draws the line over its footer chrome).\n */\n mainFooterList?: ListConfig;\n leftRail?: WorkbenchPanel;\n rightRail?: WorkbenchPanel;\n bottomDrawer?: WorkbenchPanel;\n /**\n * Minimum width, in px, the work area keeps beside the inline rails, fixed\n * or `resizable` (default 320; `0` turns it off). Resizing a rail stops\n * where the work area would drop below it, and inline rails shrink\n * proportionally when the Workbench gets narrower. Workbenches without a\n * rail ignore it.\n */\n mainMinSize?: number;\n /**\n * Minimum height, in px, the work area keeps above an inline bottom drawer,\n * fixed or `resizable` (default 120; `0` turns it off) — the drawer's\n * counterpart of `mainMinSize`. Resizing the drawer stops where the work\n * area would drop below it, and the drawer shrinks when the Workbench gets\n * shorter. Workbenches without a drawer ignore it.\n */\n mainMinHeight?: number;\n /** Dim the work area below any open overlay and absorb outside presses; off by default. */\n overlayBackdrop?: boolean;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ninterface ResolvedResize {\n regionId: string;\n axis: ResizableRegionAxis;\n edge: ResizableRegionEdge;\n size: number;\n min: number;\n max: number;\n}\n\n/**\n * Each panel's separator is its inner edge. Growing the left rail moves that\n * edge toward the inline end; growing the right rail or the drawer moves it\n * toward the start — the same edge vocabulary `ResizableRegion` uses.\n */\nconst EDGES: Record<WorkbenchPanelKey, ResizableRegionEdge> = {\n leftRail: 'end',\n rightRail: 'start',\n bottomDrawer: 'start',\n};\n\nconst DEFAULT_LABELS: Record<WorkbenchPanelKey, string> = {\n leftRail: 'left rail',\n rightRail: 'right rail',\n bottomDrawer: 'bottom drawer',\n};\n\nfunction resolveResize(\n id: string,\n key: WorkbenchPanelKey,\n panel: WorkbenchPanel,\n): ResolvedResize | undefined {\n if (!panel.resizable) return undefined;\n const defaults = WORKBENCH_RESIZE_DEFAULTS[key];\n const limits = panel.resizable === true ? {} : panel.resizable;\n const min = limits.min ?? defaults.min;\n const max = Math.max(min, limits.max ?? defaults.max);\n return {\n regionId: workbenchRegionId(id, key),\n axis: key === 'bottomDrawer' ? 'vertical' : 'horizontal',\n edge: EDGES[key],\n size: clampRegionSize(panel.size ?? defaults.size, min, max),\n min,\n max,\n };\n}\n\n/** The attributes a resizable panel adds for the resize wiring to read. */\nconst resizeAttributes = (resize: ResolvedResize | undefined) =>\n resize\n ? {\n 'data-resizable': 'true',\n 'data-region-id': resize.regionId,\n 'data-axis': resize.axis,\n 'data-edge': resize.edge,\n }\n : {};\n\n/**\n * A resizable panel's size lives in the resize wiring's track property, so a\n * drag or key press resizes the panel before the app re-renders; the CSS maps\n * it onto the rail width or drawer height.\n */\nfunction panelStyle(\n panel: WorkbenchPanel,\n resize: ResolvedResize | undefined,\n sizeProperty: string,\n) {\n if (resize) return `--kui-resizable-region-size:${resize.size}px`;\n return panel.size ? `${sizeProperty}: ${panel.size}px` : undefined;\n}\n\n/**\n * The separator a resizable panel owns: the same focusable `role=\"separator\"`\n * contract a `ResizableRegion` handle carries, so one resize wiring drives\n * both. It leaves the tab order while the panel is collapsed or not inline.\n */\nfunction PanelHandle({\n panel,\n resize,\n label,\n}: {\n panel: WorkbenchPanel;\n resize: ResolvedResize;\n label: string;\n}) {\n const inert =\n Boolean(panel.collapsed) || (panel.presentation ?? 'inline') !== 'inline';\n return (\n <div\n class=\"kui-workbench__handle\"\n role=\"separator\"\n tabindex={inert ? '-1' : '0'}\n aria-label={`Resize ${label}`}\n aria-orientation={\n resize.axis === 'horizontal' ? 'vertical' : 'horizontal'\n }\n aria-valuemin={resize.min}\n aria-valuemax={resize.max}\n aria-valuenow={resize.size}\n aria-hidden={inert ? 'true' : undefined}\n data-kui-resize-handle\n data-region-id={resize.regionId}\n >\n <span class=\"kui-workbench__handle-icon\" aria-hidden=\"true\">\n <ResizeGrip axis={resize.axis} />\n </span>\n </div>\n );\n}\n\n/**\n * A collapsed panel leaves the accessibility tree as a whole, like a collapsed\n * `CollapsiblePanel`: its content and separator are already inert or hidden,\n * so the labeled landmark would otherwise stay behind, empty, for a screen\n * reader to land on. Its restore control renders outside it and stays\n * reachable.\n */\nfunction hiddenFromAccessibility(panel: WorkbenchPanel) {\n return panel.collapsed || panel.presentation === 'hidden'\n ? ('true' as const)\n : undefined;\n}\n\n/** A breakpoint's attribute value; `never` (or none) renders no attribute. */\nconst responsiveAt = (at: WorkbenchResponsiveOverlayAt | undefined) =>\n at === 'never' ? undefined : at;\n\nconst inline = (panel: WorkbenchPanel | undefined) =>\n Boolean(panel && (panel.presentation ?? 'inline') === 'inline');\n\nconst expanded = (panel: WorkbenchPanel | undefined) =>\n Boolean(panel && !panel.collapsed);\n\nconst responsiveRail = (panel: WorkbenchPanel | undefined) =>\n panel ? responsiveAt(panel.responsiveOverlayAt ?? 'narrow') : undefined;\n\nconst responsiveDrawer = (panel: WorkbenchPanel | undefined) =>\n panel ? responsiveAt(panel.responsiveOverlayAt) : undefined;\n\nfunction Rail({\n id,\n side,\n panel,\n}: {\n id: string;\n side: 'left' | 'right';\n panel: WorkbenchPanel;\n}) {\n const key: WorkbenchPanelKey = side === 'left' ? 'leftRail' : 'rightRail';\n const resize = resolveResize(id, key, panel);\n return (\n <aside\n id={workbenchRegionId(id, key)}\n class={`kui-workbench__rail kui-workbench__rail--${side}`}\n data-workbench-rail={side}\n data-appearance={\n !panel.toolbar && panel.pane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(\n panel.responsiveOverlayAt ?? 'narrow',\n )}\n data-compact-overlay={panel.compactOverlay ?? 'inset'}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-rail-width')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, key, panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS[key]}\n />\n )}\n </aside>\n );\n}\n\nfunction Drawer({ id, panel }: { id: string; panel: WorkbenchPanel }) {\n const resize = resolveResize(id, 'bottomDrawer', panel);\n return (\n <section\n id={workbenchRegionId(id, 'bottomDrawer')}\n class=\"kui-workbench__drawer\"\n data-workbench-drawer\n data-appearance={\n !panel.toolbar && panel.pane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n data-collapsed={String(panel.collapsed ?? false)}\n data-separator={panel.separator ?? 'auto'}\n data-collapse-motion={panel.collapseMotion ?? 'slide'}\n data-content-overflow={panel.contentOverflow ?? 'clip'}\n data-presentation={panel.presentation ?? 'inline'}\n data-responsive-overlay-at={responsiveAt(panel.responsiveOverlayAt)}\n {...resizeAttributes(resize)}\n aria-label={panel.label || undefined}\n aria-hidden={hiddenFromAccessibility(panel)}\n inert={Boolean(panel.collapsed)}\n style={panelStyle(panel, resize, '--kui-workbench-drawer-height')}\n >\n <div\n class=\"kui-workbench__panel-content\"\n data-workbench-panel-content\n inert={Boolean(panel.collapsed)}\n >\n {panelBody(id, 'bottomDrawer', panel)}\n </div>\n {resize && (\n <PanelHandle\n panel={panel}\n resize={resize}\n label={panel.label || DEFAULT_LABELS.bottomDrawer}\n />\n )}\n </section>\n );\n}\n\n/** A collapsed panel's restore control, outside the clipped panel. */\nfunction restore(\n panel: WorkbenchPanel | undefined,\n side: 'left' | 'right' | 'bottom',\n position: ResizableRegionRestorePosition,\n generated: SafeHtml | undefined,\n) {\n const control = panel?.restoreControl ?? generated;\n if (!panel?.collapsed || !control || panel.presentation === 'hidden')\n return '';\n return (\n <div\n class=\"kui-workbench__restore\"\n data-panel={side}\n data-position={panel.restorePosition ?? position}\n >\n {control}\n </div>\n );\n}\n\n/**\n * The Xcode-like multi-panel workspace: a collapsible left rail, right rail, and\n * bottom drawer around a central work area (any absent). Collapsing snaps the\n * panel's track to zero in one reflow while its fixed-size content slides out via\n * a composited transform — the instant-width / sliding-content technique, so the\n * work area relayouts once, not per frame. Bottom-drawer content stays anchored\n * to the shell's stable bottom edge throughout that transition. The app owns\n * each `collapsed` flag; the collapse is pure CSS. A collapsed panel renders\n * `inert` and `aria-hidden`, so neither Tab nor assistive technology reaches\n * controls that have slid out of view or an empty landmark (its restore control\n * lives outside it and stays reachable). A panel may opt in to drag and keyboard resizing with\n * `resizable`, which `wireWorkbench` drives. See `docs/23-app-layouts.md` §3.3.\n */\nexport function Workbench({\n id,\n label,\n main,\n leftRail,\n rightRail,\n bottomDrawer,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n mainMinSize = WORKBENCH_MAIN_MIN_SIZE,\n mainMinHeight = WORKBENCH_MAIN_MIN_HEIGHT,\n overlayBackdrop = false,\n className = '',\n slot,\n}: WorkbenchProps) {\n // Each work-area minimum applies only on an axis a panel shares with it:\n // the width beside a rail, the height above the drawer.\n const px = (value: number) => Math.max(0, Math.round(value));\n const mainMin = leftRail || rightRail ? px(mainMinSize) : undefined;\n const mainMinBlock = bottomDrawer ? px(mainMinHeight) : undefined;\n const style = [\n mainMin === undefined ? '' : `--_kui-workbench-main-min-width:${mainMin}px`,\n mainMinBlock === undefined\n ? ''\n : `--_kui-workbench-main-min-height:${mainMinBlock}px`,\n ]\n .filter(Boolean)\n .join(';');\n return (\n <section\n class={`kui-workbench ${className}`.trim()}\n id={id}\n data-component=\"workbench\"\n data-main-min-size={mainMin === undefined ? undefined : String(mainMin)}\n data-main-min-height={\n mainMinBlock === undefined ? undefined : String(mainMinBlock)\n }\n data-left-inline-expanded={\n inline(leftRail) && expanded(leftRail) ? 'true' : undefined\n }\n data-right-inline-expanded={\n inline(rightRail) && expanded(rightRail) ? 'true' : undefined\n }\n data-left-responsive-inline={\n inline(leftRail) ? responsiveRail(leftRail) : undefined\n }\n data-right-responsive-inline={\n inline(rightRail) ? responsiveRail(rightRail) : undefined\n }\n data-left-responsive-expanded={\n inline(leftRail) && expanded(leftRail)\n ? responsiveRail(leftRail)\n : undefined\n }\n data-right-responsive-expanded={\n inline(rightRail) && expanded(rightRail)\n ? responsiveRail(rightRail)\n : undefined\n }\n data-rail-overlay-expanded={\n (leftRail?.presentation === 'overlay' && expanded(leftRail)) ||\n (rightRail?.presentation === 'overlay' && expanded(rightRail))\n ? 'true'\n : undefined\n }\n data-drawer-overlay-expanded={\n bottomDrawer?.presentation === 'overlay' && expanded(bottomDrawer)\n ? 'true'\n : undefined\n }\n data-drawer-responsive-expanded={\n inline(bottomDrawer) && expanded(bottomDrawer)\n ? responsiveDrawer(bottomDrawer)\n : undefined\n }\n data-overlay-backdrop={overlayBackdrop ? 'true' : undefined}\n data-responsive-overlay={\n responsiveRail(leftRail) ||\n responsiveRail(rightRail) ||\n responsiveDrawer(bottomDrawer)\n ? 'true'\n : undefined\n }\n style={style || undefined}\n aria-label={label}\n slot={slot}\n >\n {leftRail && <Rail id={id} side=\"left\" panel={leftRail} />}\n {restore(\n leftRail,\n 'left',\n 'bottom-start',\n floatingRestore(id, 'leftRail', leftRail, Boolean(mainToolbar)),\n )}\n <div class=\"kui-workbench__center\">\n <div\n class=\"kui-workbench__main\"\n data-workbench-main\n data-drawer-inline-expanded={\n inline(bottomDrawer) && expanded(bottomDrawer) ? 'true' : undefined\n }\n data-drawer-responsive-inline={\n inline(bottomDrawer) ? responsiveDrawer(bottomDrawer) : undefined\n }\n data-appearance={\n !mainToolbar &&\n !mainBottomToolbar &&\n !mainHeader &&\n !mainFooter &&\n mainPane?.appearance === 'sunken'\n ? 'sunken'\n : undefined\n }\n >\n {mainBody({\n workbenchId: id,\n main,\n mainToolbar,\n mainHeader,\n mainFooter,\n mainBottomToolbar,\n mainHeaderPlacement,\n mainFooterPlacement,\n mainPane,\n mainHeaderList,\n mainFooterList,\n leftRail,\n rightRail,\n bottomDrawer,\n })}\n </div>\n {bottomDrawer && <Drawer id={id} panel={bottomDrawer} />}\n {restore(\n bottomDrawer,\n 'bottom',\n 'bottom-end',\n floatingRestore(\n id,\n 'bottomDrawer',\n bottomDrawer,\n Boolean(mainBottomToolbar),\n ),\n )}\n </div>\n {rightRail && <Rail id={id} side=\"right\" panel={rightRail} />}\n {restore(\n rightRail,\n 'right',\n 'bottom-end',\n floatingRestore(id, 'rightRail', rightRail, Boolean(mainToolbar)),\n )}\n {overlayBackdrop ? (\n <div\n class=\"kui-workbench__backdrop\"\n data-workbench-backdrop\n aria-hidden=\"true\"\n />\n ) : null}\n </section>\n );\n}\n"]}
@@ -13,9 +13,26 @@ function ToolbarText({
13
13
  ellipsis = true,
14
14
  maxLines = null,
15
15
  fill = false,
16
- slot
16
+ slot,
17
+ action
17
18
  }) {
18
19
  const capped = wrap && maxLines != null && maxLines > 0;
20
+ if (action !== void 0)
21
+ return /* @__PURE__ */ jsx(
22
+ "button",
23
+ {
24
+ type: "button",
25
+ class: `kui-toolbar-text ${className}`.trim(),
26
+ "data-component": "toolbar-text",
27
+ "data-size": size,
28
+ "data-fill": fill ? "true" : void 0,
29
+ "data-ellipsis": ellipsis ? void 0 : "false",
30
+ "data-action": action,
31
+ id,
32
+ slot,
33
+ children: /* @__PURE__ */ jsx("span", { class: "kui-toolbar-text__text", children: text })
34
+ }
35
+ );
19
36
  return /* @__PURE__ */ jsx(
20
37
  "span",
21
38
  {
@@ -40,4 +57,4 @@ function ToolbarText({
40
57
 
41
58
  export { ToolbarText };
42
59
 
43
- //# sourceMappingURL=chunk-V3DX3K65.js.map
60
+ //# sourceMappingURL=chunk-R5F5XUJ7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toolbar-text.tsx"],"names":[],"mappings":";;;;AA8DO,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,SAAA,GAAY,EAAA;AAAA,EACZ,EAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,IAAA,GAAO,KAAA;AAAA,EACP,QAAA,GAAW,IAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX,IAAA,GAAO,KAAA;AAAA,EACP,IAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,MAAA,GAAS,IAAA,IAAQ,QAAA,IAAY,IAAA,IAAQ,QAAA,GAAW,CAAA;AACtD,EAAA,IAAI,MAAA,KAAW,MAAA;AACb,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,QAC5C,gBAAA,EAAe,cAAA;AAAA,QACf,WAAA,EAAW,IAAA;AAAA,QACX,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,QAC3B,eAAA,EAAe,WAAW,MAAA,GAAY,OAAA;AAAA,QACtC,aAAA,EAAa,MAAA;AAAA,QACb,EAAA;AAAA,QACA,IAAA;AAAA,QAEA,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,KAC7C;AAEJ,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,gBAAA,EAAe,cAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,MAC3B,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,MAC3B,eAAA,EAAe,WAAW,MAAA,GAAY,OAAA;AAAA,MACtC,gBAAA,EAAgB,MAAA,GAAS,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,MAC5C,KAAA,EAAO,MAAA,GAAS,CAAA,6BAAA,EAAgC,QAAQ,CAAA,CAAA,GAAK,MAAA;AAAA,MAC7D,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,EAAA;AAAA,MACA,IAAA,EAAM,eAAe,SAAA,GAAY,MAAA;AAAA,MACjC,YAAA,EAAY,YAAA,GAAe,MAAA,CAAO,YAAY,CAAA,GAAI,MAAA;AAAA,MAClD,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAClC,IAAA;AAAA,MAEC,QAAA,EAAA,WAAA,mBACC,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAO,EAAA,CAAG,CAAC,CAAA,EAAG,CAAA,mBAExB,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,GAE/C;AAEJ","file":"chunk-R5F5XUJ7.js","sourcesContent":["import { em } from './css-values.js';\nimport { Skeleton } from './skeleton.js';\n\nexport type ToolbarTextSize =\n 'xlarge' | 'xlarge-fixed' | 'large' | 'default' | 'small' | 'xsmall';\n\n/** ARIA heading level for a title exposed as a heading landmark. */\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\ninterface ToolbarTextBaseProps {\n text: string;\n size?: ToolbarTextSize;\n className?: string;\n /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */\n id?: string;\n /**\n * Show a trailing ellipsis (…) where the text is truncated — on the single line\n * (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip\n * instead. Default true.\n */\n ellipsis?: boolean;\n /**\n * Grow to fill the free space of the flex row it sits in (a Toolbar zone),\n * truncating at the space left by its siblings instead of taking only its\n * text's width. Default false.\n */\n fill?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n /**\n * Cap wrapped text to this many lines, truncating past it. Only takes effect with\n * `wrap`; ignored on a single line. `null`/omitted wraps without a line cap. Default null.\n */\n}\n\ntype ToolbarTextWrappingProps =\n | {\n /** Wrap onto multiple lines; combine with `maxLines` to cap them. */\n wrap: true;\n maxLines?: number | null;\n }\n | { wrap?: false; maxLines?: never };\n\nexport type ToolbarTextProps = ToolbarTextBaseProps &\n (\n | ({\n action?: never;\n /** Expose `role=\"heading\"` and `aria-level` on read-only text. */\n headingLevel?: HeadingLevel;\n /** Render an unanimated loading skeleton instead of the text. */\n placeholder?: boolean;\n } & ToolbarTextWrappingProps)\n | {\n /** Render a native button with this delegated action; the app owns editing. */\n action: string;\n headingLevel?: never;\n placeholder?: never;\n wrap?: never;\n maxLines?: never;\n }\n );\n\nexport function ToolbarText({\n text,\n size = 'default',\n className = '',\n id,\n headingLevel,\n placeholder = false,\n wrap = false,\n ellipsis = true,\n maxLines = null,\n fill = false,\n slot,\n action,\n}: ToolbarTextProps) {\n const capped = wrap && maxLines != null && maxLines > 0;\n if (action !== undefined)\n return (\n <button\n type=\"button\"\n class={`kui-toolbar-text ${className}`.trim()}\n data-component=\"toolbar-text\"\n data-size={size}\n data-fill={fill ? 'true' : undefined}\n data-ellipsis={ellipsis ? undefined : 'false'}\n data-action={action}\n id={id}\n slot={slot}\n >\n <span class=\"kui-toolbar-text__text\">{text}</span>\n </button>\n );\n return (\n <span\n class={`kui-toolbar-text ${className}`.trim()}\n data-component=\"toolbar-text\"\n data-size={size}\n data-fill={fill ? 'true' : undefined}\n data-wrap={wrap ? 'true' : undefined}\n data-ellipsis={ellipsis ? undefined : 'false'}\n data-max-lines={capped ? String(maxLines) : undefined}\n style={capped ? `--kui-toolbar-text-max-lines:${maxLines}` : undefined}\n data-placeholder={placeholder ? 'true' : undefined}\n id={id}\n role={headingLevel ? 'heading' : undefined}\n aria-level={headingLevel ? String(headingLevel) : undefined}\n aria-busy={placeholder ? 'true' : undefined}\n slot={slot}\n >\n {placeholder ? (\n <Skeleton width={em(8)} />\n ) : (\n <span class=\"kui-toolbar-text__text\">{text}</span>\n )}\n </span>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { ToolbarText } from './chunk-V3DX3K65.js';
1
+ import { ToolbarText } from './chunk-R5F5XUJ7.js';
2
2
  import { ToolbarControlGroup } from './chunk-QJ5VFCW3.js';
3
3
  import { Toolbar } from './chunk-RGS4WX2M.js';
4
4
  import { LucideIcon } from './chunk-WTSNV5RG.js';
@@ -120,4 +120,4 @@ function NavStack({
120
120
 
121
121
  export { NavStack };
122
122
 
123
- //# sourceMappingURL=chunk-DC6CN2DS.js.map
123
+ //# sourceMappingURL=chunk-VLYIPBCQ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":";;;;;;;AA4FA,IAAM,uBAAA,GAA0B;AAAA,EAC9B,aAAA;AAAA,EACA,cAAA;AAAA,EACA;AACF,CAAA;AAUO,SAAS,QAAA,CAAS;AAAA,EACvB,EAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,MAAA;AAAA,EACZ,QAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAgB,EAAC;AAAA,EACjB,WAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,aAAA;AAAA,EACA,cAAA,GAAiB,QAAA;AAAA,EACjB,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAkB;AAChB,EAAA,MAAM,QAAA,GAAW,MAAM,MAAA,GAAS,CAAA;AAChC,EAAA,MAAM,GAAA,GAAM,MAAM,QAAQ,CAAA;AAC1B,EAAA,MAAM,MAAA,GAAS,MAAM,MAAA,GAAS,CAAA;AAC9B,EAAA,uBACE,IAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,cAAA,EAAiB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACzC,EAAA;AAAA,MACA,gBAAA,EAAe,WAAA;AAAA,MACf,mBAAA,EAAmB,EAAA;AAAA,MACnB,YAAA,EAAY,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA;AAAA,MAC/B,sBAAA,EACE,cAAA,KAAmB,QAAA,IAAY,cAAA,KAAmB,SAC9C,cAAA,GACA,MAAA;AAAA,MAEN,YAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,CAAC,+BACA,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAwB,yBAAqB,IAAA,EACtD,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,OAAA;AAAA,YAAA;AAAA,cACC,OAAO,aAAA,CAAc,KAAA;AAAA,cACrB,cAAc,aAAA,CAAc,YAAA;AAAA,cAC5B,aAAa,aAAA,CAAc,WAAA;AAAA,cAC3B,YAAY,aAAA,CAAc,UAAA;AAAA,cAC1B,cAAc,aAAA,CAAc,YAAA;AAAA,cAC5B,aAAA,EACE,cAAc,aAAA,IAAiB,uBAAA;AAAA,cAEjC,yBACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,gBAAA,MAAA,oBACC,GAAA;AAAA,kBAAC,mBAAA;AAAA,kBAAA;AAAA,oBACC,UAAA,EAAW,YAAA;AAAA,oBACX,KAAA,EAAM,SAAA;AAAA,oBACN,OAAA,EAAS,WAAW,OAAA,GAAU,MAAA;AAAA,oBAC9B,MAAA,EAAM,IAAA;AAAA,oBAEN,QAAA,kBAAA,IAAA;AAAA,sBAAC,QAAA;AAAA,sBAAA;AAAA,wBACC,IAAA,EAAK,QAAA;AAAA,wBACL,KAAA,EAAM,qBAAA;AAAA,wBACN,eAAA,EAAa,IAAA;AAAA,wBACb,YAAA,EAAY,WAAW,MAAA,GAAY,SAAA;AAAA,wBAElC,QAAA,EAAA;AAAA,0BAAA,QAAA,oBACC,GAAA;AAAA,4BAAC,UAAA;AAAA,4BAAA;AAAA,8BACC,IAAA,EAAM,WAAA;AAAA,8BACN,IAAA,EAAK,cAAA;AAAA,8BACL,SAAA,EAAU;AAAA;AAAA,2BACZ;AAAA,0BAED,QAAA,mBAAW,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,EAAS,CAAA,GAAU;AAAA;AAAA;AAAA;AACxC;AAAA,iBACF;AAAA,gBAED,GAAA,EAAK,OAAA;AAAA,gCACN,GAAA;AAAA,kBAAC,WAAA;AAAA,kBAAA;AAAA,oBACC,IAAA,EAAM,KAAK,KAAA,IAAS,EAAA;AAAA,oBACpB,IAAA,EAAM,cAAc,SAAA,IAAa,OAAA;AAAA,oBACjC,cAAc,aAAA,CAAc,YAAA;AAAA,oBAC5B,IAAA,EAAI;AAAA;AAAA;AACN,eAAA,EACF,CAAA;AAAA,cAEF,QAAQ,GAAA,EAAK,MAAA;AAAA,cACb,0BACE,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,gBAAA,GAAA,EAAK,OAAA;AAAA,gBACL;AAAA,eAAA,EACH;AAAA;AAAA,WAEJ;AAAA,UACC,GAAA,EAAK,0BACJ,GAAA,CAAC,KAAA,EAAA,EAAI,OAAM,uBAAA,EAAwB,uBAAA,EAAqB,IAAA,EACrD,QAAA,EAAA,GAAA,CAAI,MAAA,EACP;AAAA,SAAA,EAEJ,CAAA;AAAA,wBAEF,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,yBAAA,EAA0B,yBAAA,EAAuB,MACzD,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,EAAM,KAAA,qBAChB,GAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,qBAAA;AAAA,YACN,YAAU,IAAA,CAAK,GAAA;AAAA,YACf,gBAAc,IAAA,CAAK,GAAA;AAAA,YACnB,iBAAA,EAAiB,MAAA,CAAO,KAAA,KAAU,QAAQ,CAAA;AAAA,YAC1C,iBAAA,EACE,IAAA,CAAK,UAAA,KAAe,QAAA,GAAW,QAAA,GAAW,MAAA;AAAA,YAE5C,aAAA,EAAa,MAAA,CAAO,KAAA,KAAU,QAAQ,CAAA;AAAA,YAErC,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA,SAET,CAAA,EACH,CAAA;AAAA,QAAA,CACE,GAAA,EAAK,aAAA,IAAiB,aAAA,qBACtB,GAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,uBAAA,EAAwB,uBAAA,EAAqB,IAAA,EACxD,QAAA,EAAA,GAAA,EAAK,aAAA,IAAiB,aAAA,EACzB;AAAA;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-DC6CN2DS.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneAppearance } from './pane.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from './toolbar-text.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n content: KerfUiContent;\n /** Background of this view's scrolling work surface. */\n appearance?: PaneAppearance;\n /** Title shown in the top toolbar for this view. */\n title?: string;\n /** Leading groups for this view's top toolbar, after the back control and before the title. */\n leading?: KerfUiContent;\n /** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */\n center?: KerfUiContent;\n /** Trailing actions for this view's top toolbar. */\n toolbar?: KerfUiContent;\n /** Fixed chrome below this view's toolbar, above its scrolling content. */\n header?: KerfUiContent;\n /** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */\n bottomToolbar?: KerfUiContent;\n}\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */\n panelToggle?: KerfUiContent;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: KerfUiContent;\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `leading` / `center` / `toolbar`\n * content fills the zones, and `toolbarConfig` configures it. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n panelToggle,\n hideToolbar = false,\n bottomToolbar,\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={toolbarConfig.label}\n dividerSides={toolbarConfig.dividerSides}\n centerAlign={toolbarConfig.centerAlign}\n responsive={toolbarConfig.responsive}\n responsiveAt={toolbarConfig.responsiveAt}\n safeAreaEdges={\n toolbarConfig.safeAreaEdges ?? DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {top?.leading}\n <ToolbarText\n text={top?.title ?? ''}\n size={toolbarConfig.titleSize ?? 'large'}\n headingLevel={toolbarConfig.headingLevel}\n fill\n />\n </>\n }\n center={top?.center}\n trailing={\n <>\n {top?.toolbar}\n {panelToggle}\n </>\n }\n />\n {top?.header && (\n <div class=\"kui-nav-stack__header\" data-nav-stack-header>\n {top.header}\n </div>\n )}\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n data-appearance={\n view.appearance === 'sunken' ? 'sunken' : undefined\n }\n aria-hidden={String(index !== topIndex)}\n >\n {view.content}\n </article>\n ))}\n </div>\n {(top?.bottomToolbar ?? bottomToolbar) && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n {top?.bottomToolbar ?? bottomToolbar}\n </footer>\n )}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-VLYIPBCQ.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneAppearance } from './pane.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from './toolbar-text.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n content: KerfUiContent;\n /** Background of this view's scrolling work surface. */\n appearance?: PaneAppearance;\n /** Title shown in the top toolbar for this view. */\n title?: string;\n /** Leading groups for this view's top toolbar, after the back control and before the title. */\n leading?: KerfUiContent;\n /** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */\n center?: KerfUiContent;\n /** Trailing actions for this view's top toolbar. */\n toolbar?: KerfUiContent;\n /** Fixed chrome below this view's toolbar, above its scrolling content. */\n header?: KerfUiContent;\n /** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */\n bottomToolbar?: KerfUiContent;\n}\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */\n panelToggle?: KerfUiContent;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: KerfUiContent;\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `leading` / `center` / `toolbar`\n * content fills the zones, and `toolbarConfig` configures it. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n panelToggle,\n hideToolbar = false,\n bottomToolbar,\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={toolbarConfig.label}\n dividerSides={toolbarConfig.dividerSides}\n centerAlign={toolbarConfig.centerAlign}\n responsive={toolbarConfig.responsive}\n responsiveAt={toolbarConfig.responsiveAt}\n safeAreaEdges={\n toolbarConfig.safeAreaEdges ?? DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {top?.leading}\n <ToolbarText\n text={top?.title ?? ''}\n size={toolbarConfig.titleSize ?? 'large'}\n headingLevel={toolbarConfig.headingLevel}\n fill\n />\n </>\n }\n center={top?.center}\n trailing={\n <>\n {top?.toolbar}\n {panelToggle}\n </>\n }\n />\n {top?.header && (\n <div class=\"kui-nav-stack__header\" data-nav-stack-header>\n {top.header}\n </div>\n )}\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n data-appearance={\n view.appearance === 'sunken' ? 'sunken' : undefined\n }\n aria-hidden={String(index !== topIndex)}\n >\n {view.content}\n </article>\n ))}\n </div>\n {(top?.bottomToolbar ?? bottomToolbar) && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n {top?.bottomToolbar ?? bottomToolbar}\n </footer>\n )}\n </section>\n );\n}\n"]}
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ export { ListHeader } from './chunk-M6DEEBEF.js';
25
25
  export { FieldLabel, Text } from './chunk-YDGNU2OD.js';
26
26
  export { ListInsetText } from './chunk-DG6G5EPF.js';
27
27
  export { ListItem, ListItemLink } from './chunk-NC4CFOID.js';
28
- export { ToolbarText } from './chunk-V3DX3K65.js';
28
+ export { ToolbarText } from './chunk-R5F5XUJ7.js';
29
29
  export { DisclosureArrow } from './chunk-G4S2QU6V.js';
30
30
  export { FloatingToolbar } from './chunk-I3Q7KKYM.js';
31
31
 
package/dist/nav-stack.js CHANGED
@@ -1,4 +1,4 @@
1
- export { NavStack } from './chunk-DC6CN2DS.js';
1
+ export { NavStack } from './chunk-VLYIPBCQ.js';
2
2
 
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- import { NavStack } from './chunk-DC6CN2DS.js';
1
+ import { NavStack } from './chunk-VLYIPBCQ.js';
2
2
  import { ResizableRegion } from './chunk-KLJKU6ZL.js';
3
3
 
4
4
 
@@ -22,6 +22,12 @@
22
22
  white-space: nowrap;
23
23
  }
24
24
 
25
+ /* A normal status chip stays readable beside a shrinkable toolbar title.
26
+ Only the explicit truncate variant gives up its label width. */
27
+ .kui-chip:not([data-truncate]) {
28
+ flex-shrink: 0;
29
+ }
30
+
25
31
  .kui-chip[data-tone="brand"] {
26
32
  --_kui-chip-fill-quiet: var(--kui-color-brand-fill-quiet);
27
33
  --_kui-chip-fill-solid: var(--kui-color-brand-on-fill);
@@ -12,6 +12,26 @@
12
12
  align-items: center;
13
13
  }
14
14
 
15
+ button.kui-toolbar-text {
16
+ appearance: none;
17
+ border: 0;
18
+ border-radius: 0.375rem;
19
+ background: transparent;
20
+ font-family: inherit;
21
+ text-align: start;
22
+ justify-content: flex-start;
23
+ cursor: pointer;
24
+ }
25
+
26
+ button.kui-toolbar-text:hover {
27
+ background: var(--kui-color-neutral-fill-normal);
28
+ }
29
+
30
+ button.kui-toolbar-text:focus-visible {
31
+ outline: var(--kui-focus-ring);
32
+ outline-offset: 0.125rem;
33
+ }
34
+
15
35
  /* In a Toolbar zone, a title fills the toolbar's control band (the
16
36
  `--_kui-toolbar-band` the Toolbar provides) and centers its first line in
17
37
  it; further lines of a wrapped title continue below the band. These rules
@@ -9,14 +9,6 @@ interface ToolbarTextBaseProps {
9
9
  className?: string;
10
10
  /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */
11
11
  id?: string;
12
- /**
13
- * Expose heading semantics (`role="heading"` + `aria-level`) so the text acts as
14
- * a heading landmark — e.g. a page's primary title. Omit to keep the plain span
15
- * (the default), which suits a dialog title referenced via `aria-labelledby`.
16
- */
17
- headingLevel?: HeadingLevel;
18
- /** Render the text as an unanimated loading skeleton instead of its value. */
19
- placeholder?: boolean;
20
12
  /**
21
13
  * Show a trailing ellipsis (…) where the text is truncated — on the single line
22
14
  * (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip
@@ -40,7 +32,20 @@ type ToolbarTextWrappingProps = {
40
32
  wrap?: false;
41
33
  maxLines?: never;
42
34
  };
43
- type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;
44
- declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, fill, slot, }: ToolbarTextProps): kerfjs.SafeHtml;
35
+ type ToolbarTextProps = ToolbarTextBaseProps & (({
36
+ action?: never;
37
+ /** Expose `role="heading"` and `aria-level` on read-only text. */
38
+ headingLevel?: HeadingLevel;
39
+ /** Render an unanimated loading skeleton instead of the text. */
40
+ placeholder?: boolean;
41
+ } & ToolbarTextWrappingProps) | {
42
+ /** Render a native button with this delegated action; the app owns editing. */
43
+ action: string;
44
+ headingLevel?: never;
45
+ placeholder?: never;
46
+ wrap?: never;
47
+ maxLines?: never;
48
+ });
49
+ declare function ToolbarText({ text, size, className, id, headingLevel, placeholder, wrap, ellipsis, maxLines, fill, slot, action, }: ToolbarTextProps): kerfjs.SafeHtml;
45
50
 
46
51
  export { type HeadingLevel, ToolbarText, type ToolbarTextProps, type ToolbarTextSize };
@@ -1,4 +1,4 @@
1
- export { ToolbarText } from './chunk-V3DX3K65.js';
1
+ export { ToolbarText } from './chunk-R5F5XUJ7.js';
2
2
 
3
3
 
4
4
 
package/dist/workbench.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Workbench } from './chunk-KCCEH7RF.js';
1
+ export { Workbench } from './chunk-3UE24JSC.js';
2
2
 
3
3
 
4
4
 
@@ -322,6 +322,11 @@ role/level pair used throughout Kerf UI. Keep the levels meaningful and
322
322
  non-skipping within a view. Pass trailing
323
323
  controls as a labeled `ToolbarControlGroup` when that group needs an accessible
324
324
  name. Keep supporting copy as app-owned content below the toolbar.
325
+ An editable title can use `ToolbarText action="edit-title"`; it renders a native
326
+ button whose full text remains its accessible name even when visually truncated.
327
+ Click, Enter, and Space activate the delegated action. The app owns the input
328
+ shown while editing and its focus lifecycle. Because the button cannot also be
329
+ a heading landmark, expose a heading elsewhere when the view needs one.
325
330
 
326
331
  ## FloatingToolbar
327
332
 
@@ -622,6 +622,12 @@ zone holds an optional icon `ToolbarControlGroup` and a direct extra-large
622
622
  `ToolbarText`; app actions belong in a trailing `ToolbarControlGroup`. Omit the
623
623
  icon group when it has no content. Supporting copy is app-owned content below
624
624
  the toolbar so it cannot pull the icon or actions out of alignment.
625
+ For an editable title, `ToolbarText action="edit-title"` renders a native button
626
+ directly in the leading zone. It keeps content width when there is room, shrinks
627
+ and ellipsizes beside a status chip when space is tight, and emits the delegated
628
+ action on click or keyboard activation. The application owns the editing control
629
+ and the swap between display and edit states. An actionable title is a button,
630
+ so place any required heading landmark on another element in the view.
625
631
 
626
632
  `ValueTable` composes typed `ValueTableRow` entries. A row owns its `dt`/`dd`
627
633
  semantics and may receive a leading `SafeHtml` icon. Every row keeps 8px of
@@ -391,6 +391,11 @@ zone children are `ToolbarText` (identity/title text) and `ToolbarControlGroup`
391
391
  standalone `wa-button` for the application's primary action. It keeps its own
392
392
  Web Awesome brand, danger, size, and hover chrome, while Toolbar aligns it in
393
393
  the control band and wraps it with other trailing items when space is tight.
394
+ For a title that opens an editor, set `action` on a direct `ToolbarText`: it
395
+ renders a native button that keeps its content width when possible and
396
+ ellipsizes before an adjacent status chip when the leading zone narrows. The
397
+ application handles the delegated action and replaces it with its own input
398
+ while editing. Use a separate heading landmark if the view needs one.
394
399
  Do not drop other bare buttons, inputs, links, or arbitrary markup straight
395
400
  into a zone; wrap controls in a `ToolbarControlGroup` so they get the shared
396
401
  toolbar geometry, hover/pressed treatment, and grouping. `SegmentedControl`,
package/docs/layout.md CHANGED
@@ -309,6 +309,10 @@ zone holds an optional icon `ToolbarControlGroup` and a direct extra-large
309
309
  `ToolbarText`; actions belong in a trailing group. Omit empty groups. Supporting
310
310
  copy is app-owned content below the toolbar and aligns with the intended content
311
311
  edge.
312
+ When the title itself opens editing, set `ToolbarText action="edit-title"` and
313
+ render it directly in the leading zone beside any status chip. The button
314
+ shrinks and ellipsizes at the space left by its siblings without filling unused
315
+ space; the app swaps its own input into the edit state.
312
316
 
313
317
  ## Spacing scale
314
318
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kerfjs/ui",
3
- "version": "5.0.0-beta.71",
3
+ "version": "5.0.0-beta.72",
4
4
  "description": "Accessible, composable UI primitives for kerf applications.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/toolbar-text.tsx"],"names":[],"mappings":";;;;AAqDO,SAAS,WAAA,CAAY;AAAA,EAC1B,IAAA;AAAA,EACA,IAAA,GAAO,SAAA;AAAA,EACP,SAAA,GAAY,EAAA;AAAA,EACZ,EAAA;AAAA,EACA,YAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,IAAA,GAAO,KAAA;AAAA,EACP,QAAA,GAAW,IAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX,IAAA,GAAO,KAAA;AAAA,EACP;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,MAAA,GAAS,IAAA,IAAQ,QAAA,IAAY,IAAA,IAAQ,QAAA,GAAW,CAAA;AACtD,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC5C,gBAAA,EAAe,cAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,MAC3B,WAAA,EAAW,OAAO,MAAA,GAAS,MAAA;AAAA,MAC3B,eAAA,EAAe,WAAW,MAAA,GAAY,OAAA;AAAA,MACtC,gBAAA,EAAgB,MAAA,GAAS,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,MAC5C,KAAA,EAAO,MAAA,GAAS,CAAA,6BAAA,EAAgC,QAAQ,CAAA,CAAA,GAAK,MAAA;AAAA,MAC7D,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,EAAA;AAAA,MACA,IAAA,EAAM,eAAe,SAAA,GAAY,MAAA;AAAA,MACjC,YAAA,EAAY,YAAA,GAAe,MAAA,CAAO,YAAY,CAAA,GAAI,MAAA;AAAA,MAClD,WAAA,EAAW,cAAc,MAAA,GAAS,MAAA;AAAA,MAClC,IAAA;AAAA,MAEC,QAAA,EAAA,WAAA,mBACC,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAO,EAAA,CAAG,CAAC,CAAA,EAAG,CAAA,mBAExB,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,wBAAA,EAA0B,QAAA,EAAA,IAAA,EAAK;AAAA;AAAA,GAE/C;AAEJ","file":"chunk-V3DX3K65.js","sourcesContent":["import { em } from './css-values.js';\nimport { Skeleton } from './skeleton.js';\n\nexport type ToolbarTextSize =\n 'xlarge' | 'xlarge-fixed' | 'large' | 'default' | 'small' | 'xsmall';\n\n/** ARIA heading level for a title exposed as a heading landmark. */\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\ninterface ToolbarTextBaseProps {\n text: string;\n size?: ToolbarTextSize;\n className?: string;\n /** Optional id, e.g. so a dialog can reference the title via aria-labelledby. */\n id?: string;\n /**\n * Expose heading semantics (`role=\"heading\"` + `aria-level`) so the text acts as\n * a heading landmark — e.g. a page's primary title. Omit to keep the plain span\n * (the default), which suits a dialog title referenced via `aria-labelledby`.\n */\n headingLevel?: HeadingLevel;\n /** Render the text as an unanimated loading skeleton instead of its value. */\n placeholder?: boolean;\n /**\n * Show a trailing ellipsis (…) where the text is truncated — on the single line\n * (default), or at the `maxLines` boundary when wrapping. Set false to hard-clip\n * instead. Default true.\n */\n ellipsis?: boolean;\n /**\n * Grow to fill the free space of the flex row it sits in (a Toolbar zone),\n * truncating at the space left by its siblings instead of taking only its\n * text's width. Default false.\n */\n fill?: boolean;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n /**\n * Cap wrapped text to this many lines, truncating past it. Only takes effect with\n * `wrap`; ignored on a single line. `null`/omitted wraps without a line cap. Default null.\n */\n}\n\ntype ToolbarTextWrappingProps =\n | {\n /** Wrap onto multiple lines; combine with `maxLines` to cap them. */\n wrap: true;\n maxLines?: number | null;\n }\n | { wrap?: false; maxLines?: never };\n\nexport type ToolbarTextProps = ToolbarTextBaseProps & ToolbarTextWrappingProps;\n\nexport function ToolbarText({\n text,\n size = 'default',\n className = '',\n id,\n headingLevel,\n placeholder = false,\n wrap = false,\n ellipsis = true,\n maxLines = null,\n fill = false,\n slot,\n}: ToolbarTextProps) {\n const capped = wrap && maxLines != null && maxLines > 0;\n return (\n <span\n class={`kui-toolbar-text ${className}`.trim()}\n data-component=\"toolbar-text\"\n data-size={size}\n data-fill={fill ? 'true' : undefined}\n data-wrap={wrap ? 'true' : undefined}\n data-ellipsis={ellipsis ? undefined : 'false'}\n data-max-lines={capped ? String(maxLines) : undefined}\n style={capped ? `--kui-toolbar-text-max-lines:${maxLines}` : undefined}\n data-placeholder={placeholder ? 'true' : undefined}\n id={id}\n role={headingLevel ? 'heading' : undefined}\n aria-level={headingLevel ? String(headingLevel) : undefined}\n aria-busy={placeholder ? 'true' : undefined}\n slot={slot}\n >\n {placeholder ? (\n <Skeleton width={em(8)} />\n ) : (\n <span class=\"kui-toolbar-text__text\">{text}</span>\n )}\n </span>\n );\n}\n"]}