@kerfjs/ui 5.0.0-beta.57 → 5.0.0-beta.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -5
- package/ai/component-catalog.json +3 -1
- package/ai/components/toolbar-control-group.md +2 -0
- package/ai/public-api-signatures-v1.md +19 -17
- package/ai/skill.md +1 -1
- package/ai/webawesome-jsx-signatures-v1.md +1 -1
- package/dist/catalog-resources.d.ts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +2 -2
- package/dist/{chunk-G2RKFVRB.js → chunk-2CCMJTVY.js} +2 -2
- package/dist/chunk-2CCMJTVY.js.map +1 -0
- package/dist/{chunk-ZIYOJFZD.js → chunk-7JUBXOIV.js} +17 -4
- package/dist/chunk-7JUBXOIV.js.map +1 -0
- package/dist/{chunk-XCO6YCYM.js → chunk-QPUPLNNB.js} +16 -5
- package/dist/chunk-QPUPLNNB.js.map +1 -0
- package/dist/{chunk-PWXNJS2B.js → chunk-W4XKTST6.js} +2 -2
- package/dist/{chunk-PWXNJS2B.js.map → chunk-W4XKTST6.js.map} +1 -1
- package/dist/collapsible-panel.d.ts +8 -8
- package/dist/collapsible-panel.js +2 -2
- package/dist/collapsible-panel.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/nav-stack.js +1 -1
- package/dist/{panel-toolbar-BN4x0rth.d.ts → panel-toolbar-DqwtBxQL.d.ts} +10 -11
- package/dist/split-view.js +1 -1
- package/dist/toolbar-control-group.d.ts +3 -1
- package/dist/toolbar-control-group.js +1 -1
- package/dist/workbench.d.ts +5 -5
- package/dist/workbench.js +1 -1
- package/docs/collapsible-panel.md +12 -7
- package/docs/component-selection.md +3 -2
- package/docs/workbench.md +12 -11
- package/package.json +1 -1
- package/dist/chunk-G2RKFVRB.js.map +0 -1
- package/dist/chunk-XCO6YCYM.js.map +0 -1
- package/dist/chunk-ZIYOJFZD.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-PWXNJS2B.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.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 /** 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 /** 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 /** 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 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={top?.toolbar}\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 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-W4XKTST6.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.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 /** 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 /** 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 /** 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 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={top?.toolbar}\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 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,7 +1,7 @@
|
|
|
1
1
|
import { SafeHtml } from 'kerfjs';
|
|
2
2
|
import { PaneConfig } from './pane.js';
|
|
3
|
-
import { P as PanelSide, a as PanelToolbar, b as PanelToggle } from './panel-toolbar-
|
|
4
|
-
export { c as collapsiblePanelToggleIcon } from './panel-toolbar-
|
|
3
|
+
import { P as PanelSide, a as PanelToolbar, b as PanelToggle } from './panel-toolbar-DqwtBxQL.js';
|
|
4
|
+
export { c as collapsiblePanelToggleIcon } from './panel-toolbar-DqwtBxQL.js';
|
|
5
5
|
import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
|
|
6
6
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
7
7
|
import './lucide-icon.js';
|
|
@@ -14,10 +14,10 @@ type CollapsiblePanelSide = PanelSide;
|
|
|
14
14
|
/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */
|
|
15
15
|
type CollapsiblePanelToolbarToggle = PanelToggle;
|
|
16
16
|
/**
|
|
17
|
-
* A panel's composed top toolbar.
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* A panel's composed top toolbar. Its groups occupy `leading`, `center`, and
|
|
18
|
+
* `trailing` while open; groups marked `relocateOnCollapse` and the standard
|
|
19
|
+
* toggle move to the work-area toolbar through
|
|
20
|
+
* {@link CollapsiblePanelRelocated} while it is collapsed.
|
|
21
21
|
*/
|
|
22
22
|
type CollapsiblePanelToolbar = PanelToolbar;
|
|
23
23
|
interface CollapsiblePanelToggleProps {
|
|
@@ -60,7 +60,7 @@ interface CollapsiblePanelProps {
|
|
|
60
60
|
* The panel's top toolbar, composed so its groups follow the panel's open
|
|
61
61
|
* state. With it, `children` renders in a `Pane` below the toolbar; render
|
|
62
62
|
* {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the
|
|
63
|
-
*
|
|
63
|
+
* marked groups and toggle stay reachable while the panel is collapsed.
|
|
64
64
|
*/
|
|
65
65
|
toolbar?: CollapsiblePanelToolbar;
|
|
66
66
|
/** Optional bottom toolbar under a `toolbar` panel's content. */
|
|
@@ -109,7 +109,7 @@ interface CollapsiblePanelRelocatedProps {
|
|
|
109
109
|
toolbar: CollapsiblePanelToolbar;
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
|
-
* A collapsed {@link CollapsiblePanel}'s
|
|
112
|
+
* A collapsed {@link CollapsiblePanel}'s marked groups and standard
|
|
113
113
|
* toggle, for the app's work-area toolbar — nothing while the panel is open.
|
|
114
114
|
* Put it first in the leading zone for a left rail, last in the trailing zone
|
|
115
115
|
* for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { collapsiblePanelToggleIcon, composedPanelBody, relocatedPanelGroups } from './chunk-
|
|
2
|
-
export { collapsiblePanelToggleIcon } from './chunk-
|
|
1
|
+
import { collapsiblePanelToggleIcon, composedPanelBody, relocatedPanelGroups } from './chunk-QPUPLNNB.js';
|
|
2
|
+
export { collapsiblePanelToggleIcon } from './chunk-QPUPLNNB.js';
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":"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","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n collapsiblePanelToggleIcon,\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type {\n ResizableRegionCollapseMotion,\n ResizableRegionContentOverflow,\n ResizableRegionPresentation,\n ResizableRegionRestorePosition,\n ResizableRegionSeparator,\n} from './resizable-region.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport { collapsiblePanelToggleIcon } from './panel-toolbar.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = PanelSide;\n\n/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */\nexport type CollapsiblePanelToolbarToggle = PanelToggle;\n\n/**\n * A panel's composed top toolbar. `title` and `panelOnly` groups lead it and\n * are available only while the panel is open; `constant` groups and the\n * standard `toggle` trail it while open and move to the app's work-area\n * toolbar — through {@link CollapsiblePanelRelocated} — while it is collapsed.\n */\nexport type CollapsiblePanelToolbar = PanelToolbar;\n\n/** A CollapsiblePanel toggle's `wireSidebar` hook. */\nconst toggleAttributes = (panelId: string): PanelToggleAttributes => ({\n 'data-collapsible-target': panelId,\n // Keyed, so the morph never reuses a (possibly focused) toggle's button for\n // another control as the toggle moves between toolbars.\n 'data-key': `${panelId}-toggle`,\n});\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n slot,\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n slot={slot}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: KerfUiContent;\n /**\n * The panel's top toolbar, composed so its groups follow the panel's open\n * state. With it, `children` renders in a `Pane` below the toolbar; render\n * {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the\n * `constant` groups and toggle stay reachable while the panel is collapsed.\n */\n toolbar?: CollapsiblePanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `children` renders as given.\n */\n pane?: PaneConfig;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /** Control shown while collapsed, in a safe-area-aware corner of the panel's container (not the viewport). */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). Bottom-drawer content stays anchored\n * to the panel's fixed bottom edge, so the track cannot move its layout origin\n * underneath the transform transition. A collapsed panel renders `inert` (with\n * `aria-hidden`), so neither Tab, pointer, nor assistive technology reaches\n * content that has slid out of view; its `restoreControl` renders outside the\n * panel and stays reachable.\n * The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n toolbar,\n footer,\n pane,\n separator = 'auto',\n collapseMotion = 'slide',\n contentOverflow = 'clip',\n presentation = 'inline',\n restoreControl,\n restorePosition = side === 'left' ? 'bottom-start' : 'bottom-end',\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <>\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n data-separator={separator}\n data-collapse-motion={collapseMotion}\n data-content-overflow={contentOverflow}\n data-presentation={presentation}\n aria-label={label || undefined}\n aria-hidden={\n collapsed || presentation === 'hidden' ? 'true' : undefined\n }\n inert={collapsed}\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">\n {toolbar\n ? composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes: toggleAttributes(id),\n pane,\n footer,\n content: children,\n })\n : children}\n </div>\n </aside>\n {collapsed && restoreControl && presentation !== 'hidden' && (\n <div\n class=\"kui-collapsible-panel__restore\"\n data-panel-restore={id}\n data-position={restorePosition}\n >\n {restoreControl}\n </div>\n )}\n </>\n );\n}\n\nexport interface CollapsiblePanelRelocatedProps {\n /** The panel's `id`. */\n panelId: string;\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state. */\n collapsed: boolean;\n /** The same `toolbar` the panel receives. */\n toolbar: CollapsiblePanelToolbar;\n}\n\n/**\n * A collapsed {@link CollapsiblePanel}'s `constant` groups and standard\n * toggle, for the app's work-area toolbar — nothing while the panel is open.\n * Put it first in the leading zone for a left rail, last in the trailing zone\n * for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`\n * `restoreControl`) for a bottom drawer. `wireSidebar` hands focus to it when\n * the panel closes from its own toggle.\n */\nexport function CollapsiblePanelRelocated({\n panelId,\n side,\n collapsed,\n toolbar,\n}: CollapsiblePanelRelocatedProps) {\n return (\n <>\n {relocatedPanelGroups(\n toolbar,\n side,\n collapsed,\n toggleAttributes(panelId),\n )}\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":"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","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n collapsiblePanelToggleIcon,\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type {\n ResizableRegionCollapseMotion,\n ResizableRegionContentOverflow,\n ResizableRegionPresentation,\n ResizableRegionRestorePosition,\n ResizableRegionSeparator,\n} from './resizable-region.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport { collapsiblePanelToggleIcon } from './panel-toolbar.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = PanelSide;\n\n/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */\nexport type CollapsiblePanelToolbarToggle = PanelToggle;\n\n/**\n * A panel's composed top toolbar. Its groups occupy `leading`, `center`, and\n * `trailing` while open; groups marked `relocateOnCollapse` and the standard\n * toggle move to the work-area toolbar through\n * {@link CollapsiblePanelRelocated} while it is collapsed.\n */\nexport type CollapsiblePanelToolbar = PanelToolbar;\n\n/** A CollapsiblePanel toggle's `wireSidebar` hook. */\nconst toggleAttributes = (panelId: string): PanelToggleAttributes => ({\n 'data-collapsible-target': panelId,\n // Keyed, so the morph never reuses a (possibly focused) toggle's button for\n // another control as the toggle moves between toolbars.\n 'data-key': `${panelId}-toggle`,\n});\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n slot,\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n slot={slot}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: KerfUiContent;\n /**\n * The panel's top toolbar, composed so its groups follow the panel's open\n * state. With it, `children` renders in a `Pane` below the toolbar; render\n * {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the\n * marked groups and toggle stay reachable while the panel is collapsed.\n */\n toolbar?: CollapsiblePanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `children` renders as given.\n */\n pane?: PaneConfig;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /** Control shown while collapsed, in a safe-area-aware corner of the panel's container (not the viewport). */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). Bottom-drawer content stays anchored\n * to the panel's fixed bottom edge, so the track cannot move its layout origin\n * underneath the transform transition. A collapsed panel renders `inert` (with\n * `aria-hidden`), so neither Tab, pointer, nor assistive technology reaches\n * content that has slid out of view; its `restoreControl` renders outside the\n * panel and stays reachable.\n * The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n toolbar,\n footer,\n pane,\n separator = 'auto',\n collapseMotion = 'slide',\n contentOverflow = 'clip',\n presentation = 'inline',\n restoreControl,\n restorePosition = side === 'left' ? 'bottom-start' : 'bottom-end',\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <>\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n data-separator={separator}\n data-collapse-motion={collapseMotion}\n data-content-overflow={contentOverflow}\n data-presentation={presentation}\n aria-label={label || undefined}\n aria-hidden={\n collapsed || presentation === 'hidden' ? 'true' : undefined\n }\n inert={collapsed}\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">\n {toolbar\n ? composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes: toggleAttributes(id),\n pane,\n footer,\n content: children,\n })\n : children}\n </div>\n </aside>\n {collapsed && restoreControl && presentation !== 'hidden' && (\n <div\n class=\"kui-collapsible-panel__restore\"\n data-panel-restore={id}\n data-position={restorePosition}\n >\n {restoreControl}\n </div>\n )}\n </>\n );\n}\n\nexport interface CollapsiblePanelRelocatedProps {\n /** The panel's `id`. */\n panelId: string;\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state. */\n collapsed: boolean;\n /** The same `toolbar` the panel receives. */\n toolbar: CollapsiblePanelToolbar;\n}\n\n/**\n * A collapsed {@link CollapsiblePanel}'s marked groups and standard\n * toggle, for the app's work-area toolbar — nothing while the panel is open.\n * Put it first in the leading zone for a left rail, last in the trailing zone\n * for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`\n * `restoreControl`) for a bottom drawer. `wireSidebar` hands focus to it when\n * the panel closes from its own toggle.\n */\nexport function CollapsiblePanelRelocated({\n panelId,\n side,\n collapsed,\n toolbar,\n}: CollapsiblePanelRelocatedProps) {\n return (\n <>\n {relocatedPanelGroups(\n toolbar,\n side,\n collapsed,\n toggleAttributes(panelId),\n )}\n </>\n );\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -33,7 +33,7 @@ export { Text } from './chunk-24PHKUR3.js';
|
|
|
33
33
|
export { DisclosureArrow } from './chunk-KROD7KZK.js';
|
|
34
34
|
export { Skeleton } from './chunk-AHEG27M7.js';
|
|
35
35
|
export { Badge } from './chunk-MP2GDBQZ.js';
|
|
36
|
-
export { ToolbarActionLink, ToolbarControlGroup } from './chunk-
|
|
36
|
+
export { ToolbarActionLink, ToolbarControlGroup } from './chunk-7JUBXOIV.js';
|
|
37
37
|
export { Toolbar } from './chunk-6YFHCLHG.js';
|
|
38
38
|
export { Pane } from './chunk-EZVNC4J6.js';
|
|
39
39
|
export { LucideIcon } from './chunk-4R777DUZ.js';
|
package/dist/nav-stack.js
CHANGED
|
@@ -33,17 +33,17 @@ interface PanelToggle {
|
|
|
33
33
|
* A collapsible panel's top toolbar, composed so its groups follow the
|
|
34
34
|
* panel's open state.
|
|
35
35
|
*
|
|
36
|
-
* - `title`
|
|
37
|
-
*
|
|
38
|
-
* - `
|
|
39
|
-
*
|
|
40
|
-
* collapsed.
|
|
36
|
+
* - `title` precedes the `leading` zone. Groups may appear in any of the
|
|
37
|
+
* `leading`, `center`, and `trailing` zones while the panel is open.
|
|
38
|
+
* - Groups marked `relocateOnCollapse` move to the work area's toolbar while
|
|
39
|
+
* the panel is collapsed, preserving their order across the three zones.
|
|
41
40
|
* - `toggle` is always the last group: in the panel's toolbar while it is
|
|
42
|
-
* open, and right after the
|
|
41
|
+
* open, and right after the relocated groups in the work area's toolbar
|
|
43
42
|
* while it is collapsed.
|
|
44
43
|
*
|
|
45
|
-
*
|
|
46
|
-
* panel's copy is inert), so give it no `id`s.
|
|
44
|
+
* Relocated content renders in both places while the panel is collapsed (the
|
|
45
|
+
* panel's copy is inert), so give it no `id`s. Pass groups directly or in
|
|
46
|
+
* arrays so their render-time annotation remains available to the panel.
|
|
47
47
|
*
|
|
48
48
|
* The toolbar's configuration (`dividerSides`, `centerAlign`, `responsive`,
|
|
49
49
|
* `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar`. It draws no
|
|
@@ -54,10 +54,9 @@ interface PanelToolbar extends ToolbarConfig {
|
|
|
54
54
|
/** Accessible name of the panel's toolbar. */
|
|
55
55
|
label: string;
|
|
56
56
|
title?: KerfUiContent;
|
|
57
|
-
|
|
58
|
-
/** Panel-only center content, available only while the panel is open. */
|
|
57
|
+
leading?: KerfUiContent;
|
|
59
58
|
center?: KerfUiContent;
|
|
60
|
-
|
|
59
|
+
trailing?: KerfUiContent;
|
|
61
60
|
toggle?: PanelToggle;
|
|
62
61
|
}
|
|
63
62
|
|
package/dist/split-view.js
CHANGED
|
@@ -56,6 +56,8 @@ interface ToolbarControlGroupProps {
|
|
|
56
56
|
overflow?: ToolbarControlGroupOverflow;
|
|
57
57
|
/** Responsive visibility owned by the enclosing Toolbar container. */
|
|
58
58
|
visibility?: ToolbarControlGroupVisibility;
|
|
59
|
+
/** Move this group into the work-area toolbar when its panel collapses. */
|
|
60
|
+
relocateOnCollapse?: boolean;
|
|
59
61
|
/** Add contrast behind photo-backed avatar content. */
|
|
60
62
|
scrim?: boolean;
|
|
61
63
|
/**
|
|
@@ -66,6 +68,6 @@ interface ToolbarControlGroupProps {
|
|
|
66
68
|
/** Native named-slot assignment when composed inside a web component. */
|
|
67
69
|
slot?: string;
|
|
68
70
|
}
|
|
69
|
-
declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, size, density, content, focusRing, selectedChrome, selectedTone, nestedDropdown, menuInset, overflow, visibility, scrim, avatarImage, slot, }: ToolbarControlGroupProps): kerfjs.SafeHtml;
|
|
71
|
+
declare function ToolbarControlGroup({ children, label, className, expanded, single, appearance, tone, buttonAppearance, shape, size, density, content, focusRing, selectedChrome, selectedTone, nestedDropdown, menuInset, overflow, visibility, relocateOnCollapse, scrim, avatarImage, slot, }: ToolbarControlGroupProps): kerfjs.SafeHtml;
|
|
70
72
|
|
|
71
73
|
export { ToolbarActionLink, type ToolbarActionLinkProps, ToolbarControlGroup, type ToolbarControlGroupAppearance, type ToolbarControlGroupButtonAppearance, type ToolbarControlGroupContent, type ToolbarControlGroupDensity, type ToolbarControlGroupFocusRing, type ToolbarControlGroupMenuInset, type ToolbarControlGroupOverflow, type ToolbarControlGroupProps, type ToolbarControlGroupSelectedChrome, type ToolbarControlGroupSelectedTone, type ToolbarControlGroupShape, type ToolbarControlGroupSize, type ToolbarControlGroupTone, type ToolbarControlGroupVisibility };
|
package/dist/workbench.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ListConfig } from './list.js';
|
|
|
3
3
|
import { PaneConfig } from './pane.js';
|
|
4
4
|
import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
|
|
5
5
|
import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
|
|
6
|
-
import { a as PanelToolbar, b as PanelToggle } from './panel-toolbar-
|
|
6
|
+
import { a as PanelToolbar, b as PanelToggle } from './panel-toolbar-DqwtBxQL.js';
|
|
7
7
|
import { ToolbarConfig } from './toolbar.js';
|
|
8
8
|
import './css-values.js';
|
|
9
9
|
import './flex-alignment-4ms8ZbV8.js';
|
|
@@ -16,7 +16,7 @@ type WorkbenchPanelToggle = PanelToggle;
|
|
|
16
16
|
/**
|
|
17
17
|
* A Workbench panel's top toolbar, composed by the Workbench so its groups can
|
|
18
18
|
* follow the panel's open state (see {@link PanelToolbar} for the roles).
|
|
19
|
-
* A collapsed rail's
|
|
19
|
+
* A collapsed rail's marked groups and toggle go to the leading edge of
|
|
20
20
|
* `mainToolbar` (left rail) or its trailing edge (right rail); a collapsed
|
|
21
21
|
* drawer's go to the trailing edge of `mainBottomToolbar`, else to a
|
|
22
22
|
* `FloatingToolbar` in the work area's bottom-end corner.
|
|
@@ -83,7 +83,7 @@ interface WorkbenchPanelResizable {
|
|
|
83
83
|
interface WorkbenchPanel {
|
|
84
84
|
content: KerfUiContent;
|
|
85
85
|
/**
|
|
86
|
-
* The panel's top toolbar, composed by the Workbench: its
|
|
86
|
+
* The panel's top toolbar, composed by the Workbench: its marked groups
|
|
87
87
|
* and standard `toggle` move to the work area's toolbar while the panel is
|
|
88
88
|
* collapsed. With it, `content` renders in a `Pane` below the toolbar.
|
|
89
89
|
*/
|
|
@@ -154,7 +154,7 @@ interface WorkbenchProps {
|
|
|
154
154
|
/** The central work area. */
|
|
155
155
|
main: KerfUiContent;
|
|
156
156
|
/**
|
|
157
|
-
* The work area's top toolbar. A collapsed left rail's
|
|
157
|
+
* The work area's top toolbar. A collapsed left rail's marked groups
|
|
158
158
|
* and toggle lead it; a collapsed right rail's trail it. With it, `main`
|
|
159
159
|
* renders in a `Pane` below the toolbar.
|
|
160
160
|
*/
|
|
@@ -170,7 +170,7 @@ interface WorkbenchProps {
|
|
|
170
170
|
*/
|
|
171
171
|
mainFooter?: KerfUiContent;
|
|
172
172
|
/**
|
|
173
|
-
* The work area's bottom toolbar. A collapsed drawer's
|
|
173
|
+
* The work area's bottom toolbar. A collapsed drawer's marked groups and
|
|
174
174
|
* toggle trail it; without it they float in the work area's corner.
|
|
175
175
|
*/
|
|
176
176
|
mainBottomToolbar?: WorkbenchMainBottomToolbar;
|
package/dist/workbench.js
CHANGED
|
@@ -129,10 +129,11 @@ Give a panel a `toolbar` (the same roles as a
|
|
|
129
129
|
[Workbench panel toolbar](workbench.md#panel-toolbars)) and it composes its own
|
|
130
130
|
top toolbar over a `Pane`, with an optional `footer` below its content:
|
|
131
131
|
|
|
132
|
-
- `title`
|
|
133
|
-
|
|
134
|
-
- `
|
|
135
|
-
|
|
132
|
+
- `title` precedes the `leading` zone; `leading`, `center`, and `trailing`
|
|
133
|
+
place groups wherever the open panel needs them;
|
|
134
|
+
- a `ToolbarControlGroup` marked `relocateOnCollapse` stays available in the
|
|
135
|
+
work area when the panel closes; the standard `toggle: { action, name,
|
|
136
|
+
showLabel?, hideLabel? }` is always the final group.
|
|
136
137
|
|
|
137
138
|
The toolbar also takes the `Toolbar`'s configuration (`dividerSides`,
|
|
138
139
|
`centerAlign`, `responsive`, `responsiveAt`, `safeAreaEdges`); it draws no
|
|
@@ -147,17 +148,21 @@ field keeps the `Pane` default; without a `toolbar` there is no `Pane`, so
|
|
|
147
148
|
|
|
148
149
|
A standalone panel does not own the rest of the screen, so the app places a
|
|
149
150
|
`CollapsiblePanelRelocated` in its own work-area toolbar: it renders the panel's
|
|
150
|
-
|
|
151
|
+
marked groups and toggle while the panel is collapsed, and nothing while it
|
|
151
152
|
is open. Put it first in the leading zone for a left rail, last in the trailing
|
|
152
153
|
zone for a right rail, and last in a bottom toolbar for a bottom drawer. With no
|
|
153
154
|
bottom toolbar, pass it inside a `FloatingToolbar` as the drawer's
|
|
154
155
|
`restoreControl`.
|
|
156
|
+
Marked groups move in `leading`, `center`, `trailing` order. Pass each marked
|
|
157
|
+
group directly or in an array rather than wrapping it in a JSX fragment, so
|
|
158
|
+
the panel can read its render-time annotation. Its copy in the closed panel is
|
|
159
|
+
inert; avoid duplicate `id` attributes on marked groups.
|
|
155
160
|
|
|
156
161
|
```tsx
|
|
157
162
|
const toolbar: CollapsiblePanelToolbar = {
|
|
158
163
|
label: "Navigator",
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
leading: <NewFileGroup />,
|
|
165
|
+
trailing: <ToolbarControlGroup relocateOnCollapse label="Search files"><SearchButton /></ToolbarControlGroup>,
|
|
161
166
|
toggle: { action: "toggle-nav", name: "navigator" },
|
|
162
167
|
};
|
|
163
168
|
|
|
@@ -191,9 +191,10 @@ an upstream component or recipe request.
|
|
|
191
191
|
on the component instead of adding application descendant width/height fixes.
|
|
192
192
|
It paints `--kui-color-surface` itself (an inline region stays transparent),
|
|
193
193
|
so do not add a background to make an overlay opaque.
|
|
194
|
-
- Give `Workbench` panels a `toolbar` (title,
|
|
194
|
+
- Give `Workbench` panels a `toolbar` (title, `leading` / `center` / `trailing`
|
|
195
195
|
groups, and a standard `toggle`) and the work area a `mainToolbar` /
|
|
196
|
-
`mainBottomToolbar`: the Workbench moves a closed panel's
|
|
196
|
+
`mainBottomToolbar`: the Workbench moves a closed panel's groups marked
|
|
197
|
+
`relocateOnCollapse`
|
|
197
198
|
and toggle into the work area's toolbar, so never hand-place or duplicate
|
|
198
199
|
panel toggles. See [Workbench panel toolbars](workbench.md#panel-toolbars).
|
|
199
200
|
- Configure application panels through the shared `separator`, `collapseMotion`,
|
package/docs/workbench.md
CHANGED
|
@@ -158,22 +158,23 @@ A panel's controls follow it open and closed when the Workbench composes the
|
|
|
158
158
|
toolbars. Give a panel a `toolbar` and the work area a `mainToolbar` (and, for
|
|
159
159
|
a drawer, optionally a `mainBottomToolbar`); the Workbench renders each as a
|
|
160
160
|
standard `Toolbar` over a `Pane`, and moves groups between them as panels open
|
|
161
|
-
and close. A panel's `toolbar` has
|
|
161
|
+
and close. A panel's `toolbar` has these parts:
|
|
162
162
|
|
|
163
163
|
- `title` — the panel's `ToolbarText` (the quiet default size in a rail).
|
|
164
|
-
- `
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
164
|
+
- `leading`, `center`, and `trailing` — the open panel's toolbar zones. Put
|
|
165
|
+
`ToolbarControlGroup`s in any order in these zones. Mark a group with
|
|
166
|
+
`relocateOnCollapse` to make it available in the work area while the panel
|
|
167
|
+
is closed; unmarked groups remain in the inert panel. Pass marked groups
|
|
168
|
+
directly or in arrays, including nested arrays, rather than JSX fragments
|
|
169
|
+
so their render-time annotation remains available.
|
|
169
170
|
- `toggle: { action, name, showLabel?, hideLabel? }` — the standard collapse
|
|
170
171
|
toggle, which the Workbench renders: the per-side panel glyph,
|
|
171
172
|
`aria-controls` naming the panel, `aria-expanded`, a "Show …"/"Hide …"
|
|
172
173
|
label (or your localized `showLabel` / `hideLabel`), and the `data-action`
|
|
173
174
|
the app handles. It is always the last group.
|
|
174
|
-
- `center` — optional panel-only center content.
|
|
175
175
|
|
|
176
|
-
While a panel is closed,
|
|
176
|
+
While a panel is closed, marked groups follow their open-panel zone order
|
|
177
|
+
(`leading`, `center`, `trailing`), followed by its toggle:
|
|
177
178
|
|
|
178
179
|
| Panel | Where they go |
|
|
179
180
|
| ------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
@@ -197,8 +198,8 @@ toggle, so it never depends on a control it covers. An app's own
|
|
|
197
198
|
toolbar: {
|
|
198
199
|
label: "Navigator",
|
|
199
200
|
title: <ToolbarText text="Navigator" />,
|
|
200
|
-
|
|
201
|
-
|
|
201
|
+
leading: <NewFileGroup />,
|
|
202
|
+
trailing: <ToolbarControlGroup relocateOnCollapse label="Search files"><SearchButton /></ToolbarControlGroup>,
|
|
202
203
|
toggle: { action: "toggle-navigator", name: "navigator" },
|
|
203
204
|
},
|
|
204
205
|
content: <Files />,
|
|
@@ -249,7 +250,7 @@ dividers described above.
|
|
|
249
250
|
|
|
250
251
|
Size a rail so its title and groups fit at its narrowest (a resizable rail's
|
|
251
252
|
`min`); a toolbar that cannot hold them drops the title rather than
|
|
252
|
-
truncating it.
|
|
253
|
+
truncating it. Relocated content renders in both places while the panel is
|
|
253
254
|
closed (the panel's copy is inert), so give it no `id`s. With `wireWorkbench`
|
|
254
255
|
given the panel's `collapsed` signal, focus follows the toggle: closing a
|
|
255
256
|
panel from its own toggle focuses the relocated toggle in the work area, and
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/workbench-toolbars.tsx","../src/workbench.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"chunk-G2RKFVRB.js","sourcesContent":["import {\n FloatingToolbar,\n type FloatingToolbarPosition,\n} from './floating-toolbar.js';\nimport { List, type ListConfig } from './list.js';\nimport { Pane, type PaneConfig } from './pane.js';\nimport {\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\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 `constant` 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;\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 footer?: KerfUiContent;\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 `constant` 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 return relocatedPanelGroups(\n panel?.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 (!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 footer: panel.footer,\n content: panel.content,\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 = 'fixed' | 'scroll' | 'auto';\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 and `mainPane` is ignored.\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 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 >\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 { 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 WorkbenchPanelToolbar,\n} from './workbench-toolbars.js';\n\nexport type {\n WorkbenchChromePlacement,\n WorkbenchMainBottomToolbar,\n WorkbenchMainToolbar,\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 = 'compact' | 'narrow' | 'never';\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/** A collapsible Workbench panel — a side rail or the bottom drawer. */\nexport interface WorkbenchPanel {\n content: KerfUiContent;\n /**\n * The panel's top toolbar, composed by the Workbench: its `constant` groups\n * and standard `toggle` move to the work area's toolbar while the panel is\n * collapsed. With it, `content` renders in a `Pane` below the toolbar.\n */\n toolbar?: WorkbenchPanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `content` renders as given.\n */\n pane?: PaneConfig;\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 — the CSS decides, so the app\n * needs no device-class check. 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\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 `constant` 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 `constant` 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 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\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-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-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 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 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 class=\"kui-workbench__main\" data-workbench-main>\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 </section>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/panel-toolbar.tsx"],"names":[],"mappings":"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","file":"chunk-XCO6YCYM.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport {\n PanelBottomClose,\n PanelBottomOpen,\n PanelLeftClose,\n PanelLeftOpen,\n PanelRightClose,\n PanelRightOpen,\n} from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport { Pane, type PaneConfig } from './pane.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\n\n/** Which edge a collapsible panel docks to. */\nexport type PanelSide = 'left' | 'right' | 'bottom';\n\n/**\n * The standard collapse/expand icon for a panel `side` and `collapsed` state,\n * so every app's sidebars and drawers use one recognizable convention:\n * `PanelLeft*` for a left rail, `PanelRight*` for a right rail, `PanelBottom*`\n * for a bottom drawer — the `Close` glyph while open, the `Open` glyph while\n * collapsed. Exposed so an app can render its own toggle affordance.\n */\nexport function collapsiblePanelToggleIcon(\n side: PanelSide,\n collapsed: boolean,\n): { icon: Parameters<typeof LucideIcon>[0]['icon']; name: string } {\n if (side === 'left')\n return collapsed\n ? { icon: PanelLeftOpen, name: 'panel-left-open' }\n : { icon: PanelLeftClose, name: 'panel-left-close' };\n if (side === 'right')\n return collapsed\n ? { icon: PanelRightOpen, name: 'panel-right-open' }\n : { icon: PanelRightClose, name: 'panel-right-close' };\n return collapsed\n ? { icon: PanelBottomOpen, name: 'panel-bottom-open' }\n : { icon: PanelBottomClose, name: 'panel-bottom-close' };\n}\n\n/**\n * The standard collapse toggle a panel toolbar renders. The app handles the\n * button's `data-action` and flips its own `collapsed` flag.\n */\nexport interface PanelToggle {\n /** The `data-action` the toggle button carries. */\n action: string;\n /** The panel's short name, for the accessible \"Show …\" / \"Hide …\" label. */\n name: string;\n /** Accessible label while the panel is collapsed. Defaults to `Show {name}`. */\n showLabel?: string;\n /** Accessible label while the panel is open. Defaults to `Hide {name}`. */\n hideLabel?: string;\n}\n\n/**\n * A collapsible panel's top toolbar, composed so its groups follow the\n * panel's open state.\n *\n * - `title` (a `ToolbarText`) and `panelOnly` groups lead the toolbar and are\n * available only while the panel is open.\n * - `constant` groups stay available either way: they trail the panel's\n * toolbar while it is open and move to the work area's toolbar while it is\n * collapsed.\n * - `toggle` is always the last group: in the panel's toolbar while it is\n * open, and right after the `constant` groups in the work area's toolbar\n * while it is collapsed.\n *\n * `constant` content renders in both places while the panel is collapsed (the\n * panel's copy is inert), so give it no `id`s.\n *\n * The toolbar's configuration (`dividerSides`, `centerAlign`, `responsive`,\n * `responsiveAt`, `safeAreaEdges`) forwards to its `Toolbar`. It draws no\n * divider of its own: the panel's `Pane` draws the line under it while the\n * content is scrolled (its `chromeDividers`, wired by `wireScrollDividers`).\n */\nexport interface PanelToolbar extends ToolbarConfig {\n /** Accessible name of the panel's toolbar. */\n label: string;\n title?: KerfUiContent;\n panelOnly?: KerfUiContent;\n /** Panel-only center content, available only while the panel is open. */\n center?: KerfUiContent;\n constant?: KerfUiContent;\n toggle?: PanelToggle;\n}\n\n/** Owner-specific attributes a toggle button carries (its wiring hooks). */\nexport type PanelToggleAttributes = Readonly<Record<string, string>>;\n\n/** The standard toggle, alone in a borderless group. */\nexport function panelToggleGroup(\n side: PanelSide,\n toggle: PanelToggle,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n return (\n <ToolbarControlGroup label={toggle.name} appearance=\"borderless\" single>\n <button\n type=\"button\"\n {...attributes}\n data-action={toggle.action}\n aria-expanded={String(!collapsed)}\n aria-label={\n collapsed\n ? (toggle.showLabel ?? `Show ${toggle.name}`)\n : (toggle.hideLabel ?? `Hide ${toggle.name}`)\n }\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n </ToolbarControlGroup>\n );\n}\n\n/**\n * The panel's own toolbar: title and panel-only groups lead, constant groups\n * and the toggle trail.\n */\nexport function composedPanelToolbar(\n toolbar: PanelToolbar,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): SafeHtml {\n return (\n <Toolbar\n label={toolbar.label}\n dividerSides={toolbar.dividerSides}\n centerAlign={toolbar.centerAlign}\n responsive={toolbar.responsive}\n responsiveAt={toolbar.responsiveAt}\n safeAreaEdges={toolbar.safeAreaEdges}\n center={toolbar.center}\n leading={\n <>\n {toolbar.title}\n {toolbar.panelOnly}\n </>\n }\n trailing={\n <>\n {toolbar.constant}\n {toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, collapsed, attributes)\n : null}\n </>\n }\n />\n );\n}\n\n/**\n * A toolbar panel's body: its content in a `Pane` under its composed toolbar,\n * with its optional `footer` below. The panel's `pane` configuration forwards\n * to that `Pane`; an omitted or `undefined` field keeps the `Pane` default.\n */\nexport function composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes,\n pane,\n footer,\n content,\n}: {\n toolbar: PanelToolbar;\n side: PanelSide;\n collapsed: boolean;\n attributes: PanelToggleAttributes;\n pane: PaneConfig | undefined;\n footer: KerfUiContent;\n content: KerfUiContent;\n}): SafeHtml {\n return (\n <Pane\n header={composedPanelToolbar(toolbar, side, collapsed, attributes)}\n footer={footer}\n contentElement={pane?.contentElement}\n contentLabel={pane?.contentLabel}\n separators={pane?.separators}\n safeAreaEdges={pane?.safeAreaEdges}\n chromeDividers={pane?.chromeDividers}\n >\n {content}\n </Pane>\n );\n}\n\n/**\n * The groups a collapsed panel hands to the work area: its `constant` groups,\n * then its toggle. Empty while the panel is open or has no toolbar.\n */\nexport function relocatedPanelGroups(\n toolbar: PanelToolbar | undefined,\n side: PanelSide,\n collapsed: boolean,\n attributes: PanelToggleAttributes,\n): KerfUiContent[] {\n if (!collapsed || !toolbar) return [];\n return [\n toolbar.constant,\n toolbar.toggle\n ? panelToggleGroup(side, toolbar.toggle, true, attributes)\n : null,\n ].filter((group) => group !== undefined && group !== null && group !== false);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/toolbar-control-group.tsx"],"names":[],"mappings":";;;AAiCO,SAAS,iBAAA,CAAkB;AAAA,EAChC,IAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAA2B;AACzB,EAAA,MAAM,eAAA,GACJ,SAAA,IACA,CAAA,EAAG,KAAK,CAAA,EAAG,MAAA,GAAS,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,GAAK,EAAE,CAAA,EAAG,QAAA,GAAW,wBAAwB,EAAE,CAAA,CAAA;AAChF,EAAA,uBACE,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,wBAAA,EAA2B,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACnD,gBAAA,EAAe,qBAAA;AAAA,MACf,IAAA;AAAA,MACA,MAAA,EAAQ,WAAW,QAAA,GAAW,MAAA;AAAA,MAC9B,GAAA,EAAK,WAAW,qBAAA,GAAwB,MAAA;AAAA,MACxC,YAAA,EAAY,eAAA;AAAA,MACZ,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,IAAA;AAAA,wBACD,GAAA,CAAC,UAAM,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QACZ,yBAAS,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAQ,kBAAO,CAAA,GAAU;AAAA;AAAA;AAAA,GACvD;AAEJ;AAuCO,SAAS,mBAAA,CAAoB;AAAA,EAClC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS,KAAA;AAAA,EACT,UAAA,GAAa,WAAA;AAAA,EACb,IAAA,GAAO,SAAA;AAAA,EACP,gBAAA,GAAmB,OAAA;AAAA,EACnB,KAAA,GAAQ,MAAA;AAAA,EACR,IAAA,GAAO,SAAA;AAAA,EACP,OAAA,GAAU,aAAA;AAAA,EACV,OAAA,GAAU,MAAA;AAAA,EACV,SAAA,GAAY,SAAA;AAAA,EACZ,cAAA,GAAiB,QAAA;AAAA,EACjB,YAAA,GAAe,OAAA;AAAA,EACf,cAAA,GAAiB,KAAA;AAAA,EACjB,SAAA,GAAY,UAAA;AAAA,EACZ,QAAA,GAAW,SAAA;AAAA,EACX,UAAA,GAAa,QAAA;AAAA,EACb,KAAA,GAAQ,KAAA;AAAA,EACR,WAAA;AAAA,EACA;AACF,CAAA,EAA6B;AAC3B,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,0BAAA,EAA6B,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACrD,gBAAA,EAAe,uBAAA;AAAA,MACf,IAAA,EAAM,QAAQ,OAAA,GAAU,MAAA;AAAA,MACxB,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,WAAA,EAAW,IAAA;AAAA,MACX,wBAAA,EAAwB,gBAAA;AAAA,MACxB,eAAA,EAAe,OAAO,QAAQ,CAAA;AAAA,MAC9B,aAAA,EAAa,OAAO,MAAM,CAAA;AAAA,MAC1B,YAAA,EAAY,KAAA;AAAA,MACZ,WAAA,EAAW,IAAA;AAAA,MACX,cAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAc,OAAA;AAAA,MACd,iBAAA,EAAiB,SAAA;AAAA,MACjB,sBAAA,EAAsB,cAAA;AAAA,MACtB,oBAAA,EAAoB,YAAA;AAAA,MACpB,sBAAA,EAAsB,OAAO,cAAc,CAAA;AAAA,MAC3C,iBAAA,EAAiB,SAAA;AAAA,MACjB,eAAA,EAAe,QAAA;AAAA,MACf,iBAAA,EAAiB,UAAA;AAAA,MACjB,YAAA,EAAY,OAAO,KAAK,CAAA;AAAA,MACxB,OACE,WAAA,GACI,CAAA,+BAAA,EAAkC,KAAK,SAAA,CAAU,WAAW,CAAC,CAAA,CAAA,CAAA,GAC7D,MAAA;AAAA,MAEN,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-ZIYOJFZD.js","sourcesContent":["import type { KerfUiContent } from './semantic-content.js';\n\nexport type ToolbarControlGroupAppearance = 'contained' | 'borderless';\nexport type ToolbarControlGroupTone = 'default' | 'dark';\nexport type ToolbarControlGroupButtonAppearance = 'plain' | 'push';\nexport type ToolbarControlGroupShape = 'pill' | 'rounded';\nexport type ToolbarControlGroupSize = 'default' | 'compact';\nexport type ToolbarControlGroupDensity = 'comfortable' | 'tight';\nexport type ToolbarControlGroupContent =\n 'icon' | 'text' | 'mixed' | 'avatar' | 'search';\nexport type ToolbarControlGroupFocusRing = 'control' | 'outline' | 'halo';\nexport type ToolbarControlGroupSelectedChrome = 'raised' | 'filled' | 'outline';\nexport type ToolbarControlGroupSelectedTone = 'brand' | 'neutral' | 'pop';\nexport type ToolbarControlGroupOverflow = 'visible' | 'scroll';\nexport type ToolbarControlGroupMenuInset = 'standard' | 'compact' | 'list-zero';\nexport type ToolbarControlGroupVisibility = 'always' | 'compact-only';\n\nexport interface ToolbarActionLinkProps {\n href: string;\n label: string;\n icon?: KerfUiContent;\n /** Optional machine-readable detail hidden visually but included in the default accessible name. */\n detail?: string;\n /** Override the accessible name when surrounding context is needed. */\n ariaLabel?: string;\n /** Open in a new tab with a safe rel and announce that behavior. */\n external?: boolean;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A semantic anchor with ToolbarControlGroup-owned action geometry. */\nexport function ToolbarActionLink({\n href,\n label,\n icon,\n detail,\n ariaLabel,\n external = false,\n className = '',\n slot,\n}: ToolbarActionLinkProps) {\n const accessibleLabel =\n ariaLabel ??\n `${label}${detail ? `, ${detail}` : ''}${external ? ' (opens in new tab)' : ''}`;\n return (\n <a\n class={`kui-toolbar-action-link ${className}`.trim()}\n data-component=\"toolbar-action-link\"\n href={href}\n target={external ? '_blank' : undefined}\n rel={external ? 'noopener noreferrer' : undefined}\n aria-label={accessibleLabel}\n slot={slot}\n >\n {icon}\n <span>{label}</span>\n {detail ? <code aria-hidden=\"true\">{detail}</code> : null}\n </a>\n );\n}\n\nexport interface ToolbarControlGroupProps {\n children: KerfUiContent;\n label?: string;\n className?: string;\n expanded?: boolean;\n single?: boolean;\n appearance?: ToolbarControlGroupAppearance;\n tone?: ToolbarControlGroupTone;\n buttonAppearance?: ToolbarControlGroupButtonAppearance;\n /** Corner shape: fully round `pill` (default) or a softer `rounded` rectangle. */\n shape?: ToolbarControlGroupShape;\n size?: ToolbarControlGroupSize;\n density?: ToolbarControlGroupDensity;\n content?: ToolbarControlGroupContent;\n /** Whether controls paint focus individually or the group paints an outline/halo on focus-within. */\n focusRing?: ToolbarControlGroupFocusRing;\n selectedChrome?: ToolbarControlGroupSelectedChrome;\n selectedTone?: ToolbarControlGroupSelectedTone;\n /** Size a nested Web Awesome dropdown trigger as part of this group. */\n nestedDropdown?: boolean;\n /** Configure the nested dropdown menu inset without consumer ::part() CSS. */\n menuInset?: ToolbarControlGroupMenuInset;\n /** Keep an overlong row of actions inside the available width with horizontal scrolling. */\n overflow?: ToolbarControlGroupOverflow;\n /** Responsive visibility owned by the enclosing Toolbar container. */\n visibility?: ToolbarControlGroupVisibility;\n /** Add contrast behind photo-backed avatar content. */\n scrim?: boolean;\n /**\n * Avatar image URL. A single-control group paints it on the group; a\n * multi-control group paints it only on the pressed selection highlight.\n */\n avatarImage?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function ToolbarControlGroup({\n children,\n label,\n className = '',\n expanded = false,\n single = false,\n appearance = 'contained',\n tone = 'default',\n buttonAppearance = 'plain',\n shape = 'pill',\n size = 'default',\n density = 'comfortable',\n content = 'icon',\n focusRing = 'control',\n selectedChrome = 'raised',\n selectedTone = 'brand',\n nestedDropdown = false,\n menuInset = 'standard',\n overflow = 'visible',\n visibility = 'always',\n scrim = false,\n avatarImage,\n slot,\n}: ToolbarControlGroupProps) {\n return (\n <div\n class={`kui-toolbar-control-group ${className}`.trim()}\n data-component=\"toolbar-control-group\"\n role={label ? 'group' : undefined}\n aria-label={label}\n data-appearance={appearance}\n data-tone={tone}\n data-button-appearance={buttonAppearance}\n data-expanded={String(expanded)}\n data-single={String(single)}\n data-shape={shape}\n data-size={size}\n data-density={density}\n data-content={content}\n data-focus-ring={focusRing}\n data-selected-chrome={selectedChrome}\n data-selected-tone={selectedTone}\n data-nested-dropdown={String(nestedDropdown)}\n data-menu-inset={menuInset}\n data-overflow={overflow}\n data-visibility={visibility}\n data-scrim={String(scrim)}\n style={\n avatarImage\n ? `--kui-toolbar-avatar-image:url(${JSON.stringify(avatarImage)})`\n : undefined\n }\n slot={slot}\n >\n {children}\n </div>\n );\n}\n"]}
|