@kerfjs/ui 5.0.0-beta.110 → 5.0.0-beta.111

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 (158) hide show
  1. package/README.md +1 -0
  2. package/ai/component-catalog.json +9 -2
  3. package/ai/component-composition.json +8 -1
  4. package/ai/components/button.md +5 -2
  5. package/ai/components/surface-scaffold.md +3 -0
  6. package/ai/public-api-signatures-v1.md +86 -39
  7. package/ai/skill.md +4 -0
  8. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  9. package/dist/backdrop-image.d.ts +8 -0
  10. package/dist/backdrop-image.js +1 -1
  11. package/dist/browser/content-item.js +1 -0
  12. package/dist/button.d.ts +4 -2
  13. package/dist/button.js +1 -1
  14. package/dist/catalog-resources.d.ts +2 -1
  15. package/dist/catalog.d.ts +2 -1
  16. package/dist/catalog.js +2 -1
  17. package/dist/catalog.js.map +1 -1
  18. package/dist/{chunk-P7EJ4CAD.js → chunk-ETFP7HAR.js} +2 -2
  19. package/dist/{chunk-P7EJ4CAD.js.map → chunk-ETFP7HAR.js.map} +1 -1
  20. package/dist/{chunk-SOFPUW3O.js → chunk-IIQ2XIMU.js} +4 -3
  21. package/dist/chunk-IIQ2XIMU.js.map +1 -0
  22. package/dist/chunk-IRC5N7FA.js +16 -0
  23. package/dist/chunk-IRC5N7FA.js.map +1 -0
  24. package/dist/{chunk-SQ5DH66U.js → chunk-ITENVZ6Q.js} +2 -15
  25. package/dist/chunk-ITENVZ6Q.js.map +1 -0
  26. package/dist/{chunk-WSEJ2FDE.js → chunk-OUCHU7JB.js} +2 -2
  27. package/dist/{chunk-WSEJ2FDE.js.map → chunk-OUCHU7JB.js.map} +1 -1
  28. package/dist/{chunk-KPINJHIC.js → chunk-PS24PVR6.js} +3 -1
  29. package/dist/chunk-PS24PVR6.js.map +1 -0
  30. package/dist/{chunk-SCDWURBO.js → chunk-SOBRGH7T.js} +18 -3
  31. package/dist/chunk-SOBRGH7T.js.map +1 -0
  32. package/dist/{chunk-6CDILXF4.js → chunk-VGECEXM6.js} +11 -2
  33. package/dist/chunk-VGECEXM6.js.map +1 -0
  34. package/dist/chunk-WD6KABEU.js +200 -0
  35. package/dist/chunk-WD6KABEU.js.map +1 -0
  36. package/dist/{chunk-HQZG3OFL.js → chunk-XRZSK2WC.js} +3 -2
  37. package/dist/chunk-XRZSK2WC.js.map +1 -0
  38. package/dist/{chunk-CPSGUGAY.js → chunk-YPAQFBMN.js} +4 -4
  39. package/dist/{chunk-CPSGUGAY.js.map → chunk-YPAQFBMN.js.map} +1 -1
  40. package/dist/collapsible-panel.d.ts +1 -0
  41. package/dist/collapsible-panel.js +3 -2
  42. package/dist/collapsible-panel.js.map +1 -1
  43. package/dist/content-item.d.ts +44 -2
  44. package/dist/content-item.js +4 -1
  45. package/dist/index.d.ts +3 -2
  46. package/dist/index.js +6 -5
  47. package/dist/list-detail-dialog.d.ts +2 -1
  48. package/dist/list-detail-dialog.js +4 -3
  49. package/dist/list-detail-dialog.js.map +1 -1
  50. package/dist/{nav-stack-CU_0dKtI.d.ts → nav-stack-CrZF95VO.d.ts} +2 -1
  51. package/dist/nav-stack.d.ts +2 -1
  52. package/dist/nav-stack.js +2 -1
  53. package/dist/pane.d.ts +3 -23
  54. package/dist/pane.js +2 -1
  55. package/dist/split-view.d.ts +2 -1
  56. package/dist/split-view.js +2 -1
  57. package/dist/styles/backdrop-image.css +18 -1
  58. package/dist/styles/components/surfaces/backdrop-image/backdrop-image.css +18 -1
  59. package/dist/styles/components/surfaces/content-item/content-item.css +52 -0
  60. package/dist/styles/components/surfaces/surface-scaffold/surface-scaffold.css +9 -1
  61. package/dist/styles/content-item.css +3 -168
  62. package/dist/styles/foundation.css +4 -4
  63. package/dist/styles/surface-scaffold.css +9 -1
  64. package/dist/styles/webawesome.css +2 -2
  65. package/dist/surface-scaffold.d.ts +6 -2
  66. package/dist/surface-scaffold.js +1 -1
  67. package/dist/surface-tint-DQgYCaP9.d.ts +25 -0
  68. package/dist/tab-navigator.d.ts +2 -1
  69. package/dist/tab-navigator.js +2 -1
  70. package/dist/tab-navigator.js.map +1 -1
  71. package/dist/toolbar.d.ts +1 -0
  72. package/dist/wire-catalog.d.ts +2 -1
  73. package/dist/wire-content-items.js +62 -0
  74. package/dist/wire-content-items.js.map +1 -1
  75. package/dist/workbench-dialog.d.ts +2 -1
  76. package/dist/workbench-dialog.js +3 -2
  77. package/dist/workbench-dialog.js.map +1 -1
  78. package/dist/workbench.d.ts +2 -1
  79. package/dist/workbench.js +2 -1
  80. package/docs/accessibility.md +6 -0
  81. package/docs/backdrop-image.md +4 -0
  82. package/docs/button.md +15 -0
  83. package/docs/component-contract.md +7 -0
  84. package/docs/component-selection.md +1 -1
  85. package/docs/design/templates/button/emphasis-dark.svg +1 -1
  86. package/docs/design/templates/button-dark.svg +1 -1
  87. package/docs/design/templates/checkbox/error-dark.svg +1 -1
  88. package/docs/design/templates/checkbox/states.svg +1 -1
  89. package/docs/design/templates/checkbox-dark.svg +1 -1
  90. package/docs/design/templates/checkbox-group/horizontal-dark.svg +1 -1
  91. package/docs/design/templates/checkbox-group/vertical.svg +1 -1
  92. package/docs/design/templates/checkbox-group-dark.svg +1 -1
  93. package/docs/design/templates/checkbox-group.svg +1 -1
  94. package/docs/design/templates/checkbox.svg +1 -1
  95. package/docs/design/templates/choice-chips/color-palette-dark.svg +1 -1
  96. package/docs/design/templates/choice-chips-dark.svg +1 -1
  97. package/docs/design/templates/color-field/error-dark.svg +1 -1
  98. package/docs/design/templates/color-field/hint.svg +1 -1
  99. package/docs/design/templates/color-field-dark.svg +1 -1
  100. package/docs/design/templates/color-field.svg +1 -1
  101. package/docs/design/templates/color-picker/gray.svg +1 -1
  102. package/docs/design/templates/color-picker/hsb.svg +1 -1
  103. package/docs/design/templates/color-picker/rgb.svg +1 -1
  104. package/docs/design/templates/color-picker.svg +1 -1
  105. package/docs/design/templates/color-swatches/palette-dark.svg +1 -1
  106. package/docs/design/templates/color-swatches-dark.svg +1 -1
  107. package/docs/design/templates/disclosure/embedded.svg +1 -1
  108. package/docs/design/templates/disclosure/framed-sunken.svg +1 -1
  109. package/docs/design/templates/disclosure/plain.svg +1 -1
  110. package/docs/design/templates/disclosure.svg +1 -1
  111. package/docs/design/templates/message-composer/chat.svg +1 -1
  112. package/docs/design/templates/message-composer.svg +1 -1
  113. package/docs/design/templates/progress-bar/determinate.svg +1 -1
  114. package/docs/design/templates/progress-bar/tones.svg +1 -1
  115. package/docs/design/templates/progress-bar.svg +1 -1
  116. package/docs/design/templates/radio-group/horizontal-dark.svg +1 -1
  117. package/docs/design/templates/radio-group/vertical.svg +1 -1
  118. package/docs/design/templates/radio-group-dark.svg +1 -1
  119. package/docs/design/templates/radio-group.svg +1 -1
  120. package/docs/design/templates/search-field/empty.svg +1 -1
  121. package/docs/design/templates/search-field/tokens.svg +1 -1
  122. package/docs/design/templates/search-field.svg +1 -1
  123. package/docs/design/templates/select/form.svg +1 -1
  124. package/docs/design/templates/select.svg +1 -1
  125. package/docs/design/templates/slider/compact.svg +1 -1
  126. package/docs/design/templates/slider/readout.svg +1 -1
  127. package/docs/design/templates/slider/ticks.svg +1 -1
  128. package/docs/design/templates/slider.svg +1 -1
  129. package/docs/design/templates/switch/states.svg +1 -1
  130. package/docs/design/templates/switch.svg +1 -1
  131. package/docs/design/templates/tag-field/error-dark.svg +1 -1
  132. package/docs/design/templates/tag-field/error.svg +1 -1
  133. package/docs/design/templates/tag-field/tags.svg +1 -1
  134. package/docs/design/templates/tag-field-dark.svg +1 -1
  135. package/docs/design/templates/tag-field.svg +1 -1
  136. package/docs/design/templates/text-field/error-dark.svg +1 -1
  137. package/docs/design/templates/text-field/labeled.svg +1 -1
  138. package/docs/design/templates/text-field/multiline.svg +1 -1
  139. package/docs/design/templates/text-field/search.svg +1 -1
  140. package/docs/design/templates/text-field-dark.svg +1 -1
  141. package/docs/design/templates/text-field.svg +1 -1
  142. package/docs/design/templates/toolbar-control-group/icon-tile-danger-dark.svg +1 -1
  143. package/docs/design/templates/toolbar-control-group-dark.svg +1 -1
  144. package/docs/design/templates.md +3 -1
  145. package/docs/layout.md +25 -0
  146. package/docs/manual-test-plan.md +27 -1
  147. package/docs/recipes.md +9 -0
  148. package/docs/surface-scaffold.md +4 -1
  149. package/llms.txt +3 -0
  150. package/package.json +1 -1
  151. package/dist/chunk-5USKCWGL.js +0 -113
  152. package/dist/chunk-5USKCWGL.js.map +0 -1
  153. package/dist/chunk-6CDILXF4.js.map +0 -1
  154. package/dist/chunk-HQZG3OFL.js.map +0 -1
  155. package/dist/chunk-KPINJHIC.js.map +0 -1
  156. package/dist/chunk-SCDWURBO.js.map +0 -1
  157. package/dist/chunk-SOFPUW3O.js.map +0 -1
  158. package/dist/chunk-SQ5DH66U.js.map +0 -1
