@kerfjs/ui 5.0.0-beta.77 → 5.0.0-beta.78

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.
Files changed (86) hide show
  1. package/README.md +3 -0
  2. package/ai/application-ui-diagnostic-ids-v1.json +3 -0
  3. package/ai/component-catalog.json +121 -9
  4. package/ai/component-composition.json +102 -6
  5. package/ai/components/nav-stack.md +3 -3
  6. package/ai/components/surface-scaffold.md +11 -2
  7. package/ai/components/toolbar-control-group.md +2 -0
  8. package/ai/components/toolbar-text.md +2 -0
  9. package/ai/components/toolbar.md +2 -0
  10. package/ai/public-api-signatures-v1.md +49 -121
  11. package/ai/skill.md +11 -1
  12. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  13. package/dist/browser/nav-stack.js +2 -0
  14. package/dist/browser/split-view.js +2 -0
  15. package/dist/catalog-resources.d.ts +3 -3
  16. package/dist/catalog.d.ts +3 -3
  17. package/dist/catalog.js +3 -3
  18. package/dist/{chunk-WJN3V2H5.js → chunk-2GOCOLQL.js} +18 -4
  19. package/dist/chunk-2GOCOLQL.js.map +1 -0
  20. package/dist/{chunk-XIZRXI7N.js → chunk-A7DYEERU.js} +13 -1
  21. package/dist/chunk-A7DYEERU.js.map +1 -0
  22. package/dist/{chunk-6VQPLV3O.js → chunk-DSLRNR43.js} +9 -8
  23. package/dist/chunk-DSLRNR43.js.map +1 -0
  24. package/dist/{chunk-AOAW55JN.js → chunk-DXQZ3BEO.js} +4 -1
  25. package/dist/chunk-DXQZ3BEO.js.map +1 -0
  26. package/dist/chunk-IKCUPTR2.js +170 -0
  27. package/dist/chunk-IKCUPTR2.js.map +1 -0
  28. package/dist/{chunk-Z6PE5T7N.js → chunk-JL4BBZP4.js} +4 -3
  29. package/dist/chunk-JL4BBZP4.js.map +1 -0
  30. package/dist/collapsible-panel.js +2 -2
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +5 -5
  33. package/dist/nav-stack-B1Qc2e5q.d.ts +101 -0
  34. package/dist/nav-stack.d.ts +11 -93
  35. package/dist/nav-stack.js +5 -1
  36. package/dist/pane.d.ts +5 -2
  37. package/dist/pane.js +1 -1
  38. package/dist/split-view.d.ts +9 -4
  39. package/dist/split-view.js +7 -3
  40. package/dist/split-view.js.map +1 -1
  41. package/dist/styles/components/actions/toolbar-control-group/toolbar-control-group.css +60 -13
  42. package/dist/styles/components/actions/toolbar-text/toolbar-text.css +7 -1
  43. package/dist/styles/components/layout/pane/pane.css +7 -0
  44. package/dist/styles/components/navigation/nav-stack/nav-stack.css +6 -12
  45. package/dist/styles/components/navigation/tab-scaffold/tab-scaffold.css +17 -0
  46. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +55 -0
  47. package/dist/styles/nav-stack.css +6 -12
  48. package/dist/styles/pane.css +7 -0
  49. package/dist/styles/surface-scaffold.css +55 -0
  50. package/dist/styles/tab-scaffold.css +17 -0
  51. package/dist/styles/toolbar-control-group.css +60 -13
  52. package/dist/styles/toolbar-text.css +7 -1
  53. package/dist/surface-scaffold-register.d.ts +4 -0
  54. package/dist/surface-scaffold-register.js +59 -0
  55. package/dist/surface-scaffold-register.js.map +1 -0
  56. package/dist/surface-scaffold.d.ts +10 -2
  57. package/dist/surface-scaffold.js +1 -1
  58. package/dist/tab-scaffold.d.ts +2 -0
  59. package/dist/tab-scaffold.js +1 -0
  60. package/dist/tab-scaffold.js.map +1 -1
  61. package/dist/wire-toolbar-visibility.js +1 -1
  62. package/dist/workbench.d.ts +5 -13
  63. package/dist/workbench.js +1 -1
  64. package/docs/component-contract.md +8 -1
  65. package/docs/component-selection.md +1 -1
  66. package/docs/layout.md +20 -0
  67. package/docs/nav-stack.md +30 -18
  68. package/docs/recipes.md +5 -1
  69. package/docs/split-view.md +7 -4
  70. package/docs/surface-scaffold.md +46 -0
  71. package/docs/tab-scaffold.md +57 -0
  72. package/docs/ui-doctor.md +23 -0
  73. package/docs/workbench.md +3 -2
  74. package/doctor/component-style-checks.mjs +224 -0
  75. package/doctor/index.mjs +42 -13
  76. package/llms.txt +10 -0
  77. package/package.json +7 -2
  78. package/ux-demo/recipes/list-detail-dialog.tsx +4 -0
  79. package/ux-demo/recipes/navigation-stack.tsx +2 -2
  80. package/dist/chunk-6VQPLV3O.js.map +0 -1
  81. package/dist/chunk-AOAW55JN.js.map +0 -1
  82. package/dist/chunk-WJN3V2H5.js.map +0 -1
  83. package/dist/chunk-XIZRXI7N.js.map +0 -1
  84. package/dist/chunk-Z4EPMX25.js +0 -123
  85. package/dist/chunk-Z4EPMX25.js.map +0 -1
  86. package/dist/chunk-Z6PE5T7N.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ import * as kerfjs from 'kerfjs';
