@kerfjs/ui 5.0.0-beta.62 → 5.0.0-beta.64

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 (169) hide show
  1. package/README.md +4 -0
  2. package/ai/component-catalog-extension.schema.json +13 -0
  3. package/ai/component-catalog.json +13 -2
  4. package/ai/component-composition.json +15 -2
  5. package/ai/components/list-item.md +1 -1
  6. package/ai/components/workbench.md +4 -2
  7. package/ai/public-api-signatures-v1.md +151 -44
  8. package/ai/skill.md +9 -5
  9. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  10. package/analyzer/index.mjs +3 -2
  11. package/catalog-projection-cli.mjs +96 -0
  12. package/catalog-projection.d.mts +55 -0
  13. package/catalog-projection.mjs +62 -0
  14. package/dist/browser/catalog.js +1 -1
  15. package/dist/browser/collapsible-panel.js +2 -0
  16. package/dist/browser/nav-stack.js +1 -0
  17. package/dist/browser/split-view.js +1 -0
  18. package/dist/browser/toolbar-control-group.js +1 -0
  19. package/dist/browser/workbench.js +1 -0
  20. package/dist/catalog-resources.d.ts +1 -1
  21. package/dist/catalog.d.ts +2 -2
  22. package/dist/catalog.js +11 -10
  23. package/dist/catalog.js.map +1 -1
  24. package/dist/chip.d.ts +9 -3
  25. package/dist/chip.js +1 -1
  26. package/dist/{chunk-UCKKT6KO.js → chunk-2EKHENQK.js} +7 -1
  27. package/dist/chunk-2EKHENQK.js.map +1 -0
  28. package/dist/{chunk-OD2VXAPL.js → chunk-3BYFWTP3.js} +4 -3
  29. package/dist/chunk-3BYFWTP3.js.map +1 -0
  30. package/dist/{chunk-5Q3N6EV7.js → chunk-5IJ6UGNZ.js} +3 -3
  31. package/dist/{chunk-5Q3N6EV7.js.map → chunk-5IJ6UGNZ.js.map} +1 -1
  32. package/dist/{chunk-KROD7KZK.js → chunk-AUVG54KC.js} +2 -2
  33. package/dist/{chunk-KROD7KZK.js.map → chunk-AUVG54KC.js.map} +1 -1
  34. package/dist/{chunk-AUKT3KMG.js → chunk-CQHN45XR.js} +17 -2
  35. package/dist/chunk-CQHN45XR.js.map +1 -0
  36. package/dist/{chunk-SWVW56CV.js → chunk-EN4LDR5Y.js} +2 -2
  37. package/dist/{chunk-SWVW56CV.js.map → chunk-EN4LDR5Y.js.map} +1 -1
  38. package/dist/{chunk-4MG3KXJM.js → chunk-F7OCOBTG.js} +2 -2
  39. package/dist/{chunk-4MG3KXJM.js.map → chunk-F7OCOBTG.js.map} +1 -1
  40. package/dist/{chunk-KYDDCJXU.js → chunk-HXCMWANP.js} +4 -4
  41. package/dist/{chunk-KYDDCJXU.js.map → chunk-HXCMWANP.js.map} +1 -1
  42. package/dist/{chunk-ENGVYQPG.js → chunk-IA4D5XNT.js} +60 -10
  43. package/dist/chunk-IA4D5XNT.js.map +1 -0
  44. package/dist/{chunk-F4QMLOXJ.js → chunk-IAOAZUOO.js} +2 -2
  45. package/dist/{chunk-F4QMLOXJ.js.map → chunk-IAOAZUOO.js.map} +1 -1
  46. package/dist/{chunk-VCBTX62E.js → chunk-J3KGJ6P6.js} +2 -2
  47. package/dist/chunk-J3KGJ6P6.js.map +1 -0
  48. package/dist/{chunk-X6ADHJNI.js → chunk-KFYANKJI.js} +25 -6
  49. package/dist/chunk-KFYANKJI.js.map +1 -0
  50. package/dist/{chunk-A3CKOW2R.js → chunk-M5H2RMCH.js} +165 -26
  51. package/dist/chunk-M5H2RMCH.js.map +1 -0
  52. package/dist/chunk-MOSIE4Z2.js +51 -0
  53. package/dist/chunk-MOSIE4Z2.js.map +1 -0
  54. package/dist/{chunk-RRB26JRJ.js → chunk-NSVLUDUW.js} +19 -4
  55. package/dist/chunk-NSVLUDUW.js.map +1 -0
  56. package/dist/{chunk-7JUBXOIV.js → chunk-NXWE5S57.js} +25 -6
  57. package/dist/chunk-NXWE5S57.js.map +1 -0
  58. package/dist/chunk-RGS4WX2M.js +44 -0
  59. package/dist/chunk-RGS4WX2M.js.map +1 -0
  60. package/dist/chunk-SH6F3CCG.js +80 -0
  61. package/dist/chunk-SH6F3CCG.js.map +1 -0
  62. package/dist/{chunk-EAC4CDY7.js → chunk-SMZGAPCU.js} +15 -2
  63. package/dist/chunk-SMZGAPCU.js.map +1 -0
  64. package/dist/{chunk-NNMLEDMD.js → chunk-TJK44RQC.js} +64 -11
  65. package/dist/chunk-TJK44RQC.js.map +1 -0
  66. package/dist/{chunk-6ZXOQEAN.js → chunk-WF75U3V4.js} +7 -1
  67. package/dist/chunk-WF75U3V4.js.map +1 -0
  68. package/dist/collapsible-panel.d.ts +18 -7
  69. package/dist/collapsible-panel.js +19 -3
  70. package/dist/collapsible-panel.js.map +1 -1
  71. package/dist/content-item.d.ts +40 -5
  72. package/dist/content-item.js +1 -1
  73. package/dist/disclosure-arrow.js +2 -1
  74. package/dist/grid.d.ts +5 -1
  75. package/dist/grid.js +1 -1
  76. package/dist/index.d.ts +3 -3
  77. package/dist/index.js +20 -20
  78. package/dist/list-action-row.js +1 -1
  79. package/dist/list-header.js +1 -1
  80. package/dist/list-item.js +1 -1
  81. package/dist/lucide-icon.d.ts +5 -2
  82. package/dist/lucide-icon.js +2 -1
  83. package/dist/nav-stack.js +2 -1
  84. package/dist/pane.d.ts +2 -1
  85. package/dist/pane.js +1 -1
  86. package/dist/{panel-toolbar-DqwtBxQL.d.ts → panel-toolbar-DDKh4uKd.d.ts} +11 -2
  87. package/dist/popup-menu-register.js +216 -3
  88. package/dist/popup-menu-register.js.map +1 -1
  89. package/dist/popup-menu.d.ts +4 -3
  90. package/dist/popup-menu.js +1 -1
  91. package/dist/select.js +1 -1
  92. package/dist/split-view.js +2 -1
  93. package/dist/split-view.js.map +1 -1
  94. package/dist/styles/catalog/components/catalog-example.css +4 -0
  95. package/dist/styles/chip.css +14 -0
  96. package/dist/styles/content-item.css +45 -0
  97. package/dist/styles/grid.css +7 -0
  98. package/dist/styles/list-action-row.css +4 -3
  99. package/dist/styles/list-header.css +4 -3
  100. package/dist/styles/list-item.css +21 -11
  101. package/dist/styles/lucide-icon.css +5 -0
  102. package/dist/styles/pane.css +3 -2
  103. package/dist/styles/popup-menu.css +24 -10
  104. package/dist/styles/segmented-control.css +3 -0
  105. package/dist/styles/select.css +11 -0
  106. package/dist/styles/sunken-panel.css +7 -0
  107. package/dist/styles/text.css +29 -0
  108. package/dist/styles/token-search-field.css +51 -11
  109. package/dist/styles/toolbar-control-group.css +49 -0
  110. package/dist/styles/workbench.css +130 -2
  111. package/dist/sunken-panel.d.ts +6 -1
  112. package/dist/sunken-panel.js +1 -1
  113. package/dist/text.d.ts +14 -3
  114. package/dist/text.js +1 -1
  115. package/dist/{token-search-field-DvgFLhLL.d.ts → token-search-field-Xk8jiw8Y.d.ts} +18 -4
  116. package/dist/token-search-field.d.ts +1 -1
  117. package/dist/token-search-field.js +2 -1
  118. package/dist/token-search-model.d.ts +1 -1
  119. package/dist/toolbar-control-group.d.ts +5 -1
  120. package/dist/toolbar-control-group.js +2 -1
  121. package/dist/toolbar.d.ts +5 -2
  122. package/dist/toolbar.js +1 -1
  123. package/dist/wire-catalog.js +1 -1
  124. package/dist/wire-content-items.d.ts +9 -0
  125. package/dist/wire-content-items.js +66 -0
  126. package/dist/wire-content-items.js.map +1 -0
  127. package/dist/wire-token-search-fields.d.ts +1 -1
  128. package/dist/wire-token-search-fields.js +2 -1
  129. package/dist/wire-workbench.d.ts +7 -0
  130. package/dist/wire-workbench.js +1 -1
  131. package/dist/workbench.d.ts +24 -8
  132. package/dist/workbench.js +2 -1
  133. package/docs/accessibility.md +30 -6
  134. package/docs/catalog.md +42 -2
  135. package/docs/collapsible-panel.md +8 -1
  136. package/docs/component-contract.md +43 -5
  137. package/docs/component-selection.md +46 -8
  138. package/docs/design/templates/toolbar/title-and-actions-dark.svg +1 -1
  139. package/docs/design/templates/toolbar/title-and-actions.svg +1 -1
  140. package/docs/design/templates/toolbar-dark.svg +1 -1
  141. package/docs/design/templates/toolbar.svg +1 -1
  142. package/docs/examples/component-catalog-extension.json +6 -0
  143. package/docs/layout.md +56 -9
  144. package/docs/sunken-panel.md +22 -0
  145. package/docs/surface-scaffold.md +6 -3
  146. package/docs/ui-analyzer.md +4 -0
  147. package/docs/ux-demo.md +1 -0
  148. package/docs/workbench.md +42 -4
  149. package/llms.txt +9 -5
  150. package/package.json +16 -2
  151. package/scripts/component-catalog-extension-validation.mjs +28 -0
  152. package/dist/chunk-4R777DUZ.js +0 -34
  153. package/dist/chunk-4R777DUZ.js.map +0 -1
  154. package/dist/chunk-6ZXOQEAN.js.map +0 -1
  155. package/dist/chunk-7JUBXOIV.js.map +0 -1
  156. package/dist/chunk-A3CKOW2R.js.map +0 -1
  157. package/dist/chunk-AUKT3KMG.js.map +0 -1
  158. package/dist/chunk-EAC4CDY7.js.map +0 -1
  159. package/dist/chunk-ENGVYQPG.js.map +0 -1
  160. package/dist/chunk-MA73TA6D.js +0 -42
  161. package/dist/chunk-MA73TA6D.js.map +0 -1
  162. package/dist/chunk-N2DRU35S.js +0 -45
  163. package/dist/chunk-N2DRU35S.js.map +0 -1
  164. package/dist/chunk-NNMLEDMD.js.map +0 -1
  165. package/dist/chunk-OD2VXAPL.js.map +0 -1
  166. package/dist/chunk-RRB26JRJ.js.map +0 -1
  167. package/dist/chunk-UCKKT6KO.js.map +0 -1
  168. package/dist/chunk-VCBTX62E.js.map +0 -1
  169. package/dist/chunk-X6ADHJNI.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/token-search-field.tsx"],"names":[],"mappings":"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","file":"chunk-NSVLUDUW.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\nimport { Search, X } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport type { TokenSearchModel } from './token-search-model.js';\n\nexport interface TokenSearchToken {\n value: string;\n label: string;\n offset?: number;\n accessibleLabel?: string;\n}\n\nexport interface TokenSearchTrailingAction {\n icon: SafeHtml;\n label: string;\n action: string;\n id?: string;\n}\n\nexport type TokenSearchEditorAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-key'?: never;\n 'data-morph-skip'?: never;\n 'data-token-search-editor'?: never;\n 'data-token-count'?: never;\n 'data-placeholder'?: never;\n }\n>;\n\ninterface TokenSearchFieldBaseProps {\n id: string;\n label: string;\n query?: string;\n tokens?: readonly TokenSearchToken[];\n /** Opt-in grammar, suggestion, and evaluation state. Overrides `query` and `tokens`. */\n model?: TokenSearchModel;\n /**\n * Editor identity for a programmatic text replacement. The editor's text is\n * DOM-owned between token changes, so a new `query` with the same tokens\n * does not re-render it (that would reset the caret on every keystroke).\n * Change `revision` when the app replaces the text itself — reseeding a\n * persistent dialog's field on reopen, applying a saved search — and the\n * editor is rebuilt from `query` and `tokens`.\n */\n revision?: string | number;\n placeholder?: string;\n tokenPlaceholder?: string;\n disabled?: boolean;\n autofocus?: boolean;\n /** Let an expanded collapsible field consume the available inline width. */\n fill?: boolean;\n leading?: KerfUiContent;\n /** Standalone field chrome or the inset visual layer of a configured toolbar group. */\n presentation?: 'standalone' | 'toolbar-group';\n editAction?: string;\n removeAction?: string;\n clearAction?: string;\n clearLabel?: string;\n /** Icon for the clear button. Default: the Lucide `x` glyph token chips also use. */\n clearIcon?: SafeHtml;\n className?: string;\n editorAttributes?: TokenSearchEditorAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ntype TokenSearchTrailingProps =\n | { trailing?: KerfUiContent; trailingAction?: never }\n | { trailing?: never; trailingAction: TokenSearchTrailingAction };\n\ntype TokenSearchCollapsibleProps =\n | {\n /** Allow an empty field to render as one iconic action. */\n collapsible: true;\n /** Keep an empty collapsible field open while the application owns focus. */\n expanded?: boolean;\n expandAction?: string;\n expandLabel?: string;\n }\n | {\n collapsible?: false;\n expanded?: never;\n expandAction?: never;\n expandLabel?: never;\n };\n\nexport type TokenSearchFieldProps = TokenSearchFieldBaseProps &\n TokenSearchCollapsibleProps &\n TokenSearchTrailingProps;\n\nexport interface TokenSearchFieldValue {\n query: string;\n tokens: TokenSearchToken[];\n}\n\ntype TokenSearchPart =\n { kind: 'text'; value: string } | { kind: 'token'; token: TokenSearchToken };\n\nfunction orderedParts(\n query: string,\n tokens: readonly TokenSearchToken[],\n): TokenSearchPart[] {\n const ordered = tokens\n .map((token, index) => ({\n token,\n index,\n offset: Math.max(0, Math.min(query.length, token.offset ?? query.length)),\n }))\n .sort(\n (left, right) => left.offset - right.offset || left.index - right.index,\n );\n const parts: TokenSearchPart[] = [];\n let cursor = 0;\n for (const { token, offset } of ordered) {\n parts.push({ kind: 'text', value: query.slice(cursor, offset) });\n parts.push({ kind: 'token', token: { ...token, offset } });\n cursor = offset;\n }\n parts.push({ kind: 'text', value: query.slice(cursor) });\n return parts;\n}\n\nfunction CloseIcon() {\n return <LucideIcon icon={X} name=\"x\" />;\n}\n\nexport function TokenSearchField({\n id,\n label,\n query = '',\n tokens = [],\n model,\n revision,\n placeholder = 'Search',\n tokenPlaceholder = 'Add search…',\n disabled = false,\n autofocus = false,\n fill = false,\n collapsible = false,\n expanded = false,\n expandAction = 'expand-token-search',\n expandLabel,\n leading,\n trailing,\n trailingAction,\n presentation = 'standalone',\n editAction = 'edit-search-token',\n removeAction = 'remove-search-token',\n clearAction = 'clear-token-search',\n clearLabel = 'Clear search',\n clearIcon,\n className = '',\n editorAttributes = {},\n slot,\n}: TokenSearchFieldProps) {\n if (model) {\n query = model.state.value.query;\n tokens = model.state.value.tokens;\n }\n const suggestions = model?.suggestions.value ?? [];\n const parts = orderedParts(query, tokens);\n const tokenKey = tokens.map((token) => token.value).join('|');\n const key = model\n ? `${id}@${String(revision ?? '')}:${model.editorRevision.value}:${tokenKey}`\n : revision === undefined\n ? `${id}:${tokenKey}`\n : `${id}@${String(revision)}:${tokenKey}`;\n const resolvedExpanded =\n !collapsible || expanded || query.length > 0 || tokens.length > 0;\n return (\n <div\n class={`kui-token-search ${className}`.trim()}\n data-component=\"token-search-field\"\n data-token-search-id={id}\n data-disabled={String(disabled)}\n data-collapsible={String(collapsible)}\n data-expanded={String(resolvedExpanded)}\n data-fill={String(fill)}\n data-has-trailing={String(Boolean(trailing || trailingAction))}\n data-presentation={presentation}\n slot={slot}\n >\n {!resolvedExpanded ? (\n <button\n type=\"button\"\n class=\"kui-token-search__expand\"\n data-action={expandAction}\n aria-label={expandLabel ?? label}\n title={expandLabel ?? label}\n disabled={disabled}\n >\n <LucideIcon icon={Search} name=\"search\" />\n </button>\n ) : (\n <>\n <span class=\"kui-token-search__leading\" aria-hidden=\"true\">\n {leading ?? <LucideIcon icon={Search} name=\"search\" />}\n </span>\n <div\n {...editorAttributes}\n class=\"kui-token-search__editor\"\n data-key={key}\n data-morph-skip\n data-token-search-editor={id}\n data-token-count={tokens.length}\n data-placeholder={tokens.length ? tokenPlaceholder : placeholder}\n role=\"searchbox\"\n aria-label={label}\n aria-disabled={disabled ? 'true' : undefined}\n contenteditable={disabled ? 'false' : 'true'}\n spellcheck=\"false\"\n autofocus={autofocus}\n >\n {parts.map((part) =>\n part.kind === 'text' ? (\n <span\n data-token-search-text\n data-empty={String(part.value.length === 0)}\n >\n {part.value || (tokens.length ? '\\u200b' : '')}\n </span>\n ) : (\n <span\n class=\"kui-token-search__token\"\n contenteditable=\"false\"\n data-component=\"token-search-token\"\n data-token-value={part.token.value}\n >\n <button\n type=\"button\"\n class=\"kui-token-search__token-edit\"\n data-action={editAction}\n data-token-value={part.token.value}\n aria-label={`Edit ${part.token.accessibleLabel ?? part.token.label}`}\n disabled={disabled}\n >\n {part.token.label}\n </button>\n <button\n type=\"button\"\n class=\"kui-token-search__token-remove\"\n data-action={removeAction}\n data-token-value={part.token.value}\n aria-label={`Remove ${part.token.accessibleLabel ?? part.token.label}`}\n disabled={disabled}\n >\n <CloseIcon />\n </button>\n </span>\n ),\n )}\n </div>\n {(query || tokens.length > 0) && (\n <button\n type=\"button\"\n class=\"kui-token-search__clear\"\n data-action={clearAction}\n aria-label={clearLabel}\n title={clearLabel}\n disabled={disabled}\n >\n {clearIcon ?? <CloseIcon />}\n </button>\n )}\n {trailingAction ? (\n <button\n type=\"button\"\n class=\"kui-token-search__trailing-action\"\n id={trailingAction.id}\n data-action={trailingAction.action}\n aria-label={trailingAction.label}\n title={trailingAction.label}\n disabled={disabled}\n >\n {trailingAction.icon}\n </button>\n ) : trailing ? (\n <span class=\"kui-token-search__trailing\">{trailing}</span>\n ) : null}\n {!disabled && suggestions.length > 0 && (\n <div\n class=\"kui-token-search__suggestions\"\n data-token-search-keep-open\n >\n {suggestions.map((suggestion) => (\n <button\n type=\"button\"\n class=\"kui-token-search__suggestion\"\n data-token-search-suggestion={suggestion.value}\n >\n {suggestion.label}\n </button>\n ))}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\n/** Read editable text and ordered token offsets from a rendered TokenSearchField editor. */\nexport function readTokenSearchField(\n editor: HTMLElement,\n knownTokens: readonly TokenSearchToken[] = [],\n): TokenSearchFieldValue {\n let query = '';\n const tokens: TokenSearchToken[] = [];\n const visit = (node: Node): void => {\n if (node.nodeType === Node.TEXT_NODE) {\n query += (node.textContent ?? '')\n .replaceAll('\\u00a0', ' ')\n .replaceAll('\\u200b', '');\n return;\n }\n if (!(node instanceof HTMLElement)) return;\n if (node.matches('[data-component=\"token-search-token\"]')) {\n const value = node.dataset.tokenValue;\n const known = knownTokens.find((token) => token.value === value);\n if (known) tokens.push({ ...known, offset: query.length });\n else if (value)\n tokens.push({ value, label: value, offset: query.length });\n return;\n }\n if (node.tagName === 'BR') {\n query += ' ';\n return;\n }\n for (const child of node.childNodes) visit(child);\n };\n for (const child of editor.childNodes) visit(child);\n return { query, tokens };\n}\n\n/** Focus an editor and place its caret at a text offset, skipping atomic token chips. */\nexport function placeTokenSearchCaret(\n editor: HTMLElement,\n offset?: number,\n): void {\n editor.focus({ preventScroll: true });\n const selection = globalThis.getSelection();\n if (!selection) return;\n const range = document.createRange();\n if (offset === undefined) {\n range.selectNodeContents(editor);\n range.collapse(false);\n } else {\n let remaining = Math.max(0, offset);\n let found = false;\n const walker = document.createTreeWalker(editor, NodeFilter.SHOW_TEXT, {\n acceptNode: (node) =>\n node.parentElement?.closest('[data-component=\"token-search-token\"]')\n ? NodeFilter.FILTER_REJECT\n : NodeFilter.FILTER_ACCEPT,\n });\n for (let node = walker.nextNode(); node; node = walker.nextNode()) {\n const source = node.textContent ?? '';\n const length = source.replaceAll('\\u200b', '').length;\n if (remaining <= length) {\n range.setStart(\n node,\n source === '\\u200b' ? 0 : Math.min(remaining, source.length),\n );\n range.collapse(true);\n found = true;\n break;\n }\n remaining -= length;\n }\n if (!found) {\n range.selectNodeContents(editor);\n range.collapse(false);\n }\n }\n selection.removeAllRanges();\n selection.addRange(range);\n}\n"]}