@@ -1,113 +0,0 @@
1
- import { filterDataAttributes } from './chunk-KH4KEMSP.js';
2
- import { jsx } from 'kerfjs/jsx-runtime';
3
-
4
- function roleForSelectionMode(mode) {
5
- switch (mode) {
6
- case "single":
7
- return "option";
8
- case "multiple":
9
- return "row";
10
- case "none":
11
- case "toggle":
12
- return "button";
13
- }
14
- }
15
- var contentItemProtectedAttributes = /* @__PURE__ */ new Set([
16
- "data-component",
17
- "data-appearance",
18
- "data-outlined",
19
- "data-bubble",
20
- "data-grid-row"
21
- ]);
22
- var interactiveProtectedAttributes = /* @__PURE__ */ new Set([
23
- "data-component",
24
- "data-appearance",
25
- "data-outlined",
26
- "data-bubble",
27
- "data-grid-row",
28
- "data-action",
29
- "data-item-id",
30
- "data-interactive",
31
- "data-selected",
32
- "data-disabled",
33
- "data-selection-mode",
34
- "data-kui-pressed"
35
- ]);
36
- function ContentItem({
37
- appearance = "transparent",
38
- children,
39
- frame = "none",
40
- flush = false,
41
- shape = "rounded",
42
- bubble,
43
- title,
44
- ariaLabel,
45
- focusTarget = false,
46
- outlined = false,
47
- tabIndex,
48
- gridRow = false,
49
- interactive = false,
50
- action,
51
- itemId,
52
- selectionMode = "none",
53
- selected = false,
54
- disabled = false,
55
- className = "",
56
- rootAttributes = {},
57
- slot
58
- }) {
59
- const safeRootAttributes = filterDataAttributes(
60
- rootAttributes,
61
- interactive ? interactiveProtectedAttributes : contentItemProtectedAttributes
62
- );
63
- if (interactive && !action) {
64
- throw new Error("Interactive ContentItem requires an action");
65
- }
66
- if (interactive && selected && selectionMode === "none") {
67
- throw new Error("Selected ContentItem requires a selectionMode");
68
- }
69
- const cls = [
70
- "kui-content-item",
71
- shape === "pill" ? "kui-content-item--pill" : "",
72
- frame === "framed" ? "kui-content-item--framed" : "",
73
- flush ? "kui-content-item--flush" : "",
74
- className
75
- ].filter(Boolean).join(" ");
76
- const interactiveAttributes = interactive ? {
77
- "data-interactive": "true",
78
- "data-action": disabled ? void 0 : action,
79
- "data-item-id": itemId,
80
- "data-selection-mode": selectionMode,
81
- "data-selected": selectionMode === "none" ? void 0 : String(selected),
82
- "data-disabled": disabled ? "true" : void 0
83
- } : {};
84
- let role = ariaLabel ? "region" : void 0;
85
- if (interactive) role = roleForSelectionMode(selectionMode);
86
- else if (gridRow) role = "row";
87
- return /* @__PURE__ */ jsx(
88
- "div",
89
- {
90
- ...safeRootAttributes,
91
- ...interactiveAttributes,
92
- class: cls,
93
- title,
94
- "data-component": "content-item",
95
- "data-appearance": appearance,
96
- "data-outlined": outlined ? "true" : void 0,
97
- "data-bubble": bubble,
98
- "data-grid-row": !interactive && gridRow ? "true" : void 0,
99
- role,
100
- "aria-label": ariaLabel,
101
- "aria-selected": interactive && (selectionMode === "single" || selectionMode === "multiple") ? String(selected) : void 0,
102
- "aria-pressed": interactive && selectionMode === "toggle" ? String(selected) : void 0,
103
- "aria-disabled": interactive && disabled ? "true" : void 0,
104
- tabindex: interactive ? disabled ? "-1" : "0" : tabIndex ?? (focusTarget ? "-1" : void 0),
105
- slot,
106
- children: interactive && selectionMode === "multiple" || !interactive && gridRow ? /* @__PURE__ */ jsx("div", { role: "gridcell", children }) : children
107
- }
108
- );
109
- }
110
-
111
- export { ContentItem };
112
-
113
- //# sourceMappingURL=chunk-5USKCWGL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/surfaces/content-item/content-item.tsx"],"names":[],"mappings":"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","file":"chunk-5USKCWGL.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport type { SemanticTone } from '../../../shared/styles/semantic-tone.js';\n\nexport type { SemanticTone } from '../../../shared/styles/semantic-tone.js';\n\n/**\n * Base surface treatment, semantic status colors, or `brand-loud`: the solid\n * brand fill with its on-loud foreground (a transcript's own messages).\n */\nexport type ContentItemAppearance =\n 'transparent' | 'surface' | 'brand-loud' | SemanticTone;\n\n/**\n * A chat-bubble layout for transcripts: the item fits its content up to 80%\n * of the row and sits at the `start` (other participants) or `end` (the\n * person's own messages) of the line.\n */\nexport type ContentItemBubble = 'start' | 'end';\n\n/** Whether the item's always-reserved 1px border is transparent or visible. */\nexport type ContentItemFrame = 'none' | 'framed';\n\n/** Corner shape: the 12px rounded rectangle or the 22px pill. */\nexport type ContentItemShape = 'rounded' | 'pill';\n/** `single` uses an option; `multiple` uses a grid row; `toggle` uses a pressed button. */\nexport type ContentItemSelectionMode =\n 'none' | 'single' | 'multiple' | 'toggle';\n\nfunction roleForSelectionMode(\n mode: ContentItemSelectionMode,\n): 'option' | 'row' | 'button' {\n switch (mode) {\n case 'single':\n return 'option';\n case 'multiple':\n return 'row';\n case 'none':\n case 'toggle':\n return 'button';\n }\n}\n\nconst contentItemProtectedAttributes = new Set([\n 'data-component',\n 'data-appearance',\n 'data-outlined',\n 'data-bubble',\n 'data-grid-row',\n]);\nconst interactiveProtectedAttributes = new Set([\n 'data-component',\n 'data-appearance',\n 'data-outlined',\n 'data-bubble',\n 'data-grid-row',\n 'data-action',\n 'data-item-id',\n 'data-interactive',\n 'data-selected',\n 'data-disabled',\n 'data-selection-mode',\n 'data-kui-pressed',\n]);\n\ntype ContentItemRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-appearance'?: never;\n 'data-outlined'?: never;\n 'data-bubble'?: never;\n 'data-grid-row'?: never;\n }\n>;\n\ntype ContentItemInteractiveRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-appearance'?: never;\n 'data-outlined'?: never;\n 'data-bubble'?: never;\n 'data-grid-row'?: never;\n 'data-action'?: never;\n 'data-item-id'?: never;\n 'data-interactive'?: never;\n 'data-selected'?: never;\n 'data-disabled'?: never;\n 'data-selection-mode'?: never;\n 'data-kui-pressed'?: never;\n }\n>;\n\ninterface ContentItemBaseProps {\n /**\n * Coordinated background, border, and foreground colors. `transparent`\n * preserves the surrounding surface; `surface` paints the base surface;\n * semantic values match StateBanner. Defaults to `transparent`.\n */\n appearance?: ContentItemAppearance;\n /** Item content; a plain string is allowed for bare copy. */\n children?: KerfUiContent | string;\n /**\n * `framed` paints the standard neutral border in the 1px the item always\n * reserves, so framing never changes geometry. Frame only an item that\n * marks a real distinction. Defaults to `none` (transparent border).\n */\n frame?: ContentItemFrame;\n /** Remove block padding and block borders while retaining inline geometry. */\n flush?: boolean;\n /** Corner shape. Defaults to `rounded`. */\n shape?: ContentItemShape;\n /**\n * Lay the item out as a chat bubble: content width up to 80% of the row,\n * at the `start` or `end` of the line. Pair `end` with `brand-loud` for the\n * person's own messages. Omit for an ordinary full-width item.\n */\n bubble?: ContentItemBubble;\n /** Native hover tooltip. */\n title?: string;\n /**\n * Names the item as a distinct region (`role=\"region\"`). Omit it for an\n * ordinary item, which stays a non-landmark grouping.\n */\n ariaLabel?: string;\n /**\n * Makes the item a programmatic focus target (`tabindex=\"-1\"`, never a tab\n * stop), for example the preferred initial focus of a NavStack view when\n * combined with `data-nav-focus` in `rootAttributes`.\n */\n focusTarget?: boolean;\n /** Keep the standard focus outline visible, such as for a drop target. */\n outlined?: boolean;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport type ContentItemProps = ContentItemBaseProps &\n (\n | {\n interactive?: false;\n action?: never;\n itemId?: never;\n selectionMode?: never;\n selected?: never;\n disabled?: never;\n /** Opt into keyboard (`0`) or programmatic (`-1`) focus. */\n tabIndex?: 0 | -1;\n /**\n * A non-selectable row of a multi-select `List` or `Grid`: renders\n * `role=\"row\"` around a `gridcell`, with no `aria-selected` and no\n * Tab stop of its own, for content between selectable rows (an\n * activity group, a \"messages skipped\" divider). Its controls stay\n * reachable by Tab; arrow keys skip it.\n */\n gridRow?: boolean;\n /** Existing static `data-*` metadata remains available. */\n rootAttributes?: ContentItemRootAttributes;\n }\n | {\n /** Enable a keyboard reachable card; wire `wireContentItems` once on its containing root. */\n interactive: true;\n /** Delegated action dispatched by pointer, Enter, or Space. */\n action: string;\n itemId?: string;\n selectionMode?: ContentItemSelectionMode;\n selected?: boolean;\n disabled?: boolean;\n tabIndex?: never;\n /** An interactive item is already a row in a multi-select grid. */\n gridRow?: never;\n /** Safe app metadata; interaction attributes are component-owned. */\n rootAttributes?: ContentItemInteractiveRootAttributes;\n }\n );\n\n/**\n * One self-contained `.kui-content` child: an 8px inline margin, a real 1px\n * border (transparent unless `framed`), 8px padding, and a rounded or pill\n * radius. It owns that whole geometry, so wrappers must not add more.\n */\nexport function ContentItem({\n appearance = 'transparent',\n children,\n frame = 'none',\n flush = false,\n shape = 'rounded',\n bubble,\n title,\n ariaLabel,\n focusTarget = false,\n outlined = false,\n tabIndex,\n gridRow = false,\n interactive = false,\n action,\n itemId,\n selectionMode = 'none',\n selected = false,\n disabled = false,\n className = '',\n rootAttributes = {},\n slot,\n}: ContentItemProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n interactive\n ? interactiveProtectedAttributes\n : contentItemProtectedAttributes,\n );\n if (interactive && !action) {\n throw new Error('Interactive ContentItem requires an action');\n }\n if (interactive && selected && selectionMode === 'none') {\n throw new Error('Selected ContentItem requires a selectionMode');\n }\n const cls = [\n 'kui-content-item',\n shape === 'pill' ? 'kui-content-item--pill' : '',\n frame === 'framed' ? 'kui-content-item--framed' : '',\n flush ? 'kui-content-item--flush' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n const interactiveAttributes = interactive\n ? {\n 'data-interactive': 'true',\n 'data-action': disabled ? undefined : action,\n 'data-item-id': itemId,\n 'data-selection-mode': selectionMode,\n 'data-selected':\n selectionMode === 'none' ? undefined : String(selected),\n 'data-disabled': disabled ? 'true' : undefined,\n }\n : {};\n let role: 'option' | 'row' | 'button' | 'region' | undefined = ariaLabel\n ? 'region'\n : undefined;\n if (interactive) role = roleForSelectionMode(selectionMode);\n else if (gridRow) role = 'row';\n return (\n <div\n {...safeRootAttributes}\n {...interactiveAttributes}\n class={cls}\n title={title}\n data-component=\"content-item\"\n data-appearance={appearance}\n data-outlined={outlined ? 'true' : undefined}\n data-bubble={bubble}\n data-grid-row={!interactive && gridRow ? 'true' : undefined}\n role={role}\n aria-label={ariaLabel}\n aria-selected={\n interactive &&\n (selectionMode === 'single' || selectionMode === 'multiple')\n ? String(selected)\n : undefined\n }\n aria-pressed={\n interactive && selectionMode === 'toggle' ? String(selected) : undefined\n }\n aria-disabled={interactive && disabled ? 'true' : undefined}\n tabindex={\n interactive\n ? disabled\n ? '-1'\n : '0'\n : (tabIndex ?? (focusTarget ? '-1' : undefined))\n }\n slot={slot}\n >\n {(interactive && selectionMode === 'multiple') ||\n (!interactive && gridRow) ? (\n <div role=\"gridcell\">{children}</div>\n ) : (\n children\n )}\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/surfaces/surface-scaffold/surface-scaffold.tsx"],"names":[],"mappings":";;;;;AA+DA,IAAM,wBAAA,uBAA+B,GAAA,CAAI;AAAA,EACvC,gBAAA;AAAA,EACA,WAAA;AAAA,EACA,mBAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA,mBAAA;AAAA,EACA,sBAAA;AAAA,EACA,iBAAA;AAAA,EACA,aAAA;AAAA,EACA,kBAAA;AAAA,EACA,0BAAA;AAAA,EACA,0BAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACF,CAAC,CAAA;AA+IM,SAAS,aAAA,CAAc;AAAA,EAC5B,EAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA,GAAQ,KAAA;AAAA,EACR,OAAA;AAAA,EACA,aAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA,GAAgB,KAAA;AAAA,EAChB,YAAA,GAAe,KAAA;AAAA,EACf,UAAA,GAAa,OAAA;AAAA,EACb,QAAA;AAAA,EACA,IAAA,GAAO,QAAA;AAAA,EACP,YAAA,GAAe,OAAA;AAAA,EACf,cAAA;AAAA,EACA,SAAA,GAAY,SAAA;AAAA,EACZ,WAAA,GAAc,aAAA;AAAA,EACd,cAAA;AAAA,EACA,SAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,WAAA,GAAc,OAAA;AAAA,EACd,UAAA,GAAa,OAAA;AAAA,EACb,UAAA,GAAa,MAAA;AAAA,EACb,kBAAA,GAAqB,QAAA;AAAA,EACrB,kBAAA,GAAqB,QAAA;AAAA,EACrB,YAAA;AAAA,EACA,iBAAiB,EAAC;AAAA,EAClB,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAuB;AACrB,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,cAAA,KAAmB,MAAA,GACf,EAAA,GACA,CAAA,sCAAA,EAAyC,cAAc,CAAA,CAAA;AAAA,IAC3D,cAAA,KAAmB,MAAA,GACf,EAAA,GACA,CAAA,6BAAA,EAAgC,cAAc,CAAA,CAAA;AAAA,IAClD,cAAc,MAAA,IAAa,SAAA,KAAc,UAAA,GACrC,EAAA,GACA,oCAAoC,SAAS,CAAA,CAAA;AAAA,IACjD,WAAW,MAAA,IAAa,MAAA,KAAW,UAAA,GAC/B,EAAA,GACA,gCAAgC,MAAM,CAAA,CAAA;AAAA,IAC1C,YAAA,KAAiB,MAAA,GACb,EAAA,GACA,CAAA,oCAAA,EAAuC,YAAY,CAAA,CAAA;AAAA,IACvD,SAAA,KAAc,MAAA,GACV,EAAA,GACA,CAAA,iCAAA,EAAoC,SAAS,CAAA;AAAA,GACnD,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACX,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,oBAAA,CAAqB,cAAA,EAAgB,wBAAwB,CAAA;AAAA,MACjE,EAAA;AAAA,MACA,KAAA,EAAO,CAAA,mBAAA,EAAsB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC9C,IAAA,EAAM,QAAQ,aAAA,GAAgB,MAAA;AAAA,MAC9B,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,kBAAA,EAAkB,WAAA;AAAA,MAClB,QAAA,EAAU,EAAA;AAAA,MACV,oBAAA,EAAoB,eAAe,EAAA,GAAK,MAAA;AAAA,MACxC,gBAAA,EAAe,gBAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,mBAAA,EAAmB,YAAA;AAAA,MACnB,sBAAA,EAAsB,cAAA,KAAmB,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MACjE,iBAAA,EAAiB,SAAA;AAAA,MACjB,mBAAA,EAAmB,WAAA;AAAA,MACnB,sBAAA,EAAsB,cAAA,KAAmB,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MACjE,iBAAA,EAAiB,SAAA,KAAc,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MACvD,aAAA,EAAa,MAAA,KAAW,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MAChD,kBAAA,EAAkB,UAAA,KAAe,MAAA,GAAS,MAAA,GAAY,UAAA;AAAA,MACtD,0BAAA,EACE,kBAAA,KAAuB,UAAA,GAAa,UAAA,GAAa,MAAA;AAAA,MAEnD,0BAAA,EACE,kBAAA,KAAuB,UAAA,GAAa,UAAA,GAAa,MAAA;AAAA,MAEnD,iBAAA,EAAiB,SAAA,KAAc,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MACvD,gBAAA,EAAgB,YAAY,EAAA,GAAK,MAAA;AAAA,MACjC,mBAAA,EAAmB,WAAA,KAAgB,OAAA,GAAU,MAAA,GAAY,WAAA;AAAA,MACzD,kBAAA,EAAkB,UAAA,KAAe,OAAA,GAAU,MAAA,GAAY,UAAA;AAAA,MACvD,OAAO,KAAA,IAAS,MAAA;AAAA,MAChB,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,aAAA,GAAgB,IAAA,mBACf,IAAA,CAAC,QAAA,EAAA,EAAO,KAAA,EAAM,4BAAA,EACX,QAAA,EAAA;AAAA,UAAA,OAAA,KAAY,MAAA,mBACX,GAAA,CAAC,IAAA,EAAA,EAAG,KAAA,EAAM,2BAAA,EAA6B,QAAA,EAAA,KAAA,EAAM,CAAA,mBAE7C,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,2BAAA,EAA6B,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,0BAElD,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,oCAAA,EACR,QAAA,EAAA;AAAA,YAAA,aAAA;AAAA,4BACD,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAA,EAAK,QAAA;AAAA,gBACL,KAAA,EAAM,2BAAA;AAAA,gBACN,YAAA,EAAY,UAAA;AAAA,gBACZ,mBAAA,EAAkB,EAAA;AAAA,gBAElB,8BAAC,UAAA,EAAA,EAAW,IAAA,EAAM,GAAG,IAAA,EAAK,GAAA,EAAI,MAAK,GAAA,EAAI;AAAA;AAAA;AACzC,WAAA,EACF;AAAA,SAAA,EACF,CAAA;AAAA,QAED,YAAA,KAAiB,kBAAkB,SAAA,mBAClC,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,kCAAA;AAAA,YACN,IAAA,EAAK,WAAA;AAAA,YACL,kBAAA,EAAiB,YAAA;AAAA,YACjB,YAAA,EAAW,cAAA;AAAA,YACX,QAAA,EAAU;AAAA;AAAA,SACZ,GACE,IAAA;AAAA,wBACJ,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,0BAAA,EAA4B,QAAA,EAAS,CAAA;AAAA,QAC/C,WAAW,MAAA,GAAY,IAAA,uBACrB,QAAA,EAAA,EAAO,KAAA,EAAM,8BAA8B,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,4BAIpD,KAAA,EAAA,EAAI,wBAAA,EAAsB,MAAC,iBAAA,EAAe,IAAA,EAAC,OAAM,kBAAA,EAAmB;AAAA;AAAA;AAAA,GACvE;AAEJ;AAkDA,IAAM,wBAAA,uBAA+B,GAAA,CAAI;AAAA,EACvC,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,WAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAC,CAAA;AASM,SAAS,oBAAA,CAAqB;AAAA,EACnC,EAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,YAAA,GAAe,SAAA;AAAA,EACf,IAAA,GAAO,QAAA;AAAA,EACP,cAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA,GAAa,MAAA;AAAA,EACb,iBAAiB,EAAC;AAAA,EAClB,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,cAAA,KAAmB,MAAA,GACf,EAAA,GACA,CAAA,8CAAA,EAAiD,cAAc,CAAA,CAAA;AAAA,IACnE,cAAA,KAAmB,MAAA,GACf,EAAA,GACA,CAAA,qCAAA,EAAwC,cAAc,CAAA,CAAA;AAAA,IAC1D,WAAW,MAAA,IAAa,MAAA,KAAW,UAAA,GAC/B,EAAA,GACA,wCAAwC,MAAM,CAAA,CAAA;AAAA,IAClD,cAAc,MAAA,IAAa,SAAA,KAAc,UAAA,GACrC,EAAA,GACA,4CAA4C,SAAS,CAAA;AAAA,GAC3D,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACX,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACE,GAAG,oBAAA,CAAqB,cAAA,EAAgB,wBAAwB,CAAA;AAAA,MACjE,EAAA;AAAA,MACA,KAAA,EAAO,CAAA,2BAAA,EAA8B,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACtD,gBAAA,EAAe,wBAAA;AAAA,MACf,mBAAA,EAAmB,YAAA;AAAA,MACnB,WAAA,EAAW,IAAA;AAAA,MACX,aAAA,EAAa,MAAA,KAAW,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MAChD,iBAAA,EAAiB,SAAA,KAAc,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,MACvD,kBAAA,EAAkB,UAAA,KAAe,MAAA,GAAS,MAAA,GAAY,UAAA;AAAA,MACtD,OAAA,EAAS,YAAA,KAAiB,SAAA,GAAY,MAAA,GAAS,MAAA;AAAA,MAC/C,IAAA,EAAK,QAAA;AAAA,MACL,YAAA,EAAY,KAAA;AAAA,MACZ,iBAAA,EAAiB,UAAA;AAAA,MACjB,kBAAA,EAAkB,WAAA;AAAA,MAClB,OAAO,KAAA,IAAS,MAAA;AAAA,MAChB,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ;AAaO,SAAS,YAAA,CAAa;AAAA,EAC3B,QAAA;AAAA,EACA,KAAA,GAAQ,UAAA;AAAA,EACR,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAsB;AACpB,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,kBAAA,EAAqB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MAC7C,gBAAA,EAAe,eAAA;AAAA,MACf,YAAA,EAAY,KAAA;AAAA,MACZ,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-6CDILXF4.js","sourcesContent":["import { X } from 'lucide';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport type { CssLength } from '../../../shared/styles/css-values.js';\nimport { LucideIcon } from '../../media/lucide-icon/lucide-icon.js';\n\nexport {\n closeDialog,\n type DialogCloseSource,\n type DialogRequestCloseDetail,\n openDialog,\n} from './internal/dialog-surface-controller.js';\n\nexport type DialogSurfaceSize = 'small' | 'medium' | 'large';\n/**\n * How the dialog is presented: `modal` (default) centered on the screen,\n * `side-sheet` against the inline end, `fullscreen`, or `bottom-sheet`\n * attached to the bottom edge (square bottom corners, safe-area and\n * virtual-keyboard clearance, optionally user-resizable).\n */\nexport type DialogSurfacePresentation =\n 'modal' | 'side-sheet' | 'fullscreen' | 'bottom-sheet';\n/**\n * How a bottom sheet appears or leaves: `slide` (default) moves the panel in\n * from, or out to, the bottom edge; `standard` keeps the dialog's\n * scale-and-fade. Both honor `prefers-reduced-motion`.\n */\nexport type DialogSurfaceSheetMotion = 'slide' | 'standard';\nexport type SurfaceInset = 'none' | 'compact' | 'comfortable';\nexport type DialogSurfaceMaxHeight = CssLength | 'viewport';\n/** A definite modal height: a length or the full viewport, minus both gutters. */\nexport type DialogSurfaceHeight = CssLength | 'viewport';\n/**\n * How the dialog body lays out its children: `flow` (default) scrolls ordinary\n * content in the body; `fill` gives one child the body's whole height and\n * lets it own scrolling (a SplitView, a Pane, an editor); `fill-last` stacks\n * the leading children at their natural height and gives the last child the\n * remaining height to own its scrolling (a heading and notices above a\n * scrolling transcript).\n */\nexport type DialogSurfaceBodyLayout = 'flow' | 'fill' | 'fill-last';\n/**\n * Where the dialog footer sits: `docked` (default) below the body, or\n * `floating` over the body's block end, inset from the panel's inline and\n * block-end edges on a transparent background (a chat composer).\n */\nexport type DialogSurfaceFooterPresentation = 'docked' | 'floating';\n/**\n * Where the dialog header sits: `docked` (default) above the body, or\n * `floating` over the body's block-start edge on the translucent chrome\n * material, so content scrolls visibly beneath the title bar.\n */\nexport type DialogSurfaceHeaderPresentation = 'docked' | 'floating';\n\n/**\n * Application `data-*` identity on the DialogSurface root, such as\n * `data-key`; the surface's own configuration attributes stay protected.\n */\nexport type DialogSurfaceRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined>\n>;\n\nconst DIALOG_SURFACE_PROTECTED = new Set([\n 'data-component',\n 'data-size',\n 'data-presentation',\n 'data-preferred-width',\n 'data-body-inset',\n 'data-footer-inset',\n 'data-viewport-gutter',\n 'data-max-height',\n 'data-height',\n 'data-body-layout',\n 'data-footer-presentation',\n 'data-header-presentation',\n 'data-min-height',\n 'data-resizable',\n 'data-enter-motion',\n 'data-exit-motion',\n 'data-light-dismiss',\n]);\n\n/**\n * The dialog's accessible name: its `label` text (also the default title), or\n * the id of an element that names it, such as a `heading` ToolbarText.\n */\nexport type DialogSurfaceName =\n { label: string; labelledBy?: never } | { label?: never; labelledBy: string };\n\nexport type DialogSurfaceProps = DialogSurfaceName & DialogSurfaceOptions;\n\nexport interface DialogSurfaceOptions {\n /** The dialog's id, for `openDialog(document.getElementById(id))`. */\n id?: string;\n /**\n * Id of the element whose text is the dialog's accessible description,\n * such as the `heading` ToolbarText's `descriptionId` or app-owned summary\n * copy in the body; rendered as `aria-describedby` on the `<dialog>`.\n */\n describedBy?: string;\n /**\n * An alert dialog: a confirmation that interrupts the person to report\n * something urgent or ask before a destructive action (\"Delete this\n * topic?\"). Renders `role=\"alertdialog\"` on the `<dialog>`; set\n * `describedBy` to the element holding the message, and leave\n * `lightDismiss` off so the person answers it.\n */\n alert?: boolean;\n /** The body content. */\n children: KerfUiContent;\n /**\n * Header title content in place of the `label` text, such as an xl\n * `ToolbarText` with a description. The dialog keeps its `label` (or\n * `labelledBy`) name.\n */\n heading?: KerfUiContent;\n /** Controls before the close button in the header. */\n headerActions?: KerfUiContent;\n /** The footer, below the body (or floating over it); usually its buttons. */\n footer?: KerfUiContent;\n /**\n * Render no header: no title and no close button. The content then owns its\n * heading and a way to close (an element with `data-dialog-close`).\n */\n withoutHeader?: boolean;\n /** Close on a press on the backdrop; otherwise the panel pulses. */\n lightDismiss?: boolean;\n /** The close button's accessible name (default `Close`). */\n closeLabel?: string;\n size?: DialogSurfaceSize;\n presentation?: DialogSurfacePresentation;\n /** Modal preferred width. Takes precedence over size, within the viewport cap. */\n preferredWidth?: CssLength;\n bodyInset?: SurfaceInset;\n footerInset?: SurfaceInset;\n /** Modal edge clearance. Omit to retain Web Awesome's default viewport cap. */\n viewportGutter?: CssLength;\n /**\n * Modal height cap, bounded by the dynamic viewport minus both gutters. On a\n * bottom sheet, the cap (and the resize ceiling), bounded by the dynamic\n * viewport minus the top safe area and one gutter.\n */\n maxHeight?: DialogSurfaceMaxHeight;\n /**\n * Modal definite height, bounded the same way, so a filling child has a\n * height to fill. Takes precedence over `maxHeight`. On a bottom sheet, the\n * height it opens at (the visible height above the safe area or keyboard).\n */\n height?: DialogSurfaceHeight;\n /**\n * A resizable bottom sheet's resize floor (default 160px), the visible\n * height above the safe area or keyboard.\n */\n minHeight?: CssLength;\n /**\n * Let the person resize a bottom sheet by its top grabber (drag, or the\n * arrow, Page Up/Down, Home and End keys) between `minHeight` and the\n * sheet's cap. Needs the `/register` entry; each opening starts at `height`\n * (or the content height). Ignored by other presentations.\n */\n resizable?: boolean;\n /** How a bottom sheet appears (default `slide` up from the bottom edge). */\n enterMotion?: DialogSurfaceSheetMotion;\n /** How a bottom sheet is dismissed (default `slide` down off the bottom edge). */\n exitMotion?: DialogSurfaceSheetMotion;\n /**\n * Body layout (default `flow`); `fill` lets one child own the body and\n * `fill-last` stacks fixed rows above one filling last child.\n */\n bodyLayout?: DialogSurfaceBodyLayout;\n /**\n * Header placement (default `docked`); `floating` lays the dialog's header\n * (its title and close control) over the body's block-start edge on the\n * translucent chrome material (`--kui-chrome-material-raised`, opaque under\n * `prefers-reduced-transparency`, increased contrast, forced colors, or\n * without `backdrop-filter`). The `/register` entry measures the header;\n * the body reserves that height before its own inset, so its first content\n * rests below the title bar. A `fill`/`fill-last` child that is the body's\n * only child and opts into block-start `scrollClearance` (a `List` or\n * `Pane`) takes the clearance inside its own scroll area instead, published\n * as `--kui-scroll-clearance-block-start`, so its content scrolls visibly\n * beneath the header. Unmeasured (without the register), the header stays\n * docked. Keep header text in the normal text color: quiet text can fall\n * below AA over the content passing beneath it.\n */\n headerPresentation?: DialogSurfaceHeaderPresentation;\n /**\n * Footer placement (default `docked`); `floating` lays the footer over the\n * body's block end. The body reserves the footer's measured height so its\n * last content is never hidden beneath it. A `fill`/`fill-last` child that\n * opts into block-end `scrollClearance` (a `List` or `Pane`) takes that\n * clearance inside its own scroll area instead, published as\n * `--kui-scroll-clearance-block-end`, so its content scrolls visibly beneath\n * the transparent footer.\n */\n footerPresentation?: DialogSurfaceFooterPresentation;\n /**\n * A floating footer's clearance from the panel's inline and block-end edges\n * (default the 16px container inset). Choose a phone value such as\n * `remify(8)` from `deviceClass()`; the scaffold adds no breakpoint.\n */\n footerOffset?: CssLength;\n /**\n * Safe `data-*` identity on the root. Give sibling dialogs distinct\n * `data-key`s so a re-render morphs each surface into itself instead of\n * reusing one dialog's element for another (structurally identical roots\n * are otherwise matched by position).\n */\n rootAttributes?: DialogSurfaceRootAttributes;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A modal dialog: a native `<dialog>` with Kerf's header, body, and footer\n * chrome, sized and presented by its props. Render it closed, then open it\n * with `openDialog()` and close it with `closeDialog()`, the close button, an\n * element with `data-dialog-close`, Escape, or (with `lightDismiss`) a press\n * on the backdrop. Import `@kerfjs/ui/surface-scaffold/register` for the\n * floating header and footer measurement, the bottom sheet's keyboard\n * clearance and grabber, and re-render resilience while open.\n */\nexport function DialogSurface({\n id,\n label,\n labelledBy,\n describedBy,\n alert = false,\n heading,\n headerActions,\n footer,\n withoutHeader = false,\n lightDismiss = false,\n closeLabel = 'Close',\n children,\n size = 'medium',\n presentation = 'modal',\n preferredWidth,\n bodyInset = 'compact',\n footerInset = 'comfortable',\n viewportGutter,\n maxHeight,\n height,\n minHeight,\n resizable = false,\n enterMotion = 'slide',\n exitMotion = 'slide',\n bodyLayout = 'flow',\n headerPresentation = 'docked',\n footerPresentation = 'docked',\n footerOffset,\n rootAttributes = {},\n className = '',\n slot,\n}: DialogSurfaceProps) {\n const style = [\n preferredWidth === undefined\n ? ''\n : `--_kui-dialog-surface-preferred-width:${preferredWidth}`,\n viewportGutter === undefined\n ? ''\n : `--_kui-dialog-surface-gutter:${viewportGutter}`,\n maxHeight === undefined || maxHeight === 'viewport'\n ? ''\n : `--_kui-dialog-surface-max-height:${maxHeight}`,\n height === undefined || height === 'viewport'\n ? ''\n : `--_kui-dialog-surface-height:${height}`,\n footerOffset === undefined\n ? ''\n : `--_kui-dialog-surface-footer-offset:${footerOffset}`,\n minHeight === undefined\n ? ''\n : `--_kui-dialog-surface-min-height:${minHeight}`,\n ]\n .filter(Boolean)\n .join(';');\n return (\n <dialog\n {...filterDataAttributes(rootAttributes, DIALOG_SURFACE_PROTECTED)}\n id={id}\n class={`kui-dialog-surface ${className}`.trim()}\n role={alert ? 'alertdialog' : undefined}\n aria-label={label}\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n tabindex={-1}\n data-light-dismiss={lightDismiss ? '' : undefined}\n data-component=\"dialog-surface\"\n data-size={size}\n data-presentation={presentation}\n data-preferred-width={preferredWidth === undefined ? undefined : ''}\n data-body-inset={bodyInset}\n data-footer-inset={footerInset}\n data-viewport-gutter={viewportGutter === undefined ? undefined : ''}\n data-max-height={maxHeight === undefined ? undefined : ''}\n data-height={height === undefined ? undefined : ''}\n data-body-layout={bodyLayout === 'flow' ? undefined : bodyLayout}\n data-header-presentation={\n headerPresentation === 'floating' ? 'floating' : undefined\n }\n data-footer-presentation={\n footerPresentation === 'floating' ? 'floating' : undefined\n }\n data-min-height={minHeight === undefined ? undefined : ''}\n data-resizable={resizable ? '' : undefined}\n data-enter-motion={enterMotion === 'slide' ? undefined : enterMotion}\n data-exit-motion={exitMotion === 'slide' ? undefined : exitMotion}\n style={style || undefined}\n slot={slot}\n >\n {withoutHeader ? null : (\n <header class=\"kui-dialog-surface__header\">\n {heading === undefined ? (\n <h2 class=\"kui-dialog-surface__title\">{label}</h2>\n ) : (\n <div class=\"kui-dialog-surface__title\">{heading}</div>\n )}\n <div class=\"kui-dialog-surface__header-actions\">\n {headerActions}\n <button\n type=\"button\"\n class=\"kui-dialog-surface__close\"\n aria-label={closeLabel}\n data-dialog-close=\"\"\n >\n <LucideIcon icon={X} name=\"x\" size=\"l\" />\n </button>\n </div>\n </header>\n )}\n {presentation === 'bottom-sheet' && resizable ? (\n <div\n class=\"kui-dialog-surface__sheet-handle\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-label=\"Resize sheet\"\n tabindex={0}\n />\n ) : null}\n <div class=\"kui-dialog-surface__body\">{children}</div>\n {footer === undefined ? null : (\n <footer class=\"kui-dialog-surface__footer\">{footer}</footer>\n )}\n {/* Where kerfjs/overlay hosts a popover or tooltip opened inside the\n modal dialog, so it stays interactive above the inert page. */}\n <div data-kerf-overlay-host data-morph-skip style=\"display:contents\" />\n </dialog>\n );\n}\n\n/** Where a PopoverDialogSurface appears: the top layer, or in flow. */\nexport type PopoverDialogSurfacePresentation = 'overlay' | 'embedded';\n\n/** Application `data-*` metadata on the surface root. */\nexport type PopoverDialogSurfaceDataAttributes = Readonly<\n Record<`data-${string}`, string>\n>;\n\ntype PopoverDialogSurfaceName =\n { label: string; labelledBy?: never } | { label?: never; labelledBy: string };\n\nexport type PopoverDialogSurfaceProps = PopoverDialogSurfaceName & {\n /** The root id: what an opening control's `popovertarget` names. */\n id?: string;\n /**\n * Id of the element whose text is the dialog's accessible description,\n * such as a title `ToolbarText`'s `descriptionId`; rendered as\n * `aria-describedby` on the `role=\"dialog\"` root.\n */\n describedBy?: string;\n children: KerfUiContent;\n /**\n * `overlay` (default) is a native `popover=\"auto\"` in the top layer:\n * non-modal, light dismiss (Escape or a press outside), nothing inert.\n * `embedded` renders the same surface in flow for a catalog or inline use.\n */\n presentation?: PopoverDialogSurfacePresentation;\n /** Preferred width preset: 400px, 560px (default), or 800px. */\n size?: DialogSurfaceSize;\n /** Preferred width; takes precedence over `size`, within the viewport cap. */\n preferredWidth?: CssLength;\n /** Definite height, bounded by the dynamic viewport minus both gutters. */\n height?: DialogSurfaceHeight;\n /** Height cap, bounded the same way, for a surface that sizes to content. */\n maxHeight?: DialogSurfaceMaxHeight;\n /** Edge clearance on each side of the viewport (default 16px). */\n viewportGutter?: CssLength;\n /**\n * Body layout (default `flow`); `fill` lets one child own the surface and\n * `fill-last` stacks fixed rows above one filling last child.\n */\n bodyLayout?: DialogSurfaceBodyLayout;\n rootAttributes?: PopoverDialogSurfaceDataAttributes;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n};\n\nconst POPOVER_DIALOG_PROTECTED = new Set([\n 'data-component',\n 'data-presentation',\n 'data-size',\n 'data-height',\n 'data-max-height',\n 'data-body-layout',\n]);\n\n/**\n * A non-modal dialog surface on the native Popover API: Kerf's dialog chrome,\n * viewport-bounded size, and single-child fill without application CSS.\n * Open it with a `popovertarget` control or `showPopover()`; it light\n * dismisses and leaves the page interactive. Use `DialogSurface` when the\n * task must block the page.\n */\nexport function PopoverDialogSurface({\n id,\n children,\n label,\n labelledBy,\n describedBy,\n presentation = 'overlay',\n size = 'medium',\n preferredWidth,\n height,\n maxHeight,\n viewportGutter,\n bodyLayout = 'flow',\n rootAttributes = {},\n className = '',\n slot,\n}: PopoverDialogSurfaceProps) {\n const style = [\n preferredWidth === undefined\n ? ''\n : `--_kui-popover-dialog-surface-preferred-width:${preferredWidth}`,\n viewportGutter === undefined\n ? ''\n : `--_kui-popover-dialog-surface-gutter:${viewportGutter}`,\n height === undefined || height === 'viewport'\n ? ''\n : `--_kui-popover-dialog-surface-height:${height}`,\n maxHeight === undefined || maxHeight === 'viewport'\n ? ''\n : `--_kui-popover-dialog-surface-max-height:${maxHeight}`,\n ]\n .filter(Boolean)\n .join(';');\n return (\n <section\n {...filterDataAttributes(rootAttributes, POPOVER_DIALOG_PROTECTED)}\n id={id}\n class={`kui-popover-dialog-surface ${className}`.trim()}\n data-component=\"popover-dialog-surface\"\n data-presentation={presentation}\n data-size={size}\n data-height={height === undefined ? undefined : ''}\n data-max-height={maxHeight === undefined ? undefined : ''}\n data-body-layout={bodyLayout === 'flow' ? undefined : bodyLayout}\n popover={presentation === 'overlay' ? 'auto' : undefined}\n role=\"dialog\"\n aria-label={label}\n aria-labelledby={labelledBy}\n aria-describedby={describedBy}\n style={style || undefined}\n slot={slot}\n >\n {children}\n </section>\n );\n}\n\nexport type PopupSurfaceInset = 'standard' | 'compact' | 'list-zero';\n\nexport interface PopupSurfaceProps {\n children: KerfUiContent;\n inset?: PopupSurfaceInset;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** Configure recurring Web Awesome dropdown-menu geometry without consumer ::part() CSS. */\nexport function PopupSurface({\n children,\n inset = 'standard',\n className = '',\n slot,\n}: PopupSurfaceProps) {\n return (\n <span\n class={`kui-popup-surface ${className}`.trim()}\n data-component=\"popup-surface\"\n data-inset={inset}\n slot={slot}\n >\n {children}\n </span>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/layout/pane/pane.tsx"],"names":[],"mappings":"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","file":"chunk-HQZG3OFL.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport type { ScrollClearance } from '../../../shared/layout/scroll-clearance.js';\nimport {\n type ScrollEdge,\n scrollEdgeAttributes,\n} from '../../../shared/layout/scroll-edge.js';\nimport type { CssColor } from '../../../shared/styles/css-values.js';\nimport { ensureSunkenTexture } from '../../../shared/styles/sunken-texture.js';\nimport {\n joinStyles,\n type SurfaceTint,\n surfaceTintAttributes,\n} from '../../../shared/styles/surface-tint.js';\n\n/**\n * Logical pane sides: where a {@link Pane} can show a separator and where it can\n * compensate for a device safe-area inset.\n */\nexport type PaneSeparatorSide =\n 'block-start' | 'block-end' | 'inline-start' | 'inline-end';\n\n/** Semantic root elements supported by {@link Pane}. */\nexport type PaneElement = 'article' | 'aside' | 'div' | 'main' | 'section';\n\n/** Semantic elements supported by the scrolling content slot. */\nexport type PaneContentElement = 'div' | 'main' | 'nav' | 'section';\n\nconst paneProtectedAttributes = new Set([\n 'data-component',\n 'data-chrome-placement',\n 'data-compact-header',\n 'data-compact-footer',\n 'data-compact-header-open',\n 'data-compact-footer-open',\n 'data-chrome-dividers',\n 'data-appearance',\n 'data-background',\n 'data-kui-tint',\n 'data-kui-tint-accent',\n 'data-deep-inset',\n 'data-outlined',\n 'data-scroll-clearance',\n 'data-header-presentation',\n 'data-header-material',\n 'data-scroll-edge',\n 'data-scroll-edge-distance',\n 'data-header-overlay',\n 'data-separator-block-start',\n 'data-separator-block-end',\n 'data-separator-inline-start',\n 'data-separator-inline-end',\n 'data-safe-area-block-start',\n 'data-safe-area-block-end',\n 'data-safe-area-inline-start',\n 'data-safe-area-inline-end',\n]);\n\nconst allPaneSides: readonly PaneSeparatorSide[] = [\n 'block-start',\n 'block-end',\n 'inline-start',\n 'inline-end',\n];\n\ntype PaneRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-separator-block-start'?: never;\n 'data-separator-block-end'?: never;\n 'data-separator-inline-start'?: never;\n 'data-separator-inline-end'?: never;\n 'data-safe-area-block-start'?: never;\n 'data-safe-area-block-end'?: never;\n 'data-safe-area-inline-start'?: never;\n 'data-safe-area-inline-end'?: never;\n 'data-chrome-placement'?: never;\n 'data-chrome-dividers'?: never;\n 'data-appearance'?: never;\n 'data-background'?: never;\n 'data-kui-tint'?: never;\n 'data-kui-tint-accent'?: never;\n 'data-deep-inset'?: never;\n 'data-outlined'?: never;\n 'data-scroll-clearance'?: never;\n 'data-header-presentation'?: never;\n 'data-header-material'?: never;\n 'data-scroll-edge'?: never;\n 'data-scroll-edge-distance'?: never;\n 'data-header-overlay'?: never;\n 'data-compact-header'?: never;\n 'data-compact-footer'?: never;\n 'data-compact-header-open'?: never;\n 'data-compact-footer-open'?: never;\n }\n>;\n\n/** How a Pane's header and footer relate to its scrolling content. */\nexport type PaneChromePlacement = 'fixed' | 'auto';\n\n/**\n * How a header or footer behaves when the pane's container presents\n * compactly (a `NavStack` view, a `TabNavigator` scene, a full-screen dialog,\n * or a compact `Workbench`): `fixed` stays docked and shrinks the content\n * area; `scroll` sits inline with the content (a footer settles at the end\n * and scrolls past when the content is longer); `overlay` lies over the\n * content on the chrome material, shown only while the app opens it.\n */\nexport type PaneCompactChrome = 'fixed' | 'scroll' | 'overlay';\n\n/** The compact chrome policy for a Pane's header and footer. */\nexport interface PaneCompactChromePolicy {\n header?: PaneCompactChrome;\n footer?: PaneCompactChrome;\n}\n\n/**\n * When a Pane draws the divider between its pinned header or footer and its\n * scrolling content: `scroll` while content is scrolled away beneath that\n * chrome, as `wireScrollDividers` reports; `always`; or `none`.\n */\nexport type PaneChromeDividers = 'scroll' | 'always' | 'none';\n\n/**\n * How a Pane's header relates to its scrolling content: `docked` in its own\n * row above the content, or `overlay` laid over the content's top edge on the\n * translucent chrome material, so content scrolls visibly beneath it.\n * `clear` lays it over\n * the same edge fully transparent, for chrome over imagery: legibility comes\n * from glass control groups or a scrim, and with `scrollEdge=\"material\"` the\n * chrome material fades in once content scrolls beneath it.\n */\nexport type PaneHeaderPresentation = 'docked' | 'overlay' | 'clear';\n\n/** Background treatment of the Pane's scrolling work surface. */\nexport type PaneAppearance = 'default' | 'sunken';\n\nexport interface PaneProps {\n /** Optional fixed chrome above the scrolling content, arranged vertically. */\n header?: KerfUiContent;\n /** The pane's primary vertical, scrolling content stack. */\n children?: KerfUiContent;\n /** Optional fixed chrome below the scrolling content. */\n footer?: KerfUiContent;\n /**\n * Whether the header and footer stay pinned around the scrolling content.\n * `fixed` (default) always pins them. `auto` pins them while the pane is\n * tall enough, and below 480px of height (30rem, so it scales with the text\n * size) lets the whole pane scroll as one column, so tall chrome can never\n * squeeze the content to nothing.\n */\n chromePlacement?: PaneChromePlacement;\n /**\n * The divider under the header and over the footer, where they meet the\n * scrolling content. Omitted defaults to `scroll` for a plain pane and\n * `always` for `appearance=\"sunken\"`. `scroll` shows the header's divider only\n * while the content is scrolled down, and the footer's only while more\n * content lies below — never when the content fits — once\n * `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above\n * the pane; unwired, neither shows. `always` shows both; `none` neither.\n * The line is drawn inside the chrome, so no state moves the content.\n */\n chromeDividers?: PaneChromeDividers;\n /**\n * `docked` (default) gives the header its own row above the scrolling\n * content. `overlay` lays the header over the content's top edge on the\n * translucent chrome material (`--kui-chrome-material`, opaque under\n * `prefers-reduced-transparency`, forced colors, or without\n * `backdrop-filter`), so content scrolls visibly beneath it. Once\n * `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is wired above\n * the pane it measures the header and publishes its height as the\n * `--kui-scroll-clearance-block-start` context, which the content adds to\n * its block-start padding and `scroll-padding` without any\n * `scrollClearance` prop, so the first item, and anything focused or\n * scrolled into view, rests clear of the header. Until then, and with\n * `chromePlacement=\"auto\"`, the header stays docked. Keep overlay header\n * text in the normal text color: quiet text can fall below AA over the\n * content passing beneath it.\n */\n /**\n * What the header and footer do when the pane's container presents\n * compactly (default `fixed`); roomy containers ignore it. The container\n * interprets it, so set it on panes inside a `NavStack`, `TabNavigator`,\n * full-screen dialog, or `Workbench`.\n */\n compactChrome?: PaneCompactChromePolicy;\n /**\n * Which `overlay` compact chrome is showing. The app owns it and flips it\n * from a control the person can reach while the chrome is hidden.\n */\n compactChromeOpen?: { header?: boolean; footer?: boolean };\n headerPresentation?: PaneHeaderPresentation;\n /**\n * With `headerPresentation=\"clear\"`, `material` fades the chrome material\n * in behind the header once content scrolls beneath it (default `none`).\n */\n scrollEdge?: ScrollEdge;\n /**\n * The scroll distance, in CSS pixels, over which the scroll edge fades in\n * (default 60).\n */\n scrollEdgeDistance?: number;\n /** Paint the scrolling work surface with the shared lowered-surface color. */\n appearance?: PaneAppearance;\n /**\n * Paint the whole pane, header and footer included, in an app-chosen color\n * (`uiColor('surface-raised')`, `fillColor('#1f2a44')`, or `colorVar(…)`\n * from `@kerfjs/ui/css-values`). It replaces the appearance's fill: a sunken\n * pane drops its lowered color and grain. Omitted, the pane keeps its\n * default (transparent, or the sunken surface). Forced colors paint\n * `Canvas`. Keep text at AA over the color; a dark color needs a matching\n * tint or dark tones for its content.\n */\n background?: CssColor;\n /**\n * A scoped tint: `{ color, scheme }`, the app's color and the scheme it\n * belongs to. The pane paints the tinted surface (unless `background` is\n * set) and its whole subtree, chrome material and quiet fills included,\n * re-derives its surface and text tokens from the color with lightness\n * clamped to keep text at WCAG AA. Without relative color syntax, or under\n * `prefers-contrast: more`, the scope keeps the plain palette in the\n * declared scheme.\n */\n tint?: SurfaceTint;\n /**\n * Clear chrome that lies over the scrolling content's block-start and/or\n * block-end edge, such as a `DialogSurface` floating footer over a filling\n * Pane. The content scroller adds the inherited\n * `--kui-scroll-clearance-block-*` context that chrome publishes to its block\n * padding and `scroll-padding`, so content scrolls visibly beneath the chrome\n * while its first and last items (and anything focused or scrolled into\n * view) can still rest clear of it. Defaults to none.\n */\n scrollClearance?: ScrollClearance;\n /** Add 8px to every side of scrolling content (default: false). */\n deepInset?: boolean;\n /** Opt into keyboard (`0`) or programmatic (`-1`) focus on the Pane root. */\n tabIndex?: 0 | -1;\n /** Keep the standard focus outline visible, such as for a drop target. */\n outlined?: boolean;\n /** Root semantics. Defaults to `div`. */\n element?: PaneElement;\n /** Scrolling content semantics. Defaults to `div`. */\n contentElement?: PaneContentElement;\n /** Independent logical-edge separator lines. Defaults to none. */\n separators?: readonly PaneSeparatorSide[];\n /**\n * Sides on which the pane may compensate for a device safe-area inset.\n * Defaults to every side: the pane pads its slots for each side that still\n * reaches an unsafe screen edge, as its surrounding layout reports, while its\n * background and separators paint through. List only the sides an app-owned\n * layout places at a screen edge, or pass `[]` to opt out.\n */\n safeAreaEdges?: readonly PaneSeparatorSide[];\n id?: string;\n /** Accessible name for a landmark root such as `aside` or `main`. */\n label?: string;\n /** Accessible name for a landmark scrolling slot such as `nav`. */\n contentLabel?: string;\n className?: string;\n headerClassName?: string;\n contentClassName?: string;\n footerClassName?: string;\n /** Safe `data-*` metadata; Pane-owned structural attributes remain protected. */\n rootAttributes?: PaneRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A pane's configuration, apart from its content and styling hooks: the props a\n * composite that renders a `Pane` for the app (a Workbench panel or work area,\n * or a CollapsiblePanel) forwards, so the app configures that pane instead of\n * styling it. An omitted or `undefined` field keeps the composite's default.\n */\nexport type PaneConfig = Pick<\n PaneProps,\n | 'contentElement'\n | 'contentLabel'\n | 'separators'\n | 'safeAreaEdges'\n | 'chromeDividers'\n | 'compactChrome'\n | 'compactChromeOpen'\n | 'headerPresentation'\n | 'scrollEdge'\n | 'scrollEdgeDistance'\n | 'appearance'\n | 'background'\n | 'tint'\n | 'deepInset'\n | 'scrollClearance'\n | 'tabIndex'\n | 'outlined'\n>;\n\nfunction paneContent(\n element: PaneContentElement,\n children: KerfUiContent,\n className: string,\n label: string | undefined,\n) {\n const attributes = {\n class: `kui-pane__content kui-content ${className}`.trim(),\n 'aria-label': label,\n };\n if (element === 'main') return <main {...attributes}>{children}</main>;\n if (element === 'nav') return <nav {...attributes}>{children}</nav>;\n if (element === 'section')\n return <section {...attributes}>{children}</section>;\n return <div {...attributes}>{children}</div>;\n}\n\n/**\n * An unpadded application column with optional fixed header/footer slots and one\n * scrolling vertical content owner. Separator lines are independently opt-in on\n * each logical edge, so the same component works as a sidebar, main area,\n * inspector, or dialog column.\n */\nexport function Pane({\n header,\n children,\n footer,\n chromePlacement = 'fixed',\n chromeDividers,\n compactChrome = {},\n compactChromeOpen = {},\n headerPresentation = 'docked',\n scrollEdge = 'none',\n scrollEdgeDistance,\n appearance = 'default',\n background,\n tint,\n deepInset = false,\n scrollClearance,\n tabIndex,\n outlined = false,\n element = 'div',\n contentElement = 'div',\n separators = [],\n safeAreaEdges = allPaneSides,\n id,\n label,\n contentLabel,\n className = '',\n headerClassName = '',\n contentClassName = '',\n footerClassName = '',\n rootAttributes = {},\n slot,\n}: PaneProps) {\n const safeRootAttributes = filterDataAttributes(\n rootAttributes,\n paneProtectedAttributes,\n );\n const content = paneContent(\n contentElement,\n children,\n contentClassName,\n contentLabel,\n );\n const resolvedChromeDividers =\n chromeDividers ?? (appearance === 'sunken' ? 'always' : 'scroll');\n if (appearance === 'sunken' && background === undefined)\n ensureSunkenTexture();\n const tinted = surfaceTintAttributes(tint);\n const clearHeader = headerPresentation === 'clear' && header !== undefined;\n const body = (\n <>\n {header === undefined ? null : (\n <header\n class={`kui-pane__header kui-pane__toolbar ${headerClassName}`.trim()}\n >\n {header}\n </header>\n )}\n {content}\n {footer === undefined ? null : (\n <footer class={`kui-pane__footer ${footerClassName}`.trim()}>\n {footer}\n </footer>\n )}\n </>\n );\n const attributes = {\n ...safeRootAttributes,\n class: `kui-pane ${tinted.className} ${className}`\n .replace(/\\s+/g, ' ')\n .trim(),\n id,\n 'data-component': 'pane',\n 'data-appearance': appearance === 'sunken' ? 'sunken' : undefined,\n 'data-background': background === undefined ? undefined : '',\n 'data-kui-tint': tinted['data-kui-tint'],\n 'data-kui-tint-accent': tinted['data-kui-tint-accent'],\n style: joinStyles(\n background === undefined\n ? undefined\n : `--_kui-pane-background:${background}`,\n tinted.style,\n ),\n 'data-deep-inset': deepInset ? 'true' : undefined,\n 'data-outlined': outlined ? 'true' : undefined,\n 'data-scroll-clearance': scrollClearance,\n 'data-header-presentation':\n headerPresentation !== 'docked' && header !== undefined\n ? 'overlay'\n : undefined,\n 'data-header-material': clearHeader ? 'clear' : undefined,\n ...scrollEdgeAttributes(scrollEdge, scrollEdgeDistance, clearHeader),\n 'data-chrome-placement': chromePlacement === 'auto' ? 'auto' : undefined,\n 'data-compact-header':\n header !== undefined && compactChrome.header !== 'fixed'\n ? compactChrome.header\n : undefined,\n 'data-compact-footer':\n footer !== undefined && compactChrome.footer !== 'fixed'\n ? compactChrome.footer\n : undefined,\n 'data-compact-header-open':\n compactChrome.header === 'overlay' && compactChromeOpen.header\n ? ''\n : undefined,\n 'data-compact-footer-open':\n compactChrome.footer === 'overlay' && compactChromeOpen.footer\n ? ''\n : undefined,\n 'data-chrome-dividers':\n resolvedChromeDividers === 'always' || resolvedChromeDividers === 'none'\n ? resolvedChromeDividers\n : undefined,\n 'data-separator-block-start': String(separators.includes('block-start')),\n 'data-separator-block-end': String(separators.includes('block-end')),\n 'data-separator-inline-start': String(separators.includes('inline-start')),\n 'data-separator-inline-end': String(separators.includes('inline-end')),\n 'data-safe-area-block-start': String(safeAreaEdges.includes('block-start')),\n 'data-safe-area-block-end': String(safeAreaEdges.includes('block-end')),\n 'data-safe-area-inline-start': String(\n safeAreaEdges.includes('inline-start'),\n ),\n 'data-safe-area-inline-end': String(safeAreaEdges.includes('inline-end')),\n 'aria-label': label,\n tabindex: tabIndex,\n slot,\n };\n\n if (element === 'article') return <article {...attributes}>{body}</article>;\n if (element === 'aside') return <aside {...attributes}>{body}</aside>;\n if (element === 'main') return <main {...attributes}>{body}</main>;\n if (element === 'section') return <section {...attributes}>{body}</section>;\n return <div {...attributes}>{body}</div>;\n}\n\nexport type { ScrollClearance } from '../../../shared/layout/scroll-clearance.js';\nexport type { ScrollEdge } from '../../../shared/layout/scroll-edge.js';\nexport type {\n SurfaceTint,\n SurfaceTintScheme,\n} from '../../../shared/styles/surface-tint.js';\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/actions/button/button.tsx"],"names":[],"mappings":"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","file":"chunk-KPINJHIC.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport { filterDataAttributes } from '../../../shared/dom/extension-attributes.js';\nimport { Badge, type BadgeTone } from '../../feedback/badge/badge.js';\nimport { LoadingSpinner } from '../../feedback/loading-spinner/loading-spinner.js';\n\n/** The color family: `neutral` (default), `brand` for the main action, `success` for a positive one, `danger` for a destructive one. */\nexport type ButtonTone = 'neutral' | 'brand' | 'success' | 'danger';\n\n/**\n * How loudly it asks: `primary` (default) fills the button, `secondary`\n * outlines it, and `plain` shows only its text until hovered.\n */\nexport type ButtonEmphasis = 'primary' | 'secondary' | 'plain';\n\n/** `default` is the 44px control height; `compact` is 33px with smaller text. */\nexport type ButtonSize = 'default' | 'compact';\n\n/** Corner shape: the shared `rounded` control radius (default) or a full `pill`. */\nexport type ButtonShape = 'rounded' | 'pill';\n/** What a form button does: `button` (default), `submit`, or `reset`. */\nexport type ButtonType = 'button' | 'submit' | 'reset';\n\nconst BUTTON_PROTECTED = new Set([\n 'data-component',\n 'data-action',\n 'data-tone',\n 'data-emphasis',\n 'data-size',\n 'data-loading',\n 'data-icon-only',\n 'data-shape',\n 'data-fill',\n 'data-focus-ring-inset',\n]);\n\n/** Application `data-*` metadata; the Button's own markers stay protected. */\nexport type ButtonRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined>\n>;\n\n/** A Button's visible label: text or rendered content, never empty. */\nexport type ButtonLabel =\n string | Exclude<KerfUiContent, null | undefined | boolean>;\n\n/**\n * A labeled button (its label names it; `ariaLabel` only when the label is\n * not enough), or an icon-only square named by `ariaLabel`.\n */\nexport type ButtonContent =\n | {\n /** The label. */\n children: ButtonLabel;\n /** A leading icon, such as a `LucideIcon`; it is decorative. */\n icon?: KerfUiContent;\n ariaLabel?: string;\n }\n | {\n children?: undefined;\n /** The icon of an icon-only square button. */\n icon: KerfUiContent;\n /** The accessible name an icon-only button needs. */\n ariaLabel: string;\n };\n\nexport type ButtonProps = ButtonContent & ButtonOptions;\n\nexport interface ButtonOptions {\n tone?: ButtonTone;\n emphasis?: ButtonEmphasis;\n size?: ButtonSize;\n /** Corner shape (default `rounded`). */\n shape?: ButtonShape;\n /**\n * Span the full width of the parent instead of sizing to the label, as on\n * `SplitButton`. The label stays centered and ellipsizes when it no longer\n * fits.\n */\n fill?: boolean;\n /**\n * Make it a toggle: `aria-pressed` reports the state, and a pressed look is\n * drawn on top of the tone and emphasis. The application owns the state and\n * flips it in its `action` handler. A link (`href`) cannot be a toggle.\n */\n pressed?: boolean;\n /**\n * Busy: a spinner replaces the label (which still names it) and the button\n * reports `aria-busy`. Presses still reach it; the application decides\n * what a press does while it is busy.\n */\n loading?: boolean;\n disabled?: boolean;\n /** A form button's behavior (default `button`, which never submits). */\n type?: ButtonType;\n name?: string;\n value?: string;\n /** The id of the form it belongs to, when it sits outside that form. */\n form?: string;\n /** Render a link with button styling instead of a `<button>`. */\n href?: string;\n /** Where a link opens. */\n target?: '_self' | '_blank' | '_parent' | '_top';\n /** Delegated `data-action` the application handles. */\n action?: string;\n /**\n * Keep the button's focus ring inside its box when an ancestor clips\n * overflow. The inset ring is two-tone, a surface-colored line inside the\n * ring color, so it stays visible on a loud fill of the ring's own hue.\n */\n focusRingInset?: boolean;\n /**\n * A count, short text, or `true` for a text-free dot over the button's\n * top-trailing corner, such as how many items a filter hides. It stays out\n * of the accessible name unless `badgeLabel` names it.\n */\n badge?: number | string | true;\n /** Words for the badge (\"3 hidden\"), added to the button's name. */\n badgeLabel?: string;\n /** The badge's tone (default `danger`). */\n badgeTone?: BadgeTone;\n /**\n * Native hover text that says more than the name, such as \"More Actions\n * for report.pdf\". An icon-only Button already gets a help tag with its\n * `ariaLabel` (with `@kerfjs/ui/help-tags-register`); a `title` replaces\n * that tag.\n */\n title?: string;\n id?: string;\n className?: string;\n /** Safe `data-*` metadata (a `data-key`, `data-dialog-close`). */\n rootAttributes?: ButtonRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standalone action button: a native `<button>` (or a link with `href`)\n * in one of four tones and three emphases, at the 44px control height or\n * compact, with a label or as an icon-only square, rounded or pill-shaped,\n * sized to its label or filling its parent's width, and optionally a\n * `pressed` toggle. Inside a\n * `ToolbarControlGroup`, use a plain `<button>`, which the group styles; use\n * Button for a dialog footer, a form, or a standalone action beside other\n * content.\n */\nexport function Button({\n children,\n tone = 'neutral',\n emphasis = 'primary',\n size = 'default',\n shape = 'rounded',\n fill = false,\n pressed,\n icon,\n loading = false,\n disabled = false,\n type = 'button',\n name,\n value,\n form,\n href,\n target,\n action,\n focusRingInset = false,\n badge,\n badgeLabel,\n badgeTone = 'danger',\n ariaLabel,\n title,\n id,\n className = '',\n rootAttributes = {},\n slot,\n}: ButtonProps) {\n const shared = {\n ...filterDataAttributes(rootAttributes, BUTTON_PROTECTED),\n id,\n class: `kui-button ${className}`.trim(),\n 'data-component': 'button',\n 'data-tone': tone,\n 'data-emphasis': emphasis,\n 'data-size': size,\n 'data-loading': loading ? '' : undefined,\n 'data-icon-only': children === undefined ? '' : undefined,\n 'data-shape': shape === 'pill' ? 'pill' : undefined,\n 'data-fill': fill ? 'true' : undefined,\n 'data-focus-ring-inset': focusRingInset ? 'true' : undefined,\n 'data-action': action,\n 'aria-label':\n ariaLabel && badge !== undefined && badgeLabel\n ? `${ariaLabel}, ${badgeLabel}`\n : ariaLabel,\n title,\n 'aria-busy': loading ? 'true' : undefined,\n slot,\n };\n const content = (\n <>\n {icon === undefined ? null : (\n <span class=\"kui-button__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n {children === undefined ? null : (\n <span class=\"kui-button__label\">{children}</span>\n )}\n {badge === undefined || badge === '' ? null : badge === true ? (\n <Badge\n tone={badgeTone}\n size=\"dot\"\n placement=\"corner\"\n {...(ariaLabel || !badgeLabel\n ? { ariaHidden: true as const }\n : { label: badgeLabel })}\n />\n ) : (\n <Badge\n tone={badgeTone}\n appearance=\"solid\"\n size=\"compact\"\n placement=\"corner\"\n {...(ariaLabel || !badgeLabel\n ? { ariaHidden: true as const }\n : { label: badgeLabel })}\n >\n {String(badge)}\n </Badge>\n )}\n {loading ? (\n <span class=\"kui-button__spinner\" aria-hidden=\"true\">\n <LoadingSpinner />\n </span>\n ) : null}\n </>\n );\n // A disabled link has no destination and is announced as disabled.\n if (href !== undefined) {\n if (pressed !== undefined)\n throw new TypeError('A link Button cannot be a toggle (pressed).');\n return (\n <a\n {...shared}\n href={disabled ? undefined : href}\n target={disabled ? undefined : target}\n role={disabled ? 'link' : undefined}\n aria-disabled={disabled ? 'true' : undefined}\n >\n {content}\n </a>\n );\n }\n return (\n <button\n {...shared}\n type={type}\n name={name}\n value={value}\n form={form}\n disabled={disabled}\n aria-pressed={pressed === undefined ? undefined : String(pressed)}\n >\n {content}\n </button>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/surfaces/backdrop-image/backdrop-image.tsx"],"names":["className"],"mappings":"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","file":"chunk-SCDWURBO.js","sourcesContent":["import type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n filterRootAttributes,\n type StructuralRootAttributes,\n} from '../../../shared/dom/extension-attributes.js';\nimport {\n type CssColor,\n type CssLength,\n remify,\n} from '../../../shared/styles/css-values.js';\n\n/** How a single image fills the backdrop (`object-fit`). */\nexport type BackdropImageFit = 'cover' | 'contain' | 'fill';\n\n/** Which part of the image stays in view when it is cropped. */\nexport type BackdropImagePosition =\n | 'center'\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top left'\n | 'top right'\n | 'bottom left'\n | 'bottom right';\n\n/** Tile the image as a background instead of fitting one copy. */\nexport type BackdropImageRepeat = 'repeat' | 'repeat-x' | 'repeat-y';\n\n/**\n * How far the image lags the scroll: `none` scrolls with the content,\n * `subtle` lags by 35%, and a number from 0 to 1 is the lag factor (0.5\n * moves the image at half the scroll speed).\n */\nexport type BackdropImageParallax = 'none' | 'subtle' | number;\n\n/**\n * A dimming layer under `overlay` content: `bottom` darkens toward the\n * block end where a title sits, `full` dims the whole image evenly.\n */\nexport type BackdropImageScrim = 'none' | 'bottom' | 'full';\n\n/**\n * A scroll-linked progressive blur: a statically blurred copy of the image\n * fades in as the image block scrolls away. Only the copy's opacity (and the\n * optional dim layer's) animates; the blur itself is set once.\n */\nexport interface BackdropImageBlur {\n /**\n * CSS blur radius applied once to the copy. Default 24px; with\n * `blurredSrc` the default is no filter, since that asset is already soft.\n */\n radius?: CssLength;\n /**\n * An app-supplied pre-blurred or low-resolution copy of the image, used\n * instead of filtering `src`.\n */\n blurredSrc?: string;\n /**\n * Peak opacity, from 0 to 1, of a black dim layer that ramps in with the\n * blur. Default 0 (no dim layer).\n */\n dim?: number;\n}\n\nconst backdropImageProtected = new Set([\n 'data-component',\n 'data-blur',\n 'data-parallax',\n 'data-scrim',\n 'data-fade',\n 'data-repeat',\n 'data-under-chrome',\n]);\n\ntype BackdropImageRootAttributes = StructuralRootAttributes &\n Readonly<{\n 'data-component'?: never;\n 'data-blur'?: never;\n 'data-parallax'?: never;\n 'data-scrim'?: never;\n 'data-fade'?: never;\n 'data-repeat'?: never;\n 'data-under-chrome'?: never;\n }>;\n\ninterface BackdropImageCommonProps {\n /** Image URL. */\n src: string;\n /**\n * Accessible description of the image. Pass `''` for a decorative image\n * that only sets a mood; assistive technology then skips it.\n */\n alt: string;\n /** Which part of a cropped image stays in view. Default `center`. */\n position?: BackdropImagePosition;\n /** Height of the image block. Default 320px (`remify(320)`). */\n height?: CssLength;\n /** How far the image lags the scroll. Default `none`. */\n parallax?: BackdropImageParallax;\n /**\n * The color the image fades into at its block end. It also paints the\n * whole surface, so `children` below the image sit on the same color and\n * the page reads as one surface. Omit for a hard edge with no surface.\n */\n fadeTo?: CssColor;\n /**\n * Blur the image progressively as it scrolls away, by cross-fading a\n * statically blurred copy. Static (unblurred) wherever parallax is.\n */\n blur?: BackdropImageBlur;\n /**\n * Run the image up beneath the scroller's block-start inset: an overlay or\n * clear Pane header, NavStack chrome handed to a view's Pane, and the top\n * safe area, the way a media page's artwork fills the screen behind\n * transparent chrome. The visible image keeps `height` below that inset,\n * and `overlay` content stays clear of the chrome. Place the image first in\n * the Pane's content; it reads the Pane's\n * `--kui-pane-content-inset-block-start`. Default `false`.\n */\n underChrome?: boolean;\n /** Dim the image under `overlay` content. Default `none`. */\n scrim?: BackdropImageScrim;\n /** Content laid over the image's block end, such as a title and actions. */\n overlay?: KerfUiContent;\n /** Content that continues below the image on the `fadeTo` surface. */\n children?: KerfUiContent;\n id?: string;\n className?: string;\n /** Safe `data-*`, `aria-*`, and structural `role` metadata on the root. */\n rootAttributes?: BackdropImageRootAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** One fitted image, with optional responsive candidates. */\nexport interface BackdropImageSingleProps extends BackdropImageCommonProps {\n repeat?: undefined;\n /** Responsive image candidates (`srcset`). */\n srcset?: string;\n /** Rendered-size hints for `srcset` (`sizes`). */\n sizes?: string;\n /** How the image fills the block. Default `cover`. */\n fit?: BackdropImageFit;\n}\n\n/** A tiled background image at its natural size. */\nexport interface BackdropImageTiledProps extends BackdropImageCommonProps {\n repeat: BackdropImageRepeat;\n srcset?: never;\n sizes?: never;\n fit?: never;\n}\n\nexport type BackdropImageProps =\n BackdropImageSingleProps | BackdropImageTiledProps;\n\nconst SUBTLE_PARALLAX = 0.35;\n\nfunction parallaxFactor(parallax: BackdropImageParallax): number {\n if (parallax === 'none') return 0;\n if (parallax === 'subtle') return SUBTLE_PARALLAX;\n if (!Number.isFinite(parallax) || parallax < 0 || parallax > 1)\n throw new RangeError(\n 'BackdropImage parallax must be none, subtle, or a number from 0 to 1.',\n );\n return parallax;\n}\n\nfunction blurDim(dim: number | undefined): number {\n if (dim === undefined) return 0;\n if (!Number.isFinite(dim) || dim < 0 || dim > 1)\n throw new RangeError('BackdropImage blur.dim must be from 0 to 1.');\n return dim;\n}\n\nconst unsafeStyleValue = /[;{}<>\"'\\\\]|\\p{Cc}/u;\n\nfunction styleValue(value: string, prop: string): string {\n const trimmed = value.trim();\n if (!trimmed || unsafeStyleValue.test(trimmed))\n throw new TypeError(`BackdropImage ${prop} requires one CSS value.`);\n return trimmed;\n}\n\n/** A CSS `url(\"…\")` for the tiled form; quotes and backslashes are escaped. */\nfunction cssUrl(src: string): string {\n if (/\\p{Cc}/u.test(src))\n throw new TypeError(\n 'BackdropImage src must not contain control characters.',\n );\n return `url(\"${src.replace(/[\"\\\\]/g, (char) => `\\\\${char}`)}\")`;\n}\n\n/**\n * An image backdrop at the top of a scrolling Pane or NavStack view: the\n * image can lag the scroll (parallax on a scroll-driven, compositor-only\n * transform), fade through a mask into `fadeTo`, and that color keeps\n * painting under `children` so the page reads as one surface. Kerf owns the\n * static fallbacks: no parallax without scroll-driven animation support,\n * under reduced motion, under `data-kui-effects=\"static\"`, or on a\n * slow-update display, and a hard edge onto solid `fadeTo` under reduced\n * transparency.\n */\nexport function BackdropImage(props: BackdropImageProps) {\n const {\n src,\n alt,\n position = 'center',\n height,\n parallax = 'none',\n blur,\n fadeTo,\n scrim = 'none',\n underChrome = false,\n overlay,\n children,\n id,\n className = '',\n rootAttributes = {},\n slot,\n } = props;\n const factor = parallaxFactor(parallax);\n const dim = blurDim(blur?.dim);\n const blurRadius =\n blur === undefined\n ? undefined\n : (blur.radius ??\n (blur.blurredSrc === undefined ? remify(24) : undefined));\n const style = [\n height === undefined\n ? ''\n : `--_kui-backdrop-image-height:${styleValue(height, 'height')}`,\n fadeTo === undefined\n ? ''\n : `--_kui-backdrop-image-fade-to:${styleValue(fadeTo, 'fadeTo')}`,\n factor === 0 ? '' : `--_kui-backdrop-image-parallax:${String(factor)}`,\n position === 'center' ? '' : `--_kui-backdrop-image-position:${position}`,\n props.fit === undefined || props.fit === 'cover'\n ? ''\n : `--_kui-backdrop-image-fit:${props.fit}`,\n blurRadius === undefined\n ? ''\n : `--_kui-backdrop-image-blur:${styleValue(blurRadius, 'blur.radius')}`,\n dim === 0 ? '' : `--_kui-backdrop-image-dim:${String(dim)}`,\n ]\n .filter(Boolean)\n .join(';');\n const image = (className: string, source: string, copy: boolean) =>\n props.repeat === undefined ? (\n <img\n class={className}\n src={source}\n srcSet={source === src ? props.srcset : undefined}\n sizes={source === src ? props.sizes : undefined}\n alt={copy ? '' : alt}\n aria-hidden={copy ? 'true' : undefined}\n decoding=\"async\"\n />\n ) : (\n <div\n class={className}\n role={!copy && alt ? 'img' : undefined}\n aria-label={!copy && alt ? alt : undefined}\n aria-hidden={copy ? 'true' : undefined}\n style={`background-image:${cssUrl(source)};background-repeat:${props.repeat}`}\n />\n );\n const hasOverlay =\n overlay !== undefined && overlay !== null && overlay !== false;\n const hasChildren =\n children !== undefined && children !== null && children !== false;\n return (\n <div\n {...filterRootAttributes(rootAttributes, backdropImageProtected)}\n id={id}\n class={`kui-backdrop-image ${className}`.trim()}\n data-component=\"backdrop-image\"\n data-parallax={factor === 0 ? 'none' : 'scroll'}\n data-blur={\n blur === undefined\n ? undefined\n : blurRadius === undefined\n ? 'asset'\n : 'filter'\n }\n data-fade={fadeTo === undefined ? undefined : 'true'}\n data-scrim={scrim === 'none' ? undefined : scrim}\n data-repeat={props.repeat}\n data-under-chrome={underChrome ? 'true' : undefined}\n style={style || undefined}\n slot={slot}\n >\n <div class=\"kui-backdrop-image__hero\">\n <div class=\"kui-backdrop-image__backdrop\">\n <div class=\"kui-backdrop-image__layers\">\n {image('kui-backdrop-image__media', src, false)}\n {blur === undefined\n ? null\n : image(\n 'kui-backdrop-image__blurred',\n blur.blurredSrc ?? src,\n true,\n )}\n </div>\n {dim === 0 ? null : <div class=\"kui-backdrop-image__dim\" />}\n {scrim === 'none' ? null : <div class=\"kui-backdrop-image__scrim\" />}\n </div>\n {hasOverlay ? (\n <div class=\"kui-backdrop-image__overlay\">{overlay}</div>\n ) : null}\n </div>\n {hasChildren ? (\n <div class=\"kui-backdrop-image__content\">{children}</div>\n ) : null}\n </div>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/navigation/nav-stack/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-SOFPUW3O.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport type { KerfUiContent } from '../../../shared/content/semantic-content.js';\nimport {\n type ScrollEdge,\n scrollEdgeAttributes,\n} from '../../../shared/layout/scroll-edge.js';\nimport type { NavPane } from '../../../shared/panels/nav-pane.js';\nimport type { PanelBottomToolbar } from '../../../shared/panels/panel-toolbar.js';\nimport type { CssColor } from '../../../shared/styles/css-values.js';\nimport {\n joinStyles,\n type SurfaceTint,\n surfaceTintAttributes,\n} from '../../../shared/styles/surface-tint.js';\nimport { Toolbar, type ToolbarConfig } from '../../actions/toolbar/toolbar.js';\nimport { ToolbarControlGroup } from '../../actions/toolbar-control-group/toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from '../../actions/toolbar-text/toolbar-text.js';\nimport { List, type ListConfig } from '../../collections/list/list.js';\nimport { paneConfigProps } from '../../layout/pane/internal/pane-config-props.js';\nimport { Pane } from '../../layout/pane/pane.js';\nimport { LucideIcon } from '../../media/lucide-icon/lucide-icon.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 extends NavPane<\n NavStackViewToolbar,\n PanelBottomToolbar\n> {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n}\n\n/** Per-view top toolbar. The stack supplies its back control before `leading`. */\nexport interface NavStackViewToolbar extends NavStackToolbarConfig {\n title?: string;\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n}\n\n/** A view's structured bottom toolbar; it cross-fades on navigation. */\nexport type NavStackViewBottomToolbar = PanelBottomToolbar;\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 /**\n * Size of the view title's `ToolbarText`. Default `xlarge` at the root,\n * where the title is the page heading, and `large` once a back control\n * shares the bar.\n */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\n/**\n * How a {@link NavStack}'s top chrome relates to the active view: `docked`\n * above it, or `overlay` laid over its top edge on the translucent chrome\n * material, so the view's content scrolls visibly beneath it.\n * `clear` lays it over\n * the same edge fully transparent, for chrome over imagery: legibility comes\n * from glass control groups or a scrim, and with `scrollEdge=\"material\"` the\n * chrome material fades in once content scrolls beneath it.\n */\nexport type NavStackChromePresentation = 'docked' | 'overlay' | 'clear';\n\n/**\n * How a {@link NavStack}'s bottom toolbar relates to the active view:\n * `docked` below it, or `overlay` laid over its bottom edge on the\n * translucent chrome material, so the view's content scrolls visibly beneath\n * it.\n * `clear` lays it over\n * the same edge fully transparent, for chrome over imagery: legibility comes\n * from glass control groups or a scrim, and with `scrollEdge=\"material\"` the\n * chrome material fades in once content scrolls beneath\n * it, until the view scrolls to its end.\n */\nexport type NavStackBottomToolbarPresentation = 'docked' | 'overlay' | 'clear';\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Persistent last group in every view's top toolbar, supplied by a hosting panel. */\n panelToggle?: KerfUiContent;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: NavStackViewBottomToolbar;\n /**\n * Stack chrome separator. `auto` (default) draws both available edges\n * against a sunken active Pane and otherwise follows `chromeDividers`;\n * `hidden` suppresses the stack-owned edges.\n */\n separator?: 'auto' | 'hidden';\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 * A sunken active Pane still draws the separator unless\n * `separator=\"hidden\"`. A `toolbarConfig.dividerSides` edge is the Toolbar's\n * own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n /**\n * `docked` (default) gives the top chrome its own band above the active\n * view. `overlay` lays the chrome over the view's top edge on the\n * translucent chrome material (`--kui-chrome-material`, opaque under\n * `prefers-reduced-transparency`, `prefers-contrast: more`, forced colors,\n * or without `backdrop-filter`), so content scrolls visibly beneath it, as\n * an iOS navigation bar does. `wireNavStack` measures the live chrome and\n * hands its height (top safe area included) to the viewport as the\n * block-start `--kui-edge-inset-*` context, so every view clears it with no\n * prop: a plain view, a sole `Pane`'s content (or header), and a nested\n * layout all pad and `scroll-padding` by it, so the first item, and anything\n * focused or scrolled into view, rests clear of the bar. Until then, and\n * with `hideToolbar`, the chrome stays docked. An untoned `ToolbarText` in\n * the chrome lifts its title and description to AA over the content passing\n * beneath it; keep any other quiet copy in the view. With `clear`, the\n * stack's own back control sits in a glass control group\n * (`material=\"glass\"`), so it stays legible over imagery.\n */\n chromePresentation?: NavStackChromePresentation;\n /**\n * `docked` (default) gives the bottom toolbar its own band below the\n * active view. `overlay` lays it over the view's bottom edge on the\n * translucent chrome material (opaque under the same preferences as\n * `chromePresentation`), so content scrolls visibly beneath it, as under\n * an iOS toolbar. `wireNavStack` measures the live bottom toolbar (never a\n * cross-fading copy) and hands its height (bottom safe area included) to\n * the viewport as the block-end `--kui-edge-inset-*` context, so a plain\n * view, a sole `Pane`'s content (or footer), and a nested layout rest their\n * last item, and anything focused or scrolled into view, clear of it. Until\n * then, and while no bottom toolbar is shown, it stays docked. Independent\n * of `chromePresentation`, which governs only the top chrome. An untoned\n * `ToolbarText` in the toolbar lifts to AA over the content beneath it.\n */\n bottomToolbarPresentation?: NavStackBottomToolbarPresentation;\n /**\n * For `clear` chrome or bottom toolbar, `material` fades the chrome\n * material in while the active view's content lies beneath it (default\n * `none`).\n */\n scrollEdge?: ScrollEdge;\n /**\n * The scroll distance, in CSS pixels, over which the scroll edge fades in\n * (default 60).\n */\n scrollEdgeDistance?: number;\n /**\n * Paint the stack, its docked chrome and bottom toolbar, and every view in\n * an app-chosen color (a `@kerfjs/ui/css-values` color builder) instead of\n * the surface. Overlay chrome keeps the chrome material; one view's own\n * color goes in its `pane: { background }`. Forced colors paint `Canvas`.\n */\n background?: CssColor;\n /**\n * A scoped tint (`{ color, scheme }`) for the stack, its chrome, bottom toolbar, and views: its surfaces and every\n * descendant re-derive their surface and text tokens from the app's color\n * in the declared scheme, with lightness clamped to keep text at WCAG AA.\n */\n tint?: SurfaceTint;\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\nconst DEFAULT_BOTTOM_SAFE_AREA_EDGES = [\n 'block-end',\n 'inline-start',\n 'inline-end',\n] as const;\n\nfunction chromeList(content: KerfUiContent, config?: ListConfig) {\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 * 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 `toolbar` fills the zones,\n * and `toolbarConfig` supplies defaults. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n panelToggle,\n hideToolbar = false,\n bottomToolbar,\n separator = 'auto',\n chromeDividers = 'scroll',\n chromePresentation = 'docked',\n bottomToolbarPresentation = 'docked',\n scrollEdge = 'none',\n scrollEdgeDistance,\n background,\n tint,\n className = '',\n slot,\n}: NavStackProps) {\n const tinted = surfaceTintAttributes(tint);\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const topToolbar = top?.toolbar;\n const bottom = top?.bottomToolbar ?? bottomToolbar;\n const canPop = views.length > 1;\n const topDensity = topToolbar?.density ?? toolbarConfig.density;\n // With a back control, the title centers on the bar (iOS-style) unless the\n // view owns the center zone; at the root it leads and fills, left-aligned.\n const centerTitle = canPop && topToolbar?.center === undefined;\n const title = (\n <ToolbarText\n text={topToolbar?.title ?? ''}\n size={\n topToolbar?.titleSize ??\n toolbarConfig.titleSize ??\n (canPop ? 'large' : 'xlarge')\n }\n headingLevel={topToolbar?.headingLevel ?? toolbarConfig.headingLevel}\n fill={!centerTitle}\n />\n );\n return (\n <section\n class={`kui-nav-stack ${tinted.className} ${className}`\n .replace(/\\s+/g, ' ')\n .trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-separator={separator}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n data-chrome-presentation={\n chromePresentation !== 'docked' && !hideToolbar ? 'overlay' : undefined\n }\n data-chrome-material={\n chromePresentation === 'clear' && !hideToolbar ? 'clear' : undefined\n }\n data-bottom-toolbar-presentation={\n bottomToolbarPresentation !== 'docked' ? 'overlay' : undefined\n }\n data-bottom-toolbar-material={\n bottomToolbarPresentation === 'clear' ? 'clear' : undefined\n }\n {...scrollEdgeAttributes(\n scrollEdge,\n scrollEdgeDistance,\n (chromePresentation === 'clear' && !hideToolbar) ||\n bottomToolbarPresentation === 'clear',\n )}\n data-background={background === undefined ? undefined : ''}\n data-kui-tint={tinted['data-kui-tint']}\n data-kui-tint-accent={tinted['data-kui-tint-accent']}\n style={joinStyles(\n background === undefined\n ? undefined\n : `--_kui-nav-stack-background:${background}`,\n tinted.style,\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={topToolbar?.label ?? toolbarConfig.label}\n density={topDensity}\n dividerSides={\n topToolbar?.dividerSides ?? toolbarConfig.dividerSides\n }\n centerAlign={\n centerTitle\n ? 'balanced'\n : (topToolbar?.centerAlign ?? toolbarConfig.centerAlign)\n }\n responsive={topToolbar?.responsive ?? toolbarConfig.responsive}\n responsiveAt={\n topToolbar?.responsiveAt ?? toolbarConfig.responsiveAt\n }\n safeAreaEdges={\n topToolbar?.safeAreaEdges ??\n toolbarConfig.safeAreaEdges ??\n DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n content={backText ? 'mixed' : 'icon'}\n size={topDensity === 'compact' ? 'compact' : 'default'}\n material={\n chromePresentation === 'clear' ? 'glass' : undefined\n }\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 {topToolbar?.leading}\n {centerTitle ? null : title}\n </>\n }\n center={centerTitle ? title : topToolbar?.center}\n trailing={\n <>\n {topToolbar?.trailing}\n {panelToggle}\n </>\n }\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.pane ||\n view.header !== undefined ||\n view.footer !== undefined ? (\n <Pane\n {...paneConfigProps(view.pane)}\n header={\n view.header === undefined ? undefined : (\n <div data-nav-stack-header>\n {chromeList(view.header, view.headerList)}\n </div>\n )\n }\n footer={\n view.footer === undefined ? undefined : (\n <div data-nav-stack-footer>\n {chromeList(view.footer, view.footerList)}\n </div>\n )\n }\n >\n {view.content}\n </Pane>\n ) : (\n view.content\n )}\n </article>\n ))}\n </div>\n {bottom && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n <Toolbar\n position=\"footer\"\n label={bottom.label}\n density={bottom.density}\n dividerSides={bottom.dividerSides}\n centerAlign={bottom.centerAlign}\n responsive={bottom.responsive}\n responsiveAt={bottom.responsiveAt}\n safeAreaEdges={\n bottom.safeAreaEdges ?? DEFAULT_BOTTOM_SAFE_AREA_EDGES\n }\n leading={bottom.leading}\n center={bottom.center}\n trailing={bottom.trailing}\n />\n </footer>\n )}\n </section>\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shared/layout/scroll-edge.ts","../src/shared/styles/surface-tint.ts"],"names":[],"mappings":";AAaO,SAAS,oBAAA,CACd,IAAA,EACA,QAAA,EACA,OAAA,EAIA;AACA,EAAA,IAAI,CAAC,WAAW,IAAA,KAAS,MAAA;AACvB,IAAA,OAAO;AAAA,MACL,kBAAA,EAAoB,MAAA;AAAA,MACpB,2BAAA,EAA6B;AAAA,KAC/B;AACF,EAAA,OAAO;AAAA,IACL,kBAAA,EAAoB,IAAA;AAAA,IACpB,2BAAA,EACE,aAAa,MAAA,IAAa,EAAE,WAAW,CAAA,CAAA,GAAK,MAAA,GAAY,OAAO,QAAQ;AAAA,GAC3E;AACF;;;ACLO,SAAS,sBAAsB,IAAA,EAOpC;AACA,EAAA,IAAI,IAAA,KAAS,MAAA;AACX,IAAA,OAAO;AAAA,MACL,eAAA,EAAiB,MAAA;AAAA,MACjB,sBAAA,EAAwB,MAAA;AAAA,MACxB,SAAA,EAAW,EAAA;AAAA,MACX,KAAA,EAAO;AAAA,KACT;AACF,EAAA,OAAO;AAAA,IACL,iBAAiB,IAAA,CAAK,MAAA;AAAA,IACtB,sBAAA,EAAwB,IAAA,CAAK,MAAA,KAAW,MAAA,GAAY,MAAA,GAAY,EAAA;AAAA,IAChE,SAAA,EAAW,CAAA,GAAA,EAAM,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,IAC5B,KAAA,EACE,IAAA,CAAK,MAAA,KAAW,MAAA,GACZ,CAAA,kBAAA,EAAqB,IAAA,CAAK,KAAK,CAAA,CAAA,GAC/B,CAAA,kBAAA,EAAqB,IAAA,CAAK,KAAK,CAAA,oBAAA,EAAuB,KAAK,MAAM,CAAA;AAAA,GACzE;AACF;AAGO,SAAS,cACX,YAAA,EACiB;AACpB,EAAA,MAAM,UAAU,YAAA,CAAa,MAAA,CAAO,CAAC,KAAA,KAAU,UAAU,MAAS,CAAA;AAClE,EAAA,OAAO,QAAQ,MAAA,KAAW,CAAA,GAAI,MAAA,GAAY,OAAA,CAAQ,KAAK,GAAG,CAAA;AAC5D","file":"chunk-SQ5DH66U.js","sourcesContent":["/**\n * What clear (fully transparent) chrome fades in as content scrolls beneath\n * it: `none` stays clear; `material` fades in the translucent chrome\n * material; `surface` fades in the opaque surface. The fade tracks the scroll\n * over `scrollEdgeDistance` (opacity only), from the scroll state\n * `wireScrollDividers` reports; unwired, the chrome stays clear.\n */\nexport type ScrollEdge = 'none' | 'material' | 'surface';\n\n/** The default scroll distance, in CSS pixels, a scroll edge fades in over. */\nexport const DEFAULT_SCROLL_EDGE_DISTANCE = 60;\n\n/** The root attributes a component with a scroll edge renders. */\nexport function scrollEdgeAttributes(\n edge: ScrollEdge,\n distance: number | undefined,\n enabled: boolean,\n): {\n 'data-scroll-edge': 'material' | 'surface' | undefined;\n 'data-scroll-edge-distance': string | undefined;\n} {\n if (!enabled || edge === 'none')\n return {\n 'data-scroll-edge': undefined,\n 'data-scroll-edge-distance': undefined,\n };\n return {\n 'data-scroll-edge': edge,\n 'data-scroll-edge-distance':\n distance === undefined || !(distance > 0) ? undefined : String(distance),\n };\n}\n","import type { CssColor } from './css-values.js';\n\n/** The color scheme an app declares for a {@link SurfaceTint}'s color. */\nexport type SurfaceTintScheme = 'light' | 'dark';\n\n/**\n * A scoped tint for a layout surface: the app's color (usually sampled from\n * artwork it already knows) and the scheme that color belongs to. Kerf does no\n * color detection; `scheme` says whether the color reads as a light or a dark\n * surface. Inside the scope the surface, raised surface, text, quiet text, and\n * everything built on them (quiet fills, separators' backdrop, the chrome\n * material) re-derive from the color, with lightness clamped so text keeps\n * WCAG AA over any color.\n */\nexport interface SurfaceTint {\n color: CssColor;\n scheme: SurfaceTintScheme;\n /**\n * An optional accent (usually the artwork's most vivid color). The scope's\n * brand ramp re-derives from it: loud fills and their text, brand text and\n * links, text on brand fills, and the focus ring, each clamped to keep AA.\n */\n accent?: CssColor;\n}\n\n/** The root attributes a tinted surface renders. */\nexport function surfaceTintAttributes(tint: SurfaceTint | undefined): {\n 'data-kui-tint': SurfaceTintScheme | undefined;\n 'data-kui-tint-accent': '' | undefined;\n /** The Web Awesome scheme class, so its theme re-derives in the scope. */\n className: string;\n /** The inline declaration carrying the color, or `undefined`. */\n style: string | undefined;\n} {\n if (tint === undefined)\n return {\n 'data-kui-tint': undefined,\n 'data-kui-tint-accent': undefined,\n className: '',\n style: undefined,\n };\n return {\n 'data-kui-tint': tint.scheme,\n 'data-kui-tint-accent': tint.accent === undefined ? undefined : '',\n className: `wa-${tint.scheme}`,\n style:\n tint.accent === undefined\n ? `--_kui-tint-color:${tint.color}`\n : `--_kui-tint-color:${tint.color};--_kui-tint-accent:${tint.accent}`,\n };\n}\n\n/** Join inline declarations, omitting absent ones. */\nexport function joinStyles(\n ...declarations: (string | undefined)[]\n): string | undefined {\n const present = declarations.filter((value) => value !== undefined);\n return present.length === 0 ? undefined : present.join(';');\n}\n"]}