2
+ import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3
+ import { ListConfig } from './list.js';
4
+ import { PaneConfig } from './pane.js';
5
+ import { c as PanelBottomToolbar } from './panel-toolbar-CL9tYOkh.js';
6
+ import { ToolbarConfig } from './toolbar.js';
7
+ import { ToolbarTextSize, HeadingLevel } from './toolbar-text.js';
8
+
9
+ /** Content and chrome shared by a navigation view and a static workbench panel. */
10
+ interface NavPane<TToolbar, TBottomToolbar> {
11
+ content: KerfUiContent;
12
+ toolbar?: TToolbar;
13
+ header?: KerfUiContent;
14
+ headerList?: ListConfig;
15
+ footer?: KerfUiContent;
16
+ footerList?: ListConfig;
17
+ bottomToolbar?: TBottomToolbar;
18
+ pane?: PaneConfig;
19
+ }
20
+
21
+ /**
22
+ * One entry in a {@link NavStack}. The app owns the stack as an array (usually a
23
+ * signal); `NavStack` renders it and `wireNavStack` animates the transitions.
24
+ */
25
+ interface NavStackView extends NavPane<NavStackViewToolbar, PanelBottomToolbar> {
26
+ /** Stable identity for keyed reconcile and transition direction. */
27
+ key: string;
28
+ }
29
+ /** Per-view top toolbar. The stack supplies its back control before `leading`. */
30
+ interface NavStackViewToolbar extends NavStackToolbarConfig {
31
+ title?: string;
32
+ leading?: KerfUiContent;
33
+ center?: KerfUiContent;
34
+ trailing?: KerfUiContent;
35
+ }
36
+ /** A view's structured bottom toolbar; it cross-fades on navigation. */
37
+ type NavStackViewBottomToolbar = PanelBottomToolbar;
38
+ /**
39
+ * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real
40
+ * `Toolbar` the stack renders; by default that toolbar draws no divider and
41
+ * claims the top and side safe-area edges the stack still touches.
42
+ */
43
+ interface NavStackToolbarConfig extends ToolbarConfig {
44
+ /** Accessible name of the top toolbar (default: none). */
45
+ label?: string;
46
+ /** Size of the view title's `ToolbarText` (default `large`). */
47
+ titleSize?: ToolbarTextSize;
48
+ /** Expose the view title as a heading at this level (default: a plain span). */
49
+ headingLevel?: HeadingLevel;
50
+ }
51
+ interface NavStackProps {
52
+ id: string;
53
+ /** Accessible name for the stack region. */
54
+ label: string;
55
+ /** The stack, root first; the last entry is the active top view. */
56
+ views: NavStackView[];
57
+ /** Accessible label for the icon-only back control (default "Back"). */
58
+ backLabel?: string;
59
+ /** The back control's icon (default a chevron-left `LucideIcon`). */
60
+ backIcon?: KerfUiContent;
61
+ /**
62
+ * Visible text beside the back icon, such as the previous view's title
63
+ * (default: icon only). When set, the text names the control and
64
+ * `backLabel` is not used.
65
+ */
66
+ backText?: string;
67
+ /** The top toolbar's configuration, forwarded to its `Toolbar`. */
68
+ toolbarConfig?: NavStackToolbarConfig;
69
+ /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */
70
+ panelToggle?: KerfUiContent;
71
+ /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */
72
+ hideToolbar?: boolean;
73
+ /** Optional persistent bottom toolbar used when the active view does not provide one. */
74
+ bottomToolbar?: NavStackViewBottomToolbar;
75
+ /**
76
+ * The line under the top chrome and over the bottom toolbar, where they
77
+ * meet the active view. `scroll` (default) shows the chrome's line only
78
+ * while the view's content is scrolled beneath it, and the bottom
79
+ * toolbar's only while more content lies below — never when the content
80
+ * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is
81
+ * wired above the stack; unwired, neither shows. `always` shows both
82
+ * without the wiring; `none` neither, even when wired. The line is drawn
83
+ * inside the chrome, so no state moves the chrome or the content. A
84
+ * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.
85
+ */
86
+ chromeDividers?: 'scroll' | 'always' | 'none';
87
+ className?: string;
88
+ /** Native named-slot assignment when composed inside a web component. */
89
+ slot?: string;
90
+ }
91
+ /**
92
+ * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last
93
+ * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and
94
+ * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the
95
+ * back control and title lead, the active view's `toolbar` fills the zones,
96
+ * and `toolbarConfig` supplies defaults. A single-pane
97
+ * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.
98
+ */
99
+ declare function NavStack({ id, label, views, backLabel, backIcon, backText, toolbarConfig, panelToggle, hideToolbar, bottomToolbar, chromeDividers, className, slot, }: NavStackProps): kerfjs.SafeHtml;
100
+
101
+ export { type NavStackProps as N, type NavStackView as a, type NavPane as b, NavStack as c, type NavStackToolbarConfig as d, type NavStackViewBottomToolbar as e, type NavStackViewToolbar as f };
@@ -1,95 +1,13 @@
1
- import * as kerfjs from 'kerfjs';
2
- import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3
- import { ToolbarConfig } from './toolbar.js';
4
- import { ToolbarTextSize, HeadingLevel } from './toolbar-text.js';
5
- import { PaneAppearance } from './pane.js';
1
+ export { c as NavStack, N as NavStackProps, d as NavStackToolbarConfig, a as NavStackView, e as NavStackViewBottomToolbar, f as NavStackViewToolbar } from './nav-stack-B1Qc2e5q.js';
2
+ import 'kerfjs';
3
+ import './semantic-content-BbzjvSu9.js';
4
+ import './list.js';
5
+ import './flex-alignment-4ms8ZbV8.js';
6
6
  import './sides-BPSWde0A.js';