@@ -1,7 +1,7 @@
1
+ import { LoadingSpinner } from './chunk-ZLWQZUGF.js';
1
2
  import { isSafeHtml } from 'kerfjs';
2
- import { jsxs, jsx } from 'kerfjs/jsx-runtime';
3
+ import { jsxs, jsx, Fragment } from 'kerfjs/jsx-runtime';
3
4
 
4
- // src/panel-toolbar-group.ts
5
5
  var RELOCATE_ON_COLLAPSE = /* @__PURE__ */ Symbol.for(
6
6
  "@kerfjs/ui.ToolbarControlGroup.relocateOnCollapse"
7
7
  );
@@ -63,10 +63,12 @@ function ToolbarControlGroup({
63
63
  visibility = "always",
64
64
  relocateOnCollapse = false,
65
65
  scrim = false,
66
+ busy = false,
67
+ busyLabel = "Working",
66
68
  avatarImage,
67
69
  slot
68
70
  }) {
69
- const group = /* @__PURE__ */ jsx(
71
+ const group = /* @__PURE__ */ jsxs(
70
72
  "div",
71
73
  {
72
74
  class: `kui-toolbar-control-group ${className}`.trim(),
@@ -90,14 +92,31 @@ function ToolbarControlGroup({
90
92
  "data-overflow": overflow,
91
93
  "data-visibility": visibility,
92
94
  "data-scrim": String(scrim),
95
+ "data-busy": String(busy),
96
+ "aria-busy": busy ? "true" : void 0,
97
+ inert: busy,
93
98
  style: avatarImage ? `--kui-toolbar-avatar-image:url(${JSON.stringify(avatarImage)})` : void 0,
94
99
  slot,
95
- children
100
+ children: [
101
+ children,
102
+ busy ? /* @__PURE__ */ jsx(
103
+ "span",
104
+ {
105
+ class: "kui-toolbar-control-group__busy-spinner",
106
+ "aria-hidden": "true",
107
+ children: /* @__PURE__ */ jsx(LoadingSpinner, {})
108
+ }
109
+ ) : null
110
+ ]
96
111
  }
97
112
  );
98
- return relocateOnCollapse ? markRelocatableGroup(group) : group;
113
+ const renderedGroup = relocateOnCollapse ? markRelocatableGroup(group) : group;
114
+ return busy ? /* @__PURE__ */ jsxs(Fragment, { children: [
115
+ renderedGroup,
116
+ /* @__PURE__ */ jsx("span", { class: "kui-toolbar-control-group__busy-status", role: "status", children: busyLabel })
117
+ ] }) : renderedGroup;
99
118
  }
100
119
 
101
120
  export { ToolbarActionLink, ToolbarControlGroup, isRelocatableGroup };
102
121
 
103
- //# sourceMappingURL=chunk-7JUBXOIV.js.map
122
+ //# sourceMappingURL=chunk-NXWE5S57.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/panel-toolbar-group.ts","../src/toolbar-control-group.tsx"],"names":[],"mappings":"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","file":"chunk-NXWE5S57.js","sourcesContent":["import { isSafeHtml, type SafeHtml } from 'kerfjs';\n\n// A render-time annotation, shared across separately bundled UI subpaths.\n// It never appears in the DOM or changes the group's visual treatment.\nconst RELOCATE_ON_COLLAPSE = Symbol.for(\n '@kerfjs/ui.ToolbarControlGroup.relocateOnCollapse',\n);\n\nexport function markRelocatableGroup(group: SafeHtml): SafeHtml {\n Object.defineProperty(group, RELOCATE_ON_COLLAPSE, { value: true });\n return group;\n}\n\nexport function isRelocatableGroup(value: unknown): value is SafeHtml {\n return (\n isSafeHtml(value) &&\n (value as SafeHtml & { [RELOCATE_ON_COLLAPSE]?: boolean })[\n RELOCATE_ON_COLLAPSE\n ] === true\n );\n}\n","import { LoadingSpinner } from './loading-spinner.js';\nimport { markRelocatableGroup } from './panel-toolbar-group.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport type ToolbarControlGroupAppearance = 'contained' | 'borderless';\nexport type ToolbarControlGroupTone = 'default' | 'dark';\nexport type ToolbarControlGroupButtonAppearance = 'plain' | 'push';\nexport type ToolbarControlGroupShape = 'pill' | 'rounded';\nexport type ToolbarControlGroupSize = 'default' | 'compact';\nexport type ToolbarControlGroupDensity = 'comfortable' | 'tight';\nexport type ToolbarControlGroupContent =\n 'icon' | 'text' | 'mixed' | 'avatar' | 'search';\nexport type ToolbarControlGroupFocusRing = 'control' | 'outline' | 'halo';\nexport type ToolbarControlGroupSelectedChrome = 'raised' | 'filled' | 'outline';\nexport type ToolbarControlGroupSelectedTone = 'brand' | 'neutral' | 'pop';\nexport type ToolbarControlGroupOverflow = 'visible' | 'scroll';\nexport type ToolbarControlGroupMenuInset = 'standard' | 'compact' | 'list-zero';\nexport type ToolbarControlGroupVisibility = 'always' | 'compact-only';\n\nexport interface ToolbarActionLinkProps {\n href: string;\n label: string;\n icon?: KerfUiContent;\n /** Optional machine-readable detail hidden visually but included in the default accessible name. */\n detail?: string;\n /** Override the accessible name when surrounding context is needed. */\n ariaLabel?: string;\n /** Open in a new tab with a safe rel and announce that behavior. */\n external?: boolean;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A semantic anchor with ToolbarControlGroup-owned action geometry. */\nexport function ToolbarActionLink({\n href,\n label,\n icon,\n detail,\n ariaLabel,\n external = false,\n className = '',\n slot,\n}: ToolbarActionLinkProps) {\n const accessibleLabel =\n ariaLabel ??\n `${label}${detail ? `, ${detail}` : ''}${external ? ' (opens in new tab)' : ''}`;\n return (\n <a\n class={`kui-toolbar-action-link ${className}`.trim()}\n data-component=\"toolbar-action-link\"\n href={href}\n target={external ? '_blank' : undefined}\n rel={external ? 'noopener noreferrer' : undefined}\n aria-label={accessibleLabel}\n slot={slot}\n >\n {icon}\n <span>{label}</span>\n {detail ? <code aria-hidden=\"true\">{detail}</code> : null}\n </a>\n );\n}\n\nexport interface ToolbarControlGroupProps {\n children: KerfUiContent;\n label?: string;\n className?: string;\n expanded?: boolean;\n single?: boolean;\n appearance?: ToolbarControlGroupAppearance;\n tone?: ToolbarControlGroupTone;\n buttonAppearance?: ToolbarControlGroupButtonAppearance;\n /** Corner shape: fully round `pill` (default) or a softer `rounded` rectangle. */\n shape?: ToolbarControlGroupShape;\n size?: ToolbarControlGroupSize;\n density?: ToolbarControlGroupDensity;\n content?: ToolbarControlGroupContent;\n /** Whether controls paint focus individually or the group paints an outline/halo on focus-within. */\n focusRing?: ToolbarControlGroupFocusRing;\n selectedChrome?: ToolbarControlGroupSelectedChrome;\n selectedTone?: ToolbarControlGroupSelectedTone;\n /** Size a nested Web Awesome dropdown trigger as part of this group. */\n nestedDropdown?: boolean;\n /** Configure the nested dropdown menu inset without consumer ::part() CSS. */\n menuInset?: ToolbarControlGroupMenuInset;\n /** Keep an overlong row of actions inside the available width with horizontal scrolling. */\n overflow?: ToolbarControlGroupOverflow;\n /** Responsive visibility owned by the enclosing Toolbar container. */\n visibility?: ToolbarControlGroupVisibility;\n /** Move this group into the work-area toolbar when its panel collapses. */\n relocateOnCollapse?: boolean;\n /** Add contrast behind photo-backed avatar content. */\n scrim?: boolean;\n /** Block the group's controls and show a spinner without changing its dimensions. */\n busy?: boolean;\n /** Announced status while busy; defaults to “Working”. */\n busyLabel?: string;\n /**\n * Avatar image URL. A single-control group paints it on the group; a\n * multi-control group paints it only on the pressed selection highlight.\n */\n avatarImage?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nexport function ToolbarControlGroup({\n children,\n label,\n className = '',\n expanded = false,\n single = false,\n appearance = 'contained',\n tone = 'default',\n buttonAppearance = 'plain',\n shape = 'pill',\n size = 'default',\n density = 'comfortable',\n content = 'icon',\n focusRing = 'control',\n selectedChrome = 'raised',\n selectedTone = 'brand',\n nestedDropdown = false,\n menuInset = 'standard',\n overflow = 'visible',\n visibility = 'always',\n relocateOnCollapse = false,\n scrim = false,\n busy = false,\n busyLabel = 'Working',\n avatarImage,\n slot,\n}: ToolbarControlGroupProps) {\n const group = (\n <div\n class={`kui-toolbar-control-group ${className}`.trim()}\n data-component=\"toolbar-control-group\"\n role={label ? 'group' : undefined}\n aria-label={label}\n data-appearance={appearance}\n data-tone={tone}\n data-button-appearance={buttonAppearance}\n data-expanded={String(expanded)}\n data-single={String(single)}\n data-shape={shape}\n data-size={size}\n data-density={density}\n data-content={content}\n data-focus-ring={focusRing}\n data-selected-chrome={selectedChrome}\n data-selected-tone={selectedTone}\n data-nested-dropdown={String(nestedDropdown)}\n data-menu-inset={menuInset}\n data-overflow={overflow}\n data-visibility={visibility}\n data-scrim={String(scrim)}\n data-busy={String(busy)}\n aria-busy={busy ? 'true' : undefined}\n inert={busy}\n style={\n avatarImage\n ? `--kui-toolbar-avatar-image:url(${JSON.stringify(avatarImage)})`\n : undefined\n }\n slot={slot}\n >\n {children}\n {busy ? (\n <span\n class=\"kui-toolbar-control-group__busy-spinner\"\n aria-hidden=\"true\"\n >\n <LoadingSpinner />\n </span>\n ) : null}\n </div>\n );\n const renderedGroup = relocateOnCollapse\n ? markRelocatableGroup(group)\n : group;\n return busy ? (\n <>\n {renderedGroup}\n <span class=\"kui-toolbar-control-group__busy-status\" role=\"status\">\n {busyLabel}\n </span>\n </>\n ) : (\n renderedGroup\n );\n}\n"]}
@@ -0,0 +1,44 @@
1
+ import { jsx, jsxs, Fragment } from 'kerfjs/jsx-runtime';
2
+
3
+ // src/toolbar.tsx
4
+ var claim = (edges, side) => edges?.includes(side) ? "true" : void 0;
5
+ function Toolbar({
6
+ leading,
7
+ center,
8
+ trailing,
9
+ label,
10
+ position = "header",
11
+ dividerSides = "",
12
+ centerAlign = "center",
13
+ responsive = "none",
14
+ responsiveAt = "narrow",
15
+ safeAreaEdges,
16
+ className = "",
17
+ slot
18
+ }) {
19
+ const attributes = {
20
+ class: `kui-toolbar ${className}`.trim(),
21
+ "data-component": "toolbar",
22
+ "divider-sides": dividerSides || void 0,
23
+ "data-has-center": String(Boolean(center)),
24
+ "data-center-align": centerAlign,
25
+ "data-responsive": responsive,
26
+ "data-responsive-at": responsiveAt,
27
+ "data-safe-area-block-start": claim(safeAreaEdges, "block-start"),
28
+ "data-safe-area-block-end": claim(safeAreaEdges, "block-end"),
29
+ "data-safe-area-inline-start": claim(safeAreaEdges, "inline-start"),
30
+ "data-safe-area-inline-end": claim(safeAreaEdges, "inline-end"),
31
+ "aria-label": label,
32
+ slot
33
+ };
34
+ const zones = /* @__PURE__ */ jsxs(Fragment, { children: [
35
+ /* @__PURE__ */ jsx("div", { class: "kui-toolbar__leading", children: leading }),
36
+ /* @__PURE__ */ jsx("div", { class: "kui-toolbar__center", children: center }),
37
+ /* @__PURE__ */ jsx("div", { class: "kui-toolbar__trailing", children: trailing })
38
+ ] });
39
+ return position === "footer" ? /* @__PURE__ */ jsx("footer", { ...attributes, children: zones }) : /* @__PURE__ */ jsx("header", { ...attributes, children: zones });
40
+ }
41
+
42
+ export { Toolbar };
43
+
44
+ //# sourceMappingURL=chunk-RGS4WX2M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/toolbar.tsx"],"names":[],"mappings":";;;AAwEA,IAAM,KAAA,GAAQ,CACZ,KAAA,EACA,IAAA,KACI,OAAO,QAAA,CAAS,IAAI,IAAI,MAAA,GAAS,MAAA;AAEhC,SAAS,OAAA,CAAQ;AAAA,EACtB,OAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA,GAAW,QAAA;AAAA,EACX,YAAA,GAAe,EAAA;AAAA,EACf,WAAA,GAAc,QAAA;AAAA,EACd,UAAA,GAAa,MAAA;AAAA,EACb,YAAA,GAAe,QAAA;AAAA,EACf,aAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,KAAA,EAAO,CAAA,YAAA,EAAe,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,IACvC,gBAAA,EAAkB,SAAA;AAAA,IAClB,iBAAiB,YAAA,IAAgB,MAAA;AAAA,IACjC,iBAAA,EAAmB,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAC,CAAA;AAAA,IACzC,mBAAA,EAAqB,WAAA;AAAA,IACrB,iBAAA,EAAmB,UAAA;AAAA,IACnB,oBAAA,EAAsB,YAAA;AAAA,IACtB,4BAAA,EAA8B,KAAA,CAAM,aAAA,EAAe,aAAa,CAAA;AAAA,IAChE,0BAAA,EAA4B,KAAA,CAAM,aAAA,EAAe,WAAW,CAAA;AAAA,IAC5D,6BAAA,EAA+B,KAAA,CAAM,aAAA,EAAe,cAAc,CAAA;AAAA,IAClE,2BAAA,EAA6B,KAAA,CAAM,aAAA,EAAe,YAAY,CAAA;AAAA,IAC9D,YAAA,EAAc,KAAA;AAAA,IACd;AAAA,GACF;AACA,EAAA,MAAM,wBACJ,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,sBAAA,EAAwB,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,oBAC3C,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,qBAAA,EAAuB,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,oBACzC,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,uBAAA,EAAyB,QAAA,EAAA,QAAA,EAAS;AAAA,GAAA,EAC/C,CAAA;AAEF,EAAA,OAAO,QAAA,KAAa,QAAA,mBAClB,GAAA,CAAC,QAAA,EAAA,EAAQ,GAAG,UAAA,EAAa,QAAA,EAAA,KAAA,EAAM,CAAA,mBAE/B,GAAA,CAAC,QAAA,EAAA,EAAQ,GAAG,UAAA,EAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAEnC","file":"chunk-RGS4WX2M.js","sourcesContent":["import type { PaneSeparatorSide } from './pane.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport type { Sides } from './sides.js';\n\nexport type ToolbarPosition = 'header' | 'footer';\n\nexport interface ToolbarProps {\n leading?: KerfUiContent;\n center?: KerfUiContent;\n trailing?: KerfUiContent;\n label?: string;\n /** Use footer semantics for a bottom toolbar; defaults to header. */\n position?: ToolbarPosition;\n /**\n * Physical divider edges in canonical top/right/bottom/left order, drawn\n * always. Defaults to none: a toolbar pinned over or under scrolling content\n * gets its divider from the scroll state instead — a `Pane` draws the line\n * between its chrome and content while content is scrolled away beneath it,\n * and `wireScrollDividers` `targets` can name a toolbar as chrome, which\n * then draws its facing side the same way.\n */\n dividerSides?: Sides;\n /** `balanced` gives both side zones equal tracks, centering the middle zone on the toolbar even if only one side has controls. */\n centerAlign?: 'center' | 'stretch' | 'balanced';\n /**\n * Component-owned responsive layout; applications choose the policy rather\n * than restyling toolbar internals. Under every policy the trailing zone\n * wraps its groups instead of clipping an action, and the center zone keeps\n * its whole content width: when the zones do not fit one row, the leading\n * title truncates with an ellipsis rather than the center overlapping it.\n * - `none` keeps one row; the leading identity truncates first.\n * - `stack` stacks the zones at `responsiveAt`, wrapping stacked control\n * groups onto further rows.\n * - `wrap` keeps one row while every zone fits at its natural width, and\n * otherwise moves the trailing zone below a whole leading identity.\n * - `center-priority` gives an expanded center control the full row.\n * - `trailing-priority` moves an expanded trailing control to a full row\n * below the leading identity at `responsiveAt`.\n */\n responsive?:\n 'none' | 'stack' | 'wrap' | 'center-priority' | 'trailing-priority';\n /** Container width at which `stack` or `trailing-priority` activates. */\n responsiveAt?: 'compact' | 'narrow';\n /**\n * Screen edges this toolbar claims for device safe-area compensation, for an\n * app bar or bottom bar that sits directly at a screen edge rather than in a\n * Pane header or footer. Each listed side pads by the inset its surrounding\n * layout reports through `--kui-edge-inset-*`, or the full device inset when\n * nothing routes that edge, while the toolbar's box and dividers paint\n * through. Omitted, the toolbar pads only the inline edges an owner such as\n * a Pane header hands it, and never a block edge.\n */\n safeAreaEdges?: readonly PaneSeparatorSide[];\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A toolbar's configuration, apart from its content: the props a composite\n * that renders a `Toolbar` for the app (a Workbench or CollapsiblePanel\n * toolbar) forwards, so the app configures that toolbar instead of styling it.\n */\nexport type ToolbarConfig = Pick<\n ToolbarProps,\n | 'dividerSides'\n | 'centerAlign'\n | 'responsive'\n | 'responsiveAt'\n | 'safeAreaEdges'\n>;\n\nconst claim = (\n edges: readonly PaneSeparatorSide[] | undefined,\n side: PaneSeparatorSide,\n) => (edges?.includes(side) ? 'true' : undefined);\n\nexport function Toolbar({\n leading,\n center,\n trailing,\n label,\n position = 'header',\n dividerSides = '',\n centerAlign = 'center',\n responsive = 'none',\n responsiveAt = 'narrow',\n safeAreaEdges,\n className = '',\n slot,\n}: ToolbarProps) {\n const attributes = {\n class: `kui-toolbar ${className}`.trim(),\n 'data-component': 'toolbar',\n 'divider-sides': dividerSides || undefined,\n 'data-has-center': String(Boolean(center)),\n 'data-center-align': centerAlign,\n 'data-responsive': responsive,\n 'data-responsive-at': responsiveAt,\n 'data-safe-area-block-start': claim(safeAreaEdges, 'block-start'),\n 'data-safe-area-block-end': claim(safeAreaEdges, 'block-end'),\n 'data-safe-area-inline-start': claim(safeAreaEdges, 'inline-start'),\n 'data-safe-area-inline-end': claim(safeAreaEdges, 'inline-end'),\n 'aria-label': label,\n slot,\n };\n const zones = (\n <>\n <div class=\"kui-toolbar__leading\">{leading}</div>\n <div class=\"kui-toolbar__center\">{center}</div>\n <div class=\"kui-toolbar__trailing\">{trailing}</div>\n </>\n );\n return position === 'footer' ? (\n <footer {...attributes}>{zones}</footer>\n ) : (\n <header {...attributes}>{zones}</header>\n );\n}\n\nexport type { Sides } from './sides.js';\n"]}
@@ -0,0 +1,80 @@
1
+ import { filterDataAttributes } from './chunk-SRSJO5QE.js';
2
+ import { jsx } from 'kerfjs/jsx-runtime';
3
+
4
+ var contentItemProtectedAttributes = /* @__PURE__ */ new Set(["data-component"]);
5
+ var interactiveProtectedAttributes = /* @__PURE__ */ new Set([
6
+ "data-component",
7
+ "data-action",
8
+ "data-item-id",
9
+ "data-interactive",
10
+ "data-selected",
11
+ "data-disabled",
12
+ "data-selection-mode",
13
+ "data-kui-pressed"
14
+ ]);
15
+ function ContentItem({
16
+ children,
17
+ frame = "none",
18
+ flush = false,
19
+ shape = "rounded",
20
+ title,
21
+ ariaLabel,
22
+ focusTarget = false,
23
+ interactive = false,
24
+ action,
25
+ itemId,
26
+ selectionMode = "none",
27
+ selected = false,
28
+ disabled = false,
29
+ className = "",
30
+ rootAttributes = {},
31
+ slot
32
+ }) {
33
+ const safeRootAttributes = filterDataAttributes(
34
+ rootAttributes,
35
+ interactive ? interactiveProtectedAttributes : contentItemProtectedAttributes
36
+ );
37
+ if (interactive && !action) {
38
+ throw new Error("Interactive ContentItem requires an action");
39
+ }
40
+ if (interactive && selected && selectionMode === "none") {
41
+ throw new Error("Selected ContentItem requires a selectionMode");
42
+ }
43
+ const cls = [
44
+ "kui-content-item",
45
+ shape === "pill" ? "kui-content-item--pill" : "",
46
+ frame === "framed" ? "kui-content-item--framed" : "",
47
+ flush ? "kui-content-item--flush" : "",
48
+ className
49
+ ].filter(Boolean).join(" ");
50
+ const interactiveAttributes = interactive ? {
51
+ "data-interactive": "true",
52
+ "data-action": disabled ? void 0 : action,
53
+ "data-item-id": itemId,
54
+ "data-selection-mode": selectionMode,
55
+ "data-selected": selectionMode === "none" ? void 0 : String(selected),
56
+ "data-disabled": disabled ? "true" : void 0
57
+ } : {};
58
+ return /* @__PURE__ */ jsx(
59
+ "div",
60
+ {
61
+ ...safeRootAttributes,
62
+ ...interactiveAttributes,
63
+ class: cls,
64
+ title,
65
+ "data-component": "content-item",
66
+ role: interactive ? selectionMode === "single" ? "option" : "button" : ariaLabel ? "region" : void 0,
67
+ "aria-label": ariaLabel,
68
+ "aria-selected": interactive && selectionMode === "single" ? String(selected) : void 0,
69
+ "aria-pressed": interactive && selectionMode === "toggle" ? String(selected) : void 0,
70
+ "aria-disabled": interactive && disabled ? "true" : void 0,
71
+ tabindex: interactive ? disabled ? "-1" : "0" : focusTarget ? "-1" : void 0,
72
+ slot,
73
+ children
74
+ }
75
+ );
76
+ }
77
+
78
+ export { ContentItem };
79
+
80
+ //# sourceMappingURL=chunk-SH6F3CCG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/content-item.tsx"],"names":[],"mappings":";;;AAWA,IAAM,8BAAA,mBAAiC,IAAI,GAAA,CAAI,CAAC,gBAAgB,CAAC,CAAA;AACjE,IAAM,8BAAA,uBAAqC,GAAA,CAAI;AAAA,EAC7C,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,kBAAA;AAAA,EACA,eAAA;AAAA,EACA,eAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAmFM,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,KAAA,GAAQ,MAAA;AAAA,EACR,KAAA,GAAQ,KAAA;AAAA,EACR,KAAA,GAAQ,SAAA;AAAA,EACR,KAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd,WAAA,GAAc,KAAA;AAAA,EACd,MAAA;AAAA,EACA,MAAA;AAAA,EACA,aAAA,GAAgB,MAAA;AAAA,EAChB,QAAA,GAAW,KAAA;AAAA,EACX,QAAA,GAAW,KAAA;AAAA,EACX,SAAA,GAAY,EAAA;AAAA,EACZ,iBAAiB,EAAC;AAAA,EAClB;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,kBAAA,GAAqB,oBAAA;AAAA,IACzB,cAAA;AAAA,IACA,cACI,8BAAA,GACA;AAAA,GACN;AACA,EAAA,IAAI,WAAA,IAAe,CAAC,MAAA,EAAQ;AAC1B,IAAA,MAAM,IAAI,MAAM,4CAA4C,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,WAAA,IAAe,QAAA,IAAY,aAAA,KAAkB,MAAA,EAAQ;AACvD,IAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AAAA,EACjE;AACA,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,kBAAA;AAAA,IACA,KAAA,KAAU,SAAS,wBAAA,GAA2B,EAAA;AAAA,IAC9C,KAAA,KAAU,WAAW,0BAAA,GAA6B,EAAA;AAAA,IAClD,QAAQ,yBAAA,GAA4B,EAAA;AAAA,IACpC;AAAA,GACF,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AACX,EAAA,MAAM,wBAAwB,WAAA,GAC1B;AAAA,IACE,kBAAA,EAAoB,MAAA;AAAA,IACpB,aAAA,EAAe,WAAW,MAAA,GAAY,MAAA;AAAA,IACtC,cAAA,EAAgB,MAAA;AAAA,IAChB,qBAAA,EAAuB,aAAA;AAAA,IACvB,eAAA,EACE,aAAA,KAAkB,MAAA,GAAS,MAAA,GAAY,OAAO,QAAQ,CAAA;AAAA,IACxD,eAAA,EAAiB,WAAW,MAAA,GAAS;AAAA,MAEvC,EAAC;AACL,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,kBAAA;AAAA,MACH,GAAG,qBAAA;AAAA,MACJ,KAAA,EAAO,GAAA;AAAA,MACP,KAAA;AAAA,MACA,gBAAA,EAAe,cAAA;AAAA,MACf,MACE,WAAA,GACI,aAAA,KAAkB,WAChB,QAAA,GACA,QAAA,GACF,YACE,QAAA,GACA,MAAA;AAAA,MAER,YAAA,EAAY,SAAA;AAAA,MACZ,iBACE,WAAA,IAAe,aAAA,KAAkB,QAAA,GAAW,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,MAEjE,gBACE,WAAA,IAAe,aAAA,KAAkB,QAAA,GAAW,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,MAEjE,eAAA,EAAe,WAAA,IAAe,QAAA,GAAW,MAAA,GAAS,MAAA;AAAA,MAClD,UACE,WAAA,GAAe,QAAA,GAAW,IAAA,GAAO,GAAA,GAAO,cAAc,IAAA,GAAO,MAAA;AAAA,MAE/D,IAAA;AAAA,MAEC;AAAA;AAAA,GACH;AAEJ","file":"chunk-SH6F3CCG.js","sourcesContent":["import { filterDataAttributes } from './extension-attributes.js';\nimport type { KerfUiContent } from './semantic-content.js';\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 option selection; `toggle` uses a pressed button. */\nexport type ContentItemSelectionMode = 'none' | 'single' | 'toggle';\n\nconst contentItemProtectedAttributes = new Set(['data-component']);\nconst interactiveProtectedAttributes = new Set([\n 'data-component',\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 }\n>;\n\ntype ContentItemInteractiveRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: 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 /** 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 /** 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 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 /** 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 /** 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 children,\n frame = 'none',\n flush = false,\n shape = 'rounded',\n title,\n ariaLabel,\n focusTarget = 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 return (\n <div\n {...safeRootAttributes}\n {...interactiveAttributes}\n class={cls}\n title={title}\n data-component=\"content-item\"\n role={\n interactive\n ? selectionMode === 'single'\n ? 'option'\n : 'button'\n : ariaLabel\n ? 'region'\n : undefined\n }\n aria-label={ariaLabel}\n aria-selected={\n interactive && selectionMode === 'single' ? String(selected) : undefined\n }\n aria-pressed={\n interactive && selectionMode === 'toggle' ? String(selected) : undefined\n }\n aria-disabled={interactive && disabled ? 'true' : undefined}\n tabindex={\n interactive ? (disabled ? '-1' : '0') : focusTarget ? '-1' : undefined\n }\n slot={slot}\n >\n {children}\n </div>\n );\n}\n"]}
@@ -3,6 +3,8 @@ import { jsxs, jsx } from 'kerfjs/jsx-runtime';
3
3
  // src/chip.tsx
4
4
  function Chip({
5
5
  children,
6
+ icon,
7
+ truncate = false,
6
8
  tone = "neutral",
7
9
  appearance = "quiet",
8
10
  shape = "pill",
@@ -13,6 +15,8 @@ function Chip({
13
15
  slot,
14
16
  ...remove
15
17
  }) {
18
+ if (truncate && typeof children !== "string")
19
+ throw new TypeError("Chip truncate requires a plain text label");
16
20
  return /* @__PURE__ */ jsxs(
17
21
  "span",
18
22
  {
@@ -23,10 +27,19 @@ function Chip({
23
27
  "data-shape": shape,
24
28
  "data-size": size,
25
29
  "data-disabled": disabled ? "" : void 0,
30
+ "data-truncate": truncate ? "" : void 0,
26
31
  "data-item-id": itemId,
27
32
  slot,
28
33
  children: [
29
- /* @__PURE__ */ jsx("span", { class: "kui-chip__label", children }),
34
+ icon === void 0 ? null : /* @__PURE__ */ jsx("span", { class: "kui-chip__icon", "aria-hidden": "true", children: icon }),
35
+ /* @__PURE__ */ jsx(
36
+ "span",
37
+ {
38
+ class: "kui-chip__label",
39
+ title: truncate ? String(children) : void 0,
40
+ children
41
+ }
42
+ ),
30
43
  remove.removeAction !== void 0 ? /* @__PURE__ */ jsx(
31
44
  "button",
32
45
  {
@@ -54,4 +67,4 @@ function Chip({
54
67
 
55
68
  export { Chip };
56
69
 
57
- //# sourceMappingURL=chunk-EAC4CDY7.js.map
70
+ //# sourceMappingURL=chunk-SMZGAPCU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chip.tsx"],"names":[],"mappings":";;;AAoCO,SAAS,IAAA,CAAK;AAAA,EACnB,QAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,IAAA,GAAO,SAAA;AAAA,EACP,UAAA,GAAa,OAAA;AAAA,EACb,KAAA,GAAQ,MAAA;AAAA,EACR,IAAA,GAAO,SAAA;AAAA,EACP,QAAA,GAAW,KAAA;AAAA,EACX,MAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,IAAI,QAAA,IAAY,OAAO,QAAA,KAAa,QAAA;AAClC,IAAA,MAAM,IAAI,UAAU,2CAA2C,CAAA;AACjE,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,CAAA,SAAA,EAAY,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,MACpC,gBAAA,EAAe,MAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,iBAAA,EAAiB,UAAA;AAAA,MACjB,YAAA,EAAY,KAAA;AAAA,MACZ,WAAA,EAAW,IAAA;AAAA,MACX,eAAA,EAAe,WAAW,EAAA,GAAK,MAAA;AAAA,MAC/B,eAAA,EAAe,WAAW,EAAA,GAAK,MAAA;AAAA,MAC/B,cAAA,EAAc,MAAA;AAAA,MACd,IAAA;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,IAAA,KAAS,MAAA,GAAY,uBACpB,GAAA,CAAC,MAAA,EAAA,EAAK,OAAM,gBAAA,EAAiB,aAAA,EAAY,QACtC,QAAA,EAAA,IAAA,EACH,CAAA;AAAA,wBAEF,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,iBAAA;AAAA,YACN,KAAA,EAAO,QAAA,GAAW,MAAA,CAAO,QAAQ,CAAA,GAAI,MAAA;AAAA,YAEpC;AAAA;AAAA,SACH;AAAA,QACC,MAAA,CAAO,iBAAiB,MAAA,mBACvB,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAM,kBAAA;AAAA,YACN,IAAA,EAAK,QAAA;AAAA,YACL,eAAa,MAAA,CAAO,YAAA;AAAA,YACpB,cAAY,MAAA,CAAO,WAAA;AAAA,YACnB,QAAA;AAAA,YAEA,QAAA,kBAAA,GAAA,CAAC,SAAI,OAAA,EAAQ,WAAA,EAAY,OAAM,IAAA,EAAK,MAAA,EAAO,IAAA,EAAK,aAAA,EAAY,MAAA,EAC1D,QAAA,kBAAA,GAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,CAAA,EAAE,sCAAA;AAAA,gBACF,IAAA,EAAK,MAAA;AAAA,gBACL,MAAA,EAAO,cAAA;AAAA,gBACP,cAAA,EAAa,MAAA;AAAA,gBACb,gBAAA,EAAe;AAAA;AAAA,aACjB,EACF;AAAA;AAAA,SACF,GACE;AAAA;AAAA;AAAA,GACN;AAEJ","file":"chunk-SMZGAPCU.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type {\n BadgeAppearance,\n BadgeShape,\n BadgeSize,\n BadgeTone,\n} from './badge.js';\n\ninterface ChipCommonProps {\n /** Decorative leading icon, normally an unsized LucideIcon. */\n icon?: SafeHtml;\n tone?: BadgeTone;\n appearance?: BadgeAppearance;\n shape?: BadgeShape;\n size?: BadgeSize;\n disabled?: boolean;\n /** Record identifier available to an application delegated action handler. */\n itemId?: string;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/** A removable chip needs both a delegated action and a specific accessible name. */\nexport type ChipProps = ChipCommonProps &\n (\n | { children: SafeHtml | string | number; truncate?: false }\n | { children: string; truncate: true }\n ) &\n (\n | { removeAction: string; removeLabel: string }\n | { removeAction?: never; removeLabel?: never }\n );\n\n/** A short label with an optional native remove button. The application owns removal. */\nexport function Chip({\n children,\n icon,\n truncate = false,\n tone = 'neutral',\n appearance = 'quiet',\n shape = 'pill',\n size = 'default',\n disabled = false,\n itemId,\n className = '',\n slot,\n ...remove\n}: ChipProps) {\n if (truncate && typeof children !== 'string')\n throw new TypeError('Chip truncate requires a plain text label');\n return (\n <span\n class={`kui-chip ${className}`.trim()}\n data-component=\"chip\"\n data-tone={tone}\n data-appearance={appearance}\n data-shape={shape}\n data-size={size}\n data-disabled={disabled ? '' : undefined}\n data-truncate={truncate ? '' : undefined}\n data-item-id={itemId}\n slot={slot}\n >\n {icon === undefined ? null : (\n <span class=\"kui-chip__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <span\n class=\"kui-chip__label\"\n title={truncate ? String(children) : undefined}\n >\n {children}\n </span>\n {remove.removeAction !== undefined ? (\n <button\n class=\"kui-chip__remove\"\n type=\"button\"\n data-action={remove.removeAction}\n aria-label={remove.removeLabel}\n disabled={disabled}\n >\n <svg viewBox=\"0 0 16 16\" width=\"12\" height=\"12\" aria-hidden=\"true\">\n <path\n d=\"M3.5 3.5 12.5 12.5M12.5 3.5 3.5 12.5\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.75\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n ) : null}\n </span>\n );\n}\n"]}
@@ -84,19 +84,56 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
84
84
  };
85
85
  const inlineState = /* @__PURE__ */ new Map();
86
86
  const sync = () => {
87
+ const workbench = findWorkbench();
88
+ let width;
87
89
  for (const panel of panels) {
88
90
  const element = panelElement(panel);
89
91
  if (!element) continue;
90
- const active = responsive(element);
91
- if (active && !inlineState.has(panel)) {
92
+ const at = Number(element.dataset.responsiveOverlayAt);
93
+ const customActive = element.dataset.responsiveOverlayAt !== void 0 && Number.isFinite(at) && at > 0 && element.dataset.presentation === "inline" && (width ??= workbench.getBoundingClientRect().width) <= at;
94
+ if (customActive) {
95
+ if (element.dataset.responsiveOverlayActive !== "true")
96
+ element.dataset.responsiveOverlayActive = "true";
97
+ } else if (element.hasAttribute("data-responsive-overlay-active"))
98
+ element.removeAttribute("data-responsive-overlay-active");
99
+ const active2 = responsive(element);
100
+ if (active2 && !inlineState.has(panel)) {
92
101
  inlineState.set(panel, panel.collapsed.peek());
93
102
  adapt(panel, element, true);
94
- } else if (!active && inlineState.has(panel)) {
103
+ } else if (!active2 && inlineState.has(panel)) {
95
104
  const remembered = inlineState.get(panel);
96
105
  inlineState.delete(panel);
97
106
  adapt(panel, element, remembered);
98
107
  }
108
+ const rendered = panelElement(panel);
109
+ if (rendered && customActive && rendered.dataset.responsiveOverlayActive !== "true")
110
+ rendered.dataset.responsiveOverlayActive = "true";
99
111
  }
112
+ if (!workbench) return;
113
+ const active = (key) => {
114
+ const element = workbench.querySelector(
115
+ PANEL_SELECTORS[key]
116
+ );
117
+ return element?.dataset.responsiveOverlayActive === "true" ? element : null;
118
+ };
119
+ const left = active("leftRail");
120
+ const right = active("rightRail");
121
+ const drawer = active("bottomDrawer");
122
+ const railOpen = [left, right].some(
123
+ (element) => element && element.dataset.collapsed !== "true"
124
+ );
125
+ const markers = [
126
+ left && "left",
127
+ right && "right",
128
+ drawer && "drawer",
129
+ railOpen && "rail-open",
130
+ (railOpen || drawer && drawer.dataset.collapsed !== "true") && "open"
131
+ ].filter(Boolean).join(" ");
132
+ if (markers) {
133
+ if (workbench.dataset.numericOverlays !== markers)
134
+ workbench.dataset.numericOverlays = markers;
135
+ } else if (workbench.hasAttribute("data-numeric-overlays"))
136
+ workbench.removeAttribute("data-numeric-overlays");
100
137
  };
101
138
  let observed = null;
102
139
  const resizeObserver = typeof globalThis.ResizeObserver === "function" ? new globalThis.ResizeObserver(() => sync()) : void 0;
@@ -114,7 +151,12 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
114
151
  });
115
152
  mutationObserver.observe(root, {
116
153
  attributes: true,
117
- attributeFilter: ["data-presentation", "data-responsive-overlay-at"],
154
+ attributeFilter: [
155
+ "data-presentation",
156
+ "data-responsive-overlay-at",
157
+ "data-responsive-overlay-active",
158
+ "data-collapsed"
159
+ ],
118
160
  childList: true,
119
161
  subtree: true
120
162
  });
@@ -186,11 +228,19 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
186
228
  const element = panelElement(panel);
187
229
  return !panel.collapsed.peek() && element && overlaid(element) ? [[panel, element]] : [];
188
230
  });
231
+ const inAllowedPortal = (panel, path) => {
232
+ const keepOpenOn = panel.keepOpenOn;
233
+ return Boolean(
234
+ keepOpenOn && path.some((target) => target instanceof Node && keepOpenOn(target))
235
+ );
236
+ };
189
237
  const onKeydown = (event) => {
190
238
  if (event.key !== "Escape" && event.key !== "Tab" || event.defaultPrevented)
191
239
  return;
192
240
  const open = openOverlays();
193
241
  if (open.length === 0) return;
242
+ if (open.some(([panel2]) => inAllowedPortal(panel2, event.composedPath())))
243
+ return;
194
244
  const active = ownerDocument.activeElement;
195
245
  const [panel, element] = open.find(([, candidate]) => candidate.contains(active)) ?? open[open.length - 1];
196
246
  if (event.key === "Escape") {
@@ -202,19 +252,20 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
202
252
  if (items.length === 0) return;
203
253
  const first = items[0];
204
254
  const last = items[items.length - 1];
205
- const inside = element.contains(active);
206
- if (event.shiftKey && (!inside || active === first)) {
255
+ const inside2 = element.contains(active);
256
+ if (event.shiftKey && (!inside2 || active === first)) {
207
257
  event.preventDefault();
208
258
  last.focus();
209
- } else if (!event.shiftKey && (!inside || active === last)) {
259
+ } else if (!event.shiftKey && (!inside2 || active === last)) {
210
260
  event.preventDefault();
211
261
  first.focus();
212
262
  }
213
263
  };
214
264
  let pressed = [];
265
+ const inside = (panel, element, path) => path.includes(element) || inAllowedPortal(panel, path);
215
266
  const onPointerdown = (event) => {
216
267
  const path = event.composedPath();
217
- pressed = openOverlays().filter(([, element]) => !path.includes(element)).map(([panel]) => panel);
268
+ pressed = openOverlays().filter(([panel, element]) => !inside(panel, element, path)).map(([panel]) => panel);
218
269
  const active = ownerDocument.activeElement;
219
270
  pressedFocus = panels.find((panel) => {
220
271
  if (panel.collapsed.peek()) return false;
@@ -230,7 +281,7 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
230
281
  pressed = [];
231
282
  const path = event.composedPath();
232
283
  for (const [panel, element] of openOverlays())
233
- if (candidates.includes(panel) && !path.includes(element))
284
+ if (candidates.includes(panel) && !inside(panel, element, path))
234
285
  panel.collapsed.value = true;
235
286
  };
236
287
  const onActivate = (event) => {
@@ -258,6 +309,8 @@ function wireWorkbenchOverlays(root, findWorkbench, panels, exclusive = false) {
258
309
  });
259
310
  return () => {
260
311
  for (const dispose of disposers.splice(0)) dispose();
312
+ for (const panel of panels)
313
+ panelElement(panel)?.removeAttribute("data-responsive-overlay-active");
261
314
  for (const [panel, remembered] of inlineState) {
262
315
  const element = panelElement(panel);
263
316
  if (element) adapt(panel, element, remembered);
@@ -374,7 +427,7 @@ function wireWorkbench(root, {
374
427
  }
375
428
  const overlayPanels = keys.flatMap((key) => {
376
429
  const collapsed = panels[key]?.collapsed;
377
- return collapsed ? [{ key, collapsed }] : [];
430
+ return collapsed ? [{ key, collapsed, keepOpenOn: panels[key]?.keepOpenOn }] : [];
378
431
  });
379
432
  if (dismissOverlays && overlayPanels.length > 0) {
380
433
  const selector2 = `[data-component="workbench"][id=${quoted(id)}]`;
@@ -396,4 +449,4 @@ function wireWorkbench(root, {
396
449
 
397
450
  export { wireWorkbench };
398
451
 
399
- //# sourceMappingURL=chunk-NNMLEDMD.js.map
452
+ //# sourceMappingURL=chunk-TJK44RQC.js.map