7
7
  import './css-values.js';
8
-
9
- /**
10
- * One entry in a {@link NavStack}. The app owns the stack as an array (usually a
11
- * signal); `NavStack` renders it and `wireNavStack` animates the transitions.
12
- */
13
- interface NavStackView {
14
- /** Stable identity for keyed reconcile and transition direction. */
15
- key: string;
16
- content: KerfUiContent;
17
- /** Background of this view's scrolling work surface. */
18
- appearance?: PaneAppearance;
19
- /** Title shown in the top toolbar for this view. */
20
- title?: string;
21
- /** Leading groups for this view's top toolbar, after the back control and before the title. */
22
- leading?: KerfUiContent;
23
- /** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */
24
- center?: KerfUiContent;
25
- /** Trailing actions for this view's top toolbar. */
26
- toolbar?: KerfUiContent;
27
- /** Fixed chrome below this view's toolbar, above its scrolling content. */
28
- header?: KerfUiContent;
29
- /** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */
30
- bottomToolbar?: KerfUiContent;
31
- }
32
- /**
33
- * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real
34
- * `Toolbar` the stack renders; by default that toolbar draws no divider and
35
- * claims the top and side safe-area edges the stack still touches.
36
- */
37
- interface NavStackToolbarConfig extends ToolbarConfig {
38
- /** Accessible name of the top toolbar (default: none). */
39
- label?: string;
40
- /** Size of the view title's `ToolbarText` (default `large`). */
41
- titleSize?: ToolbarTextSize;
42
- /** Expose the view title as a heading at this level (default: a plain span). */
43
- headingLevel?: HeadingLevel;
44
- }
45
- interface NavStackProps {
46
- id: string;
47
- /** Accessible name for the stack region. */
48
- label: string;
49
- /** The stack, root first; the last entry is the active top view. */
50
- views: NavStackView[];
51
- /** Accessible label for the icon-only back control (default "Back"). */
52
- backLabel?: string;
53
- /** The back control's icon (default a chevron-left `LucideIcon`). */
54
- backIcon?: KerfUiContent;
55
- /**
56
- * Visible text beside the back icon, such as the previous view's title
57
- * (default: icon only). When set, the text names the control and
58
- * `backLabel` is not used.
59
- */
60
- backText?: string;
61
- /** The top toolbar's configuration, forwarded to its `Toolbar`. */
62
- toolbarConfig?: NavStackToolbarConfig;
63
- /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */
64
- panelToggle?: KerfUiContent;
65
- /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */
66
- hideToolbar?: boolean;
67
- /** Optional persistent bottom toolbar used when the active view does not provide one. */
68
- bottomToolbar?: KerfUiContent;
69
- /**
70
- * The line under the top chrome and over the bottom toolbar, where they
71
- * meet the active view. `scroll` (default) shows the chrome's line only
72
- * while the view's content is scrolled beneath it, and the bottom
73
- * toolbar's only while more content lies below — never when the content
74
- * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is
75
- * wired above the stack; unwired, neither shows. `always` shows both
76
- * without the wiring; `none` neither, even when wired. The line is drawn
77
- * inside the chrome, so no state moves the chrome or the content. A
78
- * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.
79
- */
80
- chromeDividers?: 'scroll' | 'always' | 'none';
81
- className?: string;
82
- /** Native named-slot assignment when composed inside a web component. */
83
- slot?: string;
84
- }
85
- /**
86
- * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last
87
- * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and
88
- * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the
89
- * back control and title lead, the active view's `leading` / `center` / `toolbar`
90
- * content fills the zones, and `toolbarConfig` configures it. A single-pane
91
- * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.
92
- */
93
- declare function NavStack({ id, label, views, backLabel, backIcon, backText, toolbarConfig, panelToggle, hideToolbar, bottomToolbar, chromeDividers, className, slot, }: NavStackProps): kerfjs.SafeHtml;
94
-
95
- export { NavStack, type NavStackProps, type NavStackToolbarConfig, type NavStackView };
8
+ import './pane.js';
9
+ import './panel-toolbar-CL9tYOkh.js';
10
+ import './toolbar.js';
11
+ import './lucide-icon.js';
12
+ import 'lucide';
13
+ import './toolbar-text.js';
package/dist/nav-stack.js CHANGED
@@ -1,4 +1,8 @@
1
- export { NavStack } from './chunk-Z4EPMX25.js';
1
+ export { NavStack } from './chunk-IKCUPTR2.js';
2
+
3
+
4
+
5
+
2
6
 
3
7
 
4
8
 
package/dist/pane.d.ts CHANGED
@@ -23,6 +23,7 @@ type PaneRootAttributes = Readonly<Record<`data-${string}`, string | undefined>
23
23
  'data-chrome-placement'?: never;
24
24
  'data-chrome-dividers'?: never;
25
25
  'data-appearance'?: never;
26
+ 'data-deep-inset'?: never;
26
27
  }>;
27
28
  /** How a Pane's header and footer relate to its scrolling content. */
28
29
  type PaneChromePlacement = 'fixed' | 'auto';
@@ -62,6 +63,8 @@ interface PaneProps {
62
63
  chromeDividers?: PaneChromeDividers;
63
64
  /** Paint the scrolling work surface with the shared lowered-surface color. */
64
65
  appearance?: PaneAppearance;
66
+ /** Add an extra 8px inline gutter to scrolling content (default: false). */
67
+ deepInset?: boolean;
65
68
  /** Root semantics. Defaults to `div`. */
66
69
  element?: PaneElement;
67
70
  /** Scrolling content semantics. Defaults to `div`. */
@@ -96,13 +99,13 @@ interface PaneProps {
96
99
  * or a CollapsiblePanel) forwards, so the app configures that pane instead of
97
100
  * styling it. An omitted or `undefined` field keeps the composite's default.
98
101
  */
99
- type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'appearance'>;
102
+ type PaneConfig = Pick<PaneProps, 'contentElement' | 'contentLabel' | 'separators' | 'safeAreaEdges' | 'chromeDividers' | 'appearance' | 'deepInset'>;
100
103
  /**
101
104
  * An unpadded application column with optional fixed header/footer slots and one
102
105
  * scrolling vertical content owner. Separator lines are independently opt-in on
103
106
  * each logical edge, so the same component works as a sidebar, main area,
104
107
  * inspector, or dialog column.
105
108
  */
106
- declare function Pane({ header, children, footer, chromePlacement, chromeDividers, appearance, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
109
+ declare function Pane({ header, children, footer, chromePlacement, chromeDividers, appearance, deepInset, element, contentElement, separators, safeAreaEdges, id, label, contentLabel, className, headerClassName, contentClassName, footerClassName, rootAttributes, slot, }: PaneProps): kerfjs.SafeHtml;
107
110
 
108
111
  export { Pane, type PaneAppearance, type PaneChromeDividers, type PaneChromePlacement, type PaneConfig, type PaneContentElement, type PaneElement, type PaneProps, type PaneSeparatorSide };
package/dist/pane.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Pane } from './chunk-AOAW55JN.js';
1
+ export { Pane } from './chunk-DXQZ3BEO.js';
2
2
 
3
3
 
4
4
  //# sourceMappingURL=pane.js.map
@@ -1,12 +1,17 @@
1
1
  import * as kerfjs from 'kerfjs';
2
2
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
3
- import { NavStackProps, NavStackView } from './nav-stack.js';
3
+ import { N as NavStackProps, a as NavStackView } from './nav-stack-B1Qc2e5q.js';
4
4
  import { ResizableRegionProps } from './resizable-region.js';
5
- import './toolbar.js';
5
+ import './list.js';
6
+ import './flex-alignment-4ms8ZbV8.js';
6
7
  import './sides-BPSWde0A.js';
8
+ import './css-values.js';
7
9
  import './pane.js';
10
+ import './panel-toolbar-CL9tYOkh.js';
11
+ import './toolbar.js';
12
+ import './lucide-icon.js';
13
+ import 'lucide';
8
14
  import './toolbar-text.js';
9
- import './css-values.js';
10
15
 
11
16
  /**
12
17
  * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /
@@ -21,7 +26,7 @@ interface SplitViewResizable extends Pick<ResizableRegionProps, 'separator' | 'h
21
26
  max: number;
22
27
  }
23
28
  /** One compact view's top- and bottom-toolbar content (see `NavStackView`). */
24
- type SplitViewCompactViewToolbars = Pick<NavStackView, 'leading' | 'center' | 'toolbar' | 'bottomToolbar'>;
29
+ type SplitViewCompactViewToolbars = Pick<NavStackView, 'toolbar' | 'bottomToolbar'>;
25
30
  /**
26
31
  * The compact `NavStack`'s configuration: its toolbar configuration, back
27
32
  * control, persistent bottom toolbar, and chrome dividers forward to the
@@ -1,4 +1,4 @@
1
- import { NavStack } from './chunk-Z4EPMX25.js';
1
+ import { NavStack } from './chunk-IKCUPTR2.js';
2
2
  import { ResizableRegion } from './chunk-Y6KT7ZTR.js';
3
3
 
4
4
 
@@ -7,6 +7,10 @@ import { ResizableRegion } from './chunk-Y6KT7ZTR.js';
7
7
 
8
8
 
9
9
 
10
+
11
+
12
+
13
+
10
14
  import { jsx, jsxs } from 'kerfjs/jsx-runtime';
11
15
 
12
16
  function SplitView({
@@ -28,7 +32,7 @@ function SplitView({
28
32
  const listView = {
29
33
  ...compactStack.list,
30
34
  key: "list",
31
- title: listTitle,
35
+ toolbar: { ...compactStack.list?.toolbar, title: listTitle },
32
36
  content: list
33
37
  };
34
38
  const views = detailActive ? [
@@ -36,7 +40,7 @@ function SplitView({
36
40
  {
37
41
  ...compactStack.detail,
38
42
  key: "detail",
39
- title: detailTitle,
43
+ toolbar: { ...compactStack.detail?.toolbar, title: detailTitle },
40
44
  content: detail
41
45
  }
42
46
  ] : [listView];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/layout/split-view/split-view.tsx"],"names":[],"mappings":"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","file":"split-view.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n NavStack,\n type NavStackProps,\n type NavStackView,\n} from '../../navigation/nav-stack/nav-stack.js';\nimport {\n ResizableRegion,\n type ResizableRegionProps,\n} from '../resizable-region/resizable-region.js';\n\n/**\n * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /\n * `max` limits, plus the region configuration that forwards unchanged\n * (`separator`, `handleIcon`, `contentOverflow`, and collapse:\n * `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,\n * `restorePosition`). Omitted options keep the region's defaults.\n */\nexport interface SplitViewResizable extends Pick<\n ResizableRegionProps,\n | 'separator'\n | 'handleIcon'\n | 'contentOverflow'\n | 'collapsed'\n | 'transitioning'\n | 'collapseMotion'\n | 'restoreControl'\n | 'restorePosition'\n> {\n size: number;\n min: number;\n max: number;\n}\n\n/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */\nexport type SplitViewCompactViewToolbars = Pick<\n NavStackView,\n 'leading' | 'center' | 'toolbar' | 'bottomToolbar'\n>;\n\n/**\n * The compact `NavStack`'s configuration: its toolbar configuration, back\n * control, persistent bottom toolbar, and chrome dividers forward to the\n * stack, and `list` / `detail` give each view its own toolbar groups.\n */\nexport interface SplitViewCompactStack extends Pick<\n NavStackProps,\n | 'toolbarConfig'\n | 'backIcon'\n | 'backText'\n | 'hideToolbar'\n | 'bottomToolbar'\n | 'chromeDividers'\n> {\n /** Toolbar content for the list (root) view. */\n list?: SplitViewCompactViewToolbars;\n /** Toolbar content for the pushed detail view. */\n detail?: SplitViewCompactViewToolbars;\n}\n\nexport interface SplitViewProps {\n id: string;\n label: string;\n /** The list (primary) pane. */\n list: KerfUiContent;\n /** The detail (secondary) pane. */\n detail: KerfUiContent;\n /**\n * Compact (\"one pane at a time\") classes — a handset or portrait tablet.\n * Derive from `deviceClass().value.compact`. When true the split collapses to\n * a `NavStack`: the list is the root and the detail is pushed over it.\n */\n compact?: boolean;\n /** In compact mode, whether the detail is currently pushed over the list. */\n detailActive?: boolean;\n /** Title/label for the list (compact NavStack root + region label). */\n listTitle?: string;\n /** Title/label for the detail (compact NavStack pushed view + region label). */\n detailTitle?: string;\n /** Back label for the compact NavStack (default \"Back\"). */\n backLabel?: string;\n /** Compact NavStack configuration and per-view toolbars. */\n compactStack?: SplitViewCompactStack;\n /** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */\n resizable?: SplitViewResizable;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list-detail split. On roomy classes it shows both panes side\n * by side with an optional resizable separator; on compact classes it collapses\n * to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the\n * resizable wiring with `wireResizableRegions` and the compact back with\n * `wireNavStack`.\n */\nexport function SplitView({\n id,\n label,\n list,\n detail,\n compact = false,\n detailActive = false,\n listTitle = '',\n detailTitle = '',\n backLabel = 'Back',\n compactStack = {},\n resizable,\n className = '',\n slot,\n}: SplitViewProps) {\n if (compact) {\n const listView: NavStackView = {\n ...compactStack.list,\n key: 'list',\n title: listTitle,\n content: list,\n };\n const views: NavStackView[] = detailActive\n ? [\n listView,\n {\n ...compactStack.detail,\n key: 'detail',\n title: detailTitle,\n content: detail,\n },\n ]\n : [listView];\n return (\n <div\n class={`kui-split-view kui-split-view--compact ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"compact\"\n slot={slot}\n >\n <NavStack\n id={`${id}-stack`}\n label={label}\n views={views}\n backLabel={backLabel}\n backIcon={compactStack.backIcon}\n backText={compactStack.backText}\n toolbarConfig={compactStack.toolbarConfig}\n hideToolbar={compactStack.hideToolbar}\n bottomToolbar={compactStack.bottomToolbar}\n chromeDividers={compactStack.chromeDividers}\n />\n </div>\n );\n }\n const listPane = resizable ? (\n <ResizableRegion\n id={`${id}-list`}\n label={listTitle || 'List'}\n size={resizable.size}\n min={resizable.min}\n max={resizable.max}\n separator={resizable.separator}\n handleIcon={resizable.handleIcon}\n contentOverflow={resizable.contentOverflow}\n collapsed={resizable.collapsed}\n transitioning={resizable.transitioning}\n collapseMotion={resizable.collapseMotion}\n restoreControl={resizable.restoreControl}\n restorePosition={resizable.restorePosition}\n >\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"true\"\n >\n {list}\n </div>\n </ResizableRegion>\n ) : (\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"false\"\n >\n {list}\n </div>\n );\n return (\n <div\n class={`kui-split-view ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"split\"\n aria-label={label}\n slot={slot}\n >\n {listPane}\n <div\n class=\"kui-split-view__detail kui-pane\"\n data-split-detail\n aria-label={detailTitle || undefined}\n >\n {detail}\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/components/layout/split-view/split-view.tsx"],"names":[],"mappings":"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","file":"split-view.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n NavStack,\n type NavStackProps,\n type NavStackView,\n} from '../../navigation/nav-stack/nav-stack.js';\nimport {\n ResizableRegion,\n type ResizableRegionProps,\n} from '../resizable-region/resizable-region.js';\n\n/**\n * The roomy list pane's `ResizableRegion`: its committed `size` and `min` /\n * `max` limits, plus the region configuration that forwards unchanged\n * (`separator`, `handleIcon`, `contentOverflow`, and collapse:\n * `collapsed`, `transitioning`, `collapseMotion`, `restoreControl`,\n * `restorePosition`). Omitted options keep the region's defaults.\n */\nexport interface SplitViewResizable extends Pick<\n ResizableRegionProps,\n | 'separator'\n | 'handleIcon'\n | 'contentOverflow'\n | 'collapsed'\n | 'transitioning'\n | 'collapseMotion'\n | 'restoreControl'\n | 'restorePosition'\n> {\n size: number;\n min: number;\n max: number;\n}\n\n/** One compact view's top- and bottom-toolbar content (see `NavStackView`). */\nexport type SplitViewCompactViewToolbars = Pick<\n NavStackView,\n 'toolbar' | 'bottomToolbar'\n>;\n\n/**\n * The compact `NavStack`'s configuration: its toolbar configuration, back\n * control, persistent bottom toolbar, and chrome dividers forward to the\n * stack, and `list` / `detail` give each view its own toolbar groups.\n */\nexport interface SplitViewCompactStack extends Pick<\n NavStackProps,\n | 'toolbarConfig'\n | 'backIcon'\n | 'backText'\n | 'hideToolbar'\n | 'bottomToolbar'\n | 'chromeDividers'\n> {\n /** Toolbar content for the list (root) view. */\n list?: SplitViewCompactViewToolbars;\n /** Toolbar content for the pushed detail view. */\n detail?: SplitViewCompactViewToolbars;\n}\n\nexport interface SplitViewProps {\n id: string;\n label: string;\n /** The list (primary) pane. */\n list: KerfUiContent;\n /** The detail (secondary) pane. */\n detail: KerfUiContent;\n /**\n * Compact (\"one pane at a time\") classes — a handset or portrait tablet.\n * Derive from `deviceClass().value.compact`. When true the split collapses to\n * a `NavStack`: the list is the root and the detail is pushed over it.\n */\n compact?: boolean;\n /** In compact mode, whether the detail is currently pushed over the list. */\n detailActive?: boolean;\n /** Title/label for the list (compact NavStack root + region label). */\n listTitle?: string;\n /** Title/label for the detail (compact NavStack pushed view + region label). */\n detailTitle?: string;\n /** Back label for the compact NavStack (default \"Back\"). */\n backLabel?: string;\n /** Compact NavStack configuration and per-view toolbars. */\n compactStack?: SplitViewCompactStack;\n /** A resizable separator on roomy classes (min/max px). Omit for a fixed split. */\n resizable?: SplitViewResizable;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A list-detail split. On roomy classes it shows both panes side\n * by side with an optional resizable separator; on compact classes it collapses\n * to a `NavStack` (list → detail). See `docs/23-app-layouts.md` §3.2. Compose the\n * resizable wiring with `wireResizableRegions` and the compact back with\n * `wireNavStack`.\n */\nexport function SplitView({\n id,\n label,\n list,\n detail,\n compact = false,\n detailActive = false,\n listTitle = '',\n detailTitle = '',\n backLabel = 'Back',\n compactStack = {},\n resizable,\n className = '',\n slot,\n}: SplitViewProps) {\n if (compact) {\n const listView: NavStackView = {\n ...compactStack.list,\n key: 'list',\n toolbar: { ...compactStack.list?.toolbar, title: listTitle },\n content: list,\n };\n const views: NavStackView[] = detailActive\n ? [\n listView,\n {\n ...compactStack.detail,\n key: 'detail',\n toolbar: { ...compactStack.detail?.toolbar, title: detailTitle },\n content: detail,\n },\n ]\n : [listView];\n return (\n <div\n class={`kui-split-view kui-split-view--compact ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"compact\"\n slot={slot}\n >\n <NavStack\n id={`${id}-stack`}\n label={label}\n views={views}\n backLabel={backLabel}\n backIcon={compactStack.backIcon}\n backText={compactStack.backText}\n toolbarConfig={compactStack.toolbarConfig}\n hideToolbar={compactStack.hideToolbar}\n bottomToolbar={compactStack.bottomToolbar}\n chromeDividers={compactStack.chromeDividers}\n />\n </div>\n );\n }\n const listPane = resizable ? (\n <ResizableRegion\n id={`${id}-list`}\n label={listTitle || 'List'}\n size={resizable.size}\n min={resizable.min}\n max={resizable.max}\n separator={resizable.separator}\n handleIcon={resizable.handleIcon}\n contentOverflow={resizable.contentOverflow}\n collapsed={resizable.collapsed}\n transitioning={resizable.transitioning}\n collapseMotion={resizable.collapseMotion}\n restoreControl={resizable.restoreControl}\n restorePosition={resizable.restorePosition}\n >\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"true\"\n >\n {list}\n </div>\n </ResizableRegion>\n ) : (\n <div\n class=\"kui-split-view__list kui-pane\"\n data-split-list\n data-resizable=\"false\"\n >\n {list}\n </div>\n );\n return (\n <div\n class={`kui-split-view ${className}`.trim()}\n id={id}\n data-component=\"split-view\"\n data-split-mode=\"split\"\n aria-label={label}\n slot={slot}\n >\n {listPane}\n <div\n class=\"kui-split-view__detail kui-pane\"\n data-split-detail\n aria-label={detailTitle || undefined}\n >\n {detail}\n </div>\n </div>\n );\n}\n"]}
@@ -610,17 +610,23 @@
610
610
  wa-button,
611
611
  .kui-select,
612
612
  .kui-toolbar-action-link
613
- ):only-child
613
+ ):nth-child(1 of :where(:not([data-toolbar-visibility-state]))):where(
614
+ :nth-last-child(1 of :not([data-toolbar-visibility-state]))
615
+ )
614
616
  ):hover {
615
617
  background-color: var(--kui-toolbar-control-hover-background);
616
618
  }
617
619
 
618
620
  .kui-toolbar-control-group:not([data-single="true"]):has(
619
- > :is(button, wa-button, .kui-toolbar-action-link):only-child
621
+ > :is(button, wa-button, .kui-toolbar-action-link):nth-child(
622
+ 1 of :where(:not([data-toolbar-visibility-state]))
623
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
620
624
  )
621
625
  > :is(button, wa-button, .kui-toolbar-action-link):hover,
622
626
  .kui-toolbar-control-group:not([data-single="true"]):has(
623
- > :is(button, wa-button):only-child
627
+ > :is(button, wa-button):nth-child(
628
+ 1 of :where(:not([data-toolbar-visibility-state]))
629
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
624
630
  )
625
631
  > wa-button:hover::part(base) {
626
632
  border-color: transparent;
@@ -765,25 +771,41 @@
765
771
 
766
772
  .kui-toolbar-control-group[data-content="avatar"]:is(
767
773
  [data-single="true"],
768
- :has(> :is(button, wa-button):only-child)
774
+ :has(
775
+ > :is(button, wa-button):nth-child(
776
+ 1 of :where(:not([data-toolbar-visibility-state]))
777
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
778
+ )
769
779
  ) {
770
780
  background-image: var(--kui-toolbar-avatar-image);
771
781
  }
772
782
 
773
783
  .kui-toolbar-control-group[data-content="avatar"]:is(
774
784
  [data-single="true"],
775
- :has(> :is(button, wa-button):only-child)
785
+ :has(
786
+ > :is(button, wa-button):nth-child(
787
+ 1 of :where(:not([data-toolbar-visibility-state]))
788
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
789
+ )
776
790
  )
777
791
  > :is(button, wa-button) {
778
792
  color: transparent;
779
793
  }
780
794
 
781
795
  .kui-toolbar-control-group[data-content="avatar"][data-single="false"]:not(
782
- :has(> :is(button, wa-button):only-child)
796
+ :has(
797
+ > :is(button, wa-button):nth-child(
798
+ 1 of :where(:not([data-toolbar-visibility-state]))
799
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
800
+ )
783
801
  )
784
802
  > button[aria-pressed="true"],
785
803
  .kui-toolbar-control-group[data-content="avatar"][data-single="false"]:not(
786
- :has(> :is(button, wa-button):only-child)
804
+ :has(
805
+ > :is(button, wa-button):nth-child(
806
+ 1 of :where(:not([data-toolbar-visibility-state]))
807
+ ):where(:nth-last-child(1 of :not([data-toolbar-visibility-state])))
808
+ )
787
809
  )
788
810
  > wa-button[aria-pressed="true"]::part(base) {
789
811
  color: transparent;
@@ -798,7 +820,10 @@
798
820
 
799
821
  .kui-toolbar-control-group[data-single="true"][data-appearance="contained"][data-tile-tone="neutral"]:has(
800
822
  > svg[aria-hidden="true"]
801
- ):not(:has(> :not(svg[aria-hidden="true"])), :has(> svg ~ svg)) {
823
+ ):not(
824
+ :has(> :not(svg[aria-hidden="true"], [data-toolbar-visibility-state])),
825
+ :has(> svg ~ svg)
826
+ ) {
802
827
  background: var(--kui-color-neutral-fill-quiet);
803
828
  border-color: var(--kui-color-neutral-border-quiet);
804
829
  color: var(--kui-color-neutral-on-quiet);
@@ -806,7 +831,10 @@
806
831
 
807
832
  .kui-toolbar-control-group[data-single="true"][data-appearance="contained"][data-tile-tone="brand"]:has(
808
833
  > svg[aria-hidden="true"]
809
- ):not(:has(> :not(svg[aria-hidden="true"])), :has(> svg ~ svg)) {
834
+ ):not(
835
+ :has(> :not(svg[aria-hidden="true"], [data-toolbar-visibility-state])),
836
+ :has(> svg ~ svg)
837
+ ) {
810
838
  background: var(--kui-color-brand-fill-quiet);
811
839
  border-color: var(--kui-color-brand-border-quiet);
812
840
  color: var(--kui-color-brand-on-quiet);
@@ -814,7 +842,10 @@
814
842
 
815
843
  .kui-toolbar-control-group[data-single="true"][data-appearance="contained"][data-tile-tone="success"]:has(
816
844
  > svg[aria-hidden="true"]
817
- ):not(:has(> :not(svg[aria-hidden="true"])), :has(> svg ~ svg)) {
845
+ ):not(
846
+ :has(> :not(svg[aria-hidden="true"], [data-toolbar-visibility-state])),
847
+ :has(> svg ~ svg)
848
+ ) {
818
849
  background: var(--kui-color-success-fill-quiet);
819
850
  border-color: var(--kui-color-success-border-quiet);
820
851
  color: var(--kui-color-success-on-quiet);
@@ -822,7 +853,10 @@
822
853
 
823
854
  .kui-toolbar-control-group[data-single="true"][data-appearance="contained"][data-tile-tone="warning"]:has(
824
855
  > svg[aria-hidden="true"]
825
- ):not(:has(> :not(svg[aria-hidden="true"])), :has(> svg ~ svg)) {
856
+ ):not(
857
+ :has(> :not(svg[aria-hidden="true"], [data-toolbar-visibility-state])),
858
+ :has(> svg ~ svg)
859
+ ) {
826
860
  background: var(--kui-color-warning-fill-quiet);
827
861
  border-color: var(--kui-color-warning-border-quiet);
828
862
  color: var(--kui-color-warning-on-quiet);
@@ -830,12 +864,25 @@
830
864
 
831
865
  .kui-toolbar-control-group[data-single="true"][data-appearance="contained"][data-tile-tone="danger"]:has(
832
866
  > svg[aria-hidden="true"]
833
- ):not(:has(> :not(svg[aria-hidden="true"])), :has(> svg ~ svg)) {
867
+ ):not(
868
+ :has(> :not(svg[aria-hidden="true"], [data-toolbar-visibility-state])),
869
+ :has(> svg ~ svg)
870
+ ) {
834
871
  background: var(--kui-color-danger-fill-quiet);
835
872
  border-color: var(--kui-color-danger-border-quiet);
836
873
  color: var(--kui-color-danger-on-quiet);
837
874
  }
838
875
  .kui-toolbar-control-group[data-toolbar-width-hidden="true"],
839
- .kui-toolbar-control-group__busy-status[data-toolbar-width-hidden="true"] {
876
+ .kui-toolbar-control-group__busy-status[data-toolbar-width-hidden="true"],
877
+ .kui-toolbar-control-group:has(
878
+ > [data-toolbar-visibility-state][data-toolbar-width-hidden="true"]
879
+ ),
880
+ .kui-toolbar-control-group__busy-status:has(
881
+ > [data-toolbar-visibility-state][data-toolbar-width-hidden="true"]
882
+ ) {
883
+ display: none;
884
+ }
885
+ .kui-toolbar-control-group > [data-toolbar-visibility-state],
886
+ .kui-toolbar-control-group__busy-status > [data-toolbar-visibility-state] {
840
887
  display: none;
841
888
  }
@@ -159,6 +159,12 @@ button.kui-toolbar-text[data-tone="dark"]:hover {
159
159
  line-clamp: none;
160
160
  max-height: calc(var(--kui-toolbar-text-max-lines) * 1.25em);
161
161
  }
162
- .kui-toolbar-text[data-toolbar-width-hidden="true"] {
162
+ .kui-toolbar-text[data-toolbar-width-hidden="true"],
163
+ .kui-toolbar-text:has(
164
+ > [data-toolbar-visibility-state][data-toolbar-width-hidden="true"]
165
+ ) {
166
+ display: none;
167
+ }
168
+ .kui-toolbar-text > [data-toolbar-visibility-state] {
163
169
  display: none;
164
170
  }
@@ -158,6 +158,13 @@
158
158
  var(--_kui-pane-content-block-end);
159
159
  }
160
160
 
161
+ /* Add one outer gutter without changing the inherited item-margin token.
162
+ Nested Row, List, and Grid therefore keep their own default 8px insets. */
163
+ .kui-pane[data-deep-inset="true"] > .kui-pane__content {
164
+ padding-inline: calc(var(--_kui-pane-safe-inline-start) + var(--kui-space-xs))
165
+ calc(var(--_kui-pane-safe-inline-end) + var(--kui-space-xs));
166
+ }
167
+
161
168
  .kui-pane__header ~ .kui-pane__content {
162
169
  --_kui-pane-content-block-start: 0px;
163
170
  }
@@ -71,10 +71,6 @@
71
71
  background: var(--kui-color-surface);
72
72
  }
73
73
 
74
- .kui-nav-stack__header {
75
- min-width: 0;
76
- }
77
-
78
74
  .kui-nav-stack__viewport {
79
75
  --kui-edge-inset-block-start: var(--_kui-nav-stack-safe-block-start);
80
76
  --kui-edge-inset-block-end: var(--_kui-nav-stack-safe-block-end);
@@ -106,11 +102,9 @@
106
102
  inset: 0;
107
103
  }
108
104
 
109
- .kui-nav-stack__view[data-appearance="sunken"] {
110
- background: var(
111
- --kui-sunken-panel-background,
112
- var(--kui-color-surface-lowered)
113
- );
105
+ .kui-nav-stack__view:has(> [data-component="pane"]) {
106
+ display: grid;
107
+ overflow: hidden;
114
108
  }
115
109
 
116
110
  /* Each view is its region's scroll owner: block insets become padding inside
@@ -180,9 +174,9 @@
180
174
  }
181
175
 
182
176
  .kui-nav-stack__bottom {
183
- padding-block-end: var(--_kui-nav-stack-safe-block-end);
184
- padding-inline: var(--_kui-nav-stack-safe-inline-start)
185
- var(--_kui-nav-stack-safe-inline-end);
177
+ --kui-edge-inset-block-end: var(--_kui-nav-stack-safe-block-end);
178
+ --kui-edge-inset-inline-start: var(--_kui-nav-stack-safe-inline-start);
179
+ --kui-edge-inset-inline-end: var(--_kui-nav-stack-safe-inline-end);
186
180
  border-block-start: 1px solid
187
181
  var(--_kui-nav-stack-bottom-divider, transparent);
188
182
  background: var(--kui-color-surface);
@@ -73,6 +73,23 @@
73
73
  scroll-padding-block-start: var(--kui-edge-inset-block-start);
74
74
  }
75
75
 
76
+ /* A plain scene adds one outer gutter; a sole Pane or layout keeps ownership
77
+ of its own content and may opt into deepInset there. */
78
+ .kui-tab-scaffold__scene[data-deep-inset="true"]:not(
79
+ :has(
80
+ > :is(
81
+ [data-component="pane"],
82
+ [data-component="nav-stack"],
83
+ [data-component="split-view"],
84
+ [data-component="workbench"],
85
+ [data-component="tab-scaffold"]
86
+ ):only-child
87
+ )
88
+ ) {
89
+ padding-inline: calc(var(--kui-edge-inset-inline-start) + var(--kui-space-xs))
90
+ calc(var(--kui-edge-inset-inline-end) + var(--kui-space-xs));
91
+ }
92
+
76
93
  .kui-tab-scaffold__scene
77
94
  > :not(
78
95
  :is(