@kerfjs/ui 5.0.0-beta.57 → 5.0.0-beta.59

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 (79) hide show
  1. package/README.md +29 -6
  2. package/ai/component-catalog.json +51 -16
  3. package/ai/component-catalog.schema.json +16 -0
  4. package/ai/component-composition.json +16 -2
  5. package/ai/components/README.md +2 -2
  6. package/ai/components/popup-menu.md +96 -7
  7. package/ai/components/text.md +3 -3
  8. package/ai/components/token-search-field.md +6 -4
  9. package/ai/components/toolbar-control-group.md +2 -0
  10. package/ai/public-api-signatures-v1.md +67 -97
  11. package/ai/skill.md +6 -2
  12. package/ai/webawesome-jsx-signatures-v1.md +1 -1
  13. package/dist/catalog-resources.d.ts +1 -1
  14. package/dist/catalog.d.ts +1 -1
  15. package/dist/catalog.js +5 -5
  16. package/dist/{chunk-G2RKFVRB.js → chunk-2CCMJTVY.js} +2 -2
  17. package/dist/chunk-2CCMJTVY.js.map +1 -0
  18. package/dist/{chunk-ZIYOJFZD.js → chunk-7JUBXOIV.js} +17 -4
  19. package/dist/chunk-7JUBXOIV.js.map +1 -0
  20. package/dist/chunk-F7F7KRO2.js +187 -0
  21. package/dist/chunk-F7F7KRO2.js.map +1 -0
  22. package/dist/{chunk-XCO6YCYM.js → chunk-QPUPLNNB.js} +16 -5
  23. package/dist/chunk-QPUPLNNB.js.map +1 -0
  24. package/dist/{chunk-63ZWBGE3.js → chunk-RRB26JRJ.js} +25 -3
  25. package/dist/chunk-RRB26JRJ.js.map +1 -0
  26. package/dist/{chunk-NBYTIVHS.js → chunk-UFYZHYWU.js} +118 -12
  27. package/dist/chunk-UFYZHYWU.js.map +1 -0
  28. package/dist/{chunk-WLG6SSNT.js → chunk-UWONG4QE.js} +41 -8
  29. package/dist/chunk-UWONG4QE.js.map +1 -0
  30. package/dist/{chunk-553ASUK6.js → chunk-UX2VVXZ3.js} +2 -2
  31. package/dist/{chunk-553ASUK6.js.map → chunk-UX2VVXZ3.js.map} +1 -1
  32. package/dist/{chunk-24PHKUR3.js → chunk-UXT7TE6B.js} +1 -1
  33. package/dist/chunk-UXT7TE6B.js.map +1 -0
  34. package/dist/{chunk-PWXNJS2B.js → chunk-W4XKTST6.js} +2 -2
  35. package/dist/{chunk-PWXNJS2B.js.map → chunk-W4XKTST6.js.map} +1 -1
  36. package/dist/collapsible-panel.d.ts +8 -8
  37. package/dist/collapsible-panel.js +2 -2
  38. package/dist/collapsible-panel.js.map +1 -1
  39. package/dist/index.d.ts +2 -2
  40. package/dist/index.js +7 -6
  41. package/dist/list-header.js +1 -1
  42. package/dist/nav-stack.js +1 -1
  43. package/dist/{panel-toolbar-BN4x0rth.d.ts → panel-toolbar-DqwtBxQL.d.ts} +10 -11
  44. package/dist/popup-menu.d.ts +31 -3
  45. package/dist/popup-menu.js +1 -1
  46. package/dist/split-view.js +1 -1
  47. package/dist/styles/popup-menu.css +33 -4
  48. package/dist/styles/text.css +8 -0
  49. package/dist/styles/token-search-field.css +29 -0
  50. package/dist/text.d.ts +1 -1
  51. package/dist/text.js +1 -1
  52. package/dist/token-search-field-CCke1yvQ.d.ts +126 -0
  53. package/dist/token-search-field.d.ts +3 -75
  54. package/dist/token-search-field.js +1 -1
  55. package/dist/token-search-model.d.ts +3 -0
  56. package/dist/token-search-model.js +3 -0
  57. package/dist/token-search-model.js.map +1 -0
  58. package/dist/toolbar-control-group.d.ts +3 -1
  59. package/dist/toolbar-control-group.js +1 -1
  60. package/dist/wire-token-search-fields.d.ts +5 -1
  61. package/dist/wire-token-search-fields.js +1 -1
  62. package/dist/workbench.d.ts +5 -5
  63. package/dist/workbench.js +1 -1
  64. package/docs/accessibility.md +14 -0
  65. package/docs/collapsible-panel.md +12 -7
  66. package/docs/component-contract.md +2 -1
  67. package/docs/component-integration.md +8 -1
  68. package/docs/component-selection.md +43 -2
  69. package/docs/layout.md +4 -1
  70. package/docs/workbench.md +12 -11
  71. package/llms.txt +6 -3
  72. package/package.json +5 -1
  73. package/dist/chunk-24PHKUR3.js.map +0 -1
  74. package/dist/chunk-63ZWBGE3.js.map +0 -1
  75. package/dist/chunk-G2RKFVRB.js.map +0 -1
  76. package/dist/chunk-NBYTIVHS.js.map +0 -1
  77. package/dist/chunk-WLG6SSNT.js.map +0 -1
  78. package/dist/chunk-XCO6YCYM.js.map +0 -1
  79. package/dist/chunk-ZIYOJFZD.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/wire-token-search-fields.ts"],"names":["block","keyboard"],"mappings":"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","file":"chunk-UFYZHYWU.js","sourcesContent":["import { delegate, delegateCapture, type Signal, signal } from 'kerfjs';\n\nimport {\n placeTokenSearchCaret,\n readTokenSearchField,\n} from './token-search-field.js';\nimport type { TokenSearchModel } from './token-search-model.js';\n\nexport interface TokenSearchSubmit {\n id: string;\n editor: HTMLElement;\n}\n\n/** Reported to {@link WireTokenSearchFieldsOptions.onEdit} on every editor input. */\nexport interface TokenSearchEdit extends TokenSearchSubmit {\n /**\n * The `InputEvent` that mutated the editor — read `event.inputType` / `event.data`\n * to gate commit behavior (e.g. only parse a chip on whitespace-terminated input)\n * without keeping a separate `input` listener.\n */\n event: InputEvent;\n}\n\n/** Reported when adjacent-token keyboard deletion asks the app to drop a chip. */\nexport interface TokenSearchTokenRemoval {\n id: string;\n /** The `data-token-value` of the token the app should remove from its state. */\n value: string;\n editor: HTMLElement;\n /** `'backward'` = the token before the caret (Backspace); `'forward'` = after (Delete). */\n direction: 'backward' | 'forward';\n}\n\n/**\n * Opt-in keyboard behavior for the atomic token chips. Off unless `keyboard` is\n * set; each piece defaults on once opted in. The helper never mutates app state:\n * a removal is reported through {@link TokenSearchKeyboardOptions.onRemoveToken}\n * for the caller to apply, while caret movement past a chip is a pure ephemeral\n * mechanic the helper performs itself.\n */\ninterface TokenSearchKeyboardBaseOptions {\n /**\n * From a collapsed caret with no selection, Backspace removes the token\n * immediately before it and Delete the token immediately after — reported via\n * `onRemoveToken` — instead of deleting a character. Default: true.\n */\n /**\n * ArrowRight moves the caret past a trailing atomic token so text typed next\n * lands after the chip. Default: true.\n */\n moveCaretPastToken?: boolean;\n /** Apply the reported removal to your controlled state, then re-render. */\n}\n\nexport type TokenSearchKeyboardOptions = TokenSearchKeyboardBaseOptions &\n (\n | {\n removeAdjacentToken?: true;\n /** Apply the reported removal to your controlled state, then re-render. */\n onRemoveToken: (removal: TokenSearchTokenRemoval) => void;\n }\n | { removeAdjacentToken: false; onRemoveToken?: never }\n );\n\n/**\n * Managed collapsible behavior for the iconic TokenSearchField. Every piece is on\n * by default; disable a specific one to own it in the app. Provide `signals` to\n * drive app-owned `expanded` signals per field id instead of helper-created ones.\n */\nexport interface TokenSearchCollapsibleOptions {\n /** Expand the field and focus its editor when the iconic trigger is activated. Default: true. */\n expandOnActivate?: boolean;\n /** Collapse the field when focus leaves it while it is empty. Default: true. */\n collapseOnEmptyBlur?: boolean;\n /** Collapse an empty field on Escape and restore focus to its trigger. Default: true. */\n collapseOnEscape?: boolean;\n /** Focus the editor on expand/controlled clear and the trigger on Escape-collapse. Default: true. */\n manageFocus?: boolean;\n /**\n * Keep an empty field expanded when focus moves to a caller-owned surface\n * rendered outside the field — a suggestions dropdown, date picker, or help\n * popover shown beside it. Return true for any focus target that must NOT\n * trigger collapse-on-empty-blur. An element carrying `data-token-search-keep-open`\n * (or any node inside one) is always exempt, so this predicate is only needed\n * for surfaces you cannot mark declaratively.\n */\n keepOpenOn?: (target: Node | null) => boolean;\n /** App-owned `expanded` signals keyed by field id; adopted instead of helper-created. */\n signals?: Readonly<Record<string, Signal<boolean>>>;\n}\n\nexport interface WireTokenSearchFieldsOptions {\n /** Optional automatic grammar/suggestion models, keyed by TokenSearchField id. */\n models?: Readonly<Record<string, TokenSearchModel>>;\n onSubmit?: (submission: TokenSearchSubmit) => void;\n /** Fired on every editor `input`, after the browser mutates it, so a caller can drop its own `input` listener. */\n onEdit?: (edit: TokenSearchEdit) => void;\n /** Managed collapsible transient behavior. `true`/omitted = on with defaults; `false` = fully off. */\n collapsible?: boolean | TokenSearchCollapsibleOptions;\n /** Opt-in atomic-chip keyboard behavior (off by default). */\n keyboard?: false | TokenSearchKeyboardOptions;\n}\n\n/**\n * The value returned from {@link wireTokenSearchFields}: call it (or `dispose()`) to\n * tear down. When collapsible behavior is managed, it also exposes the transient\n * `expanded` state per field id so the app can read it in render, hand in its own\n * signal, or drive it imperatively.\n */\nexport interface TokenSearchFieldsHandle {\n (): void;\n dispose(): void;\n /** The managed `expanded` signal for a field id (adopted or helper-created); undefined when unmanaged. */\n expanded(id: string): Signal<boolean> | undefined;\n /** Expand the field (and, when focus is managed, focus its editor). */\n open(id: string): void;\n /** Collapse the field (and, when focus is managed, restore focus to its trigger). */\n close(id: string): void;\n}\n\ninterface PendingTokenDeletion {\n id: string;\n offset: number;\n tokenCount: number;\n selectedAll: boolean;\n}\n\nfunction editorFromEvent(\n root: HTMLElement,\n event: Event,\n): HTMLElement | undefined {\n const target = event.target;\n if (!(target instanceof Element)) return;\n const editor = target.closest<HTMLElement>('[data-token-search-editor]');\n return editor && root.contains(editor) ? editor : undefined;\n}\n\nfunction caretQueryOffset(editor: HTMLElement): number | undefined {\n const selection = editor.ownerDocument.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n const selectionRange = selection.getRangeAt(0);\n if (!editor.contains(selectionRange.startContainer)) return;\n const prefixRange = editor.ownerDocument.createRange();\n prefixRange.selectNodeContents(editor);\n prefixRange.setEnd(selectionRange.startContainer, selectionRange.startOffset);\n const prefix = editor.ownerDocument.createElement('div');\n prefix.append(prefixRange.cloneContents());\n return readTokenSearchField(prefix).query.length;\n}\n\nfunction replacementEditor(\n root: HTMLElement,\n id: string,\n): HTMLElement | undefined {\n return [\n ...root.querySelectorAll<HTMLElement>('[data-token-search-editor]'),\n ].find((editor) => editor.dataset.tokenSearchEditor === id);\n}\n\nfunction editorIsEmpty(editor: HTMLElement): boolean {\n const value = readTokenSearchField(editor);\n return value.query.length === 0 && value.tokens.length === 0;\n}\n\n/** Whether the active selection covers all logical text and tokens in the editor. */\nfunction selectionCoversEditor(editor: HTMLElement): boolean {\n // onBeforeInput calls this only after caretQueryOffset verified a live range.\n const selected = editor.ownerDocument.getSelection()!.getRangeAt(0);\n if (selected.collapsed || !editor.contains(selected.commonAncestorContainer))\n return false;\n // Browser select-all ranges are not structurally identical across platforms:\n // some use editor child offsets while others start/end inside the first/last\n // text nodes. Compare the selected logical value instead of DOM boundaries.\n const selectedHost = editor.ownerDocument.createElement('div');\n selectedHost.append(selected.cloneContents());\n const fullValue = readTokenSearchField(editor);\n const selectedValue = readTokenSearchField(selectedHost);\n return (\n selectedValue.query === fullValue.query &&\n selectedValue.tokens.length === fullValue.tokens.length &&\n selectedValue.tokens.every(\n (token, index) => token.value === fullValue.tokens[index]?.value,\n )\n );\n}\n\nconst TOKEN_SELECTOR = '[data-component=\"token-search-token\"]';\nconst TEXT_SELECTOR = '[data-token-search-text]';\nconst stripZwsp = (text: string): string => text.replaceAll('​', '');\n\n/**\n * A `contenteditable` host emptied by select-all + Delete (or Backspace) leaves a\n * bogus `<br>` in every engine: it renders as a stray newline and `readTokenSearchField`\n * reads it back as a space. Strip those line breaks after a delete, and when the field\n * is otherwise empty (no chips, no visible text) restore the canonical empty text span\n * and place the caret in it so typing resumes cleanly. Called only after the browser has\n * applied the delete, so an ordinary partial delete is never touched.\n */\nfunction normalizeEmptiedEditor(\n editor: HTMLElement,\n selectedAll = false,\n): void {\n const lineBreaks = editor.querySelectorAll('br');\n if (lineBreaks.length === 0 && !selectedAll) return;\n for (const lineBreak of lineBreaks) lineBreak.remove();\n if (!selectedAll && editor.querySelector(TOKEN_SELECTOR)) return;\n if (!selectedAll && stripZwsp(editor.textContent ?? '') !== '') return;\n const doc = editor.ownerDocument;\n const span = doc.createElement('span');\n span.setAttribute('data-token-search-text', '');\n span.setAttribute('data-empty', 'true');\n editor.replaceChildren(span);\n if (doc.activeElement !== editor) return;\n // The editor is the focused, connected editing host, so a selection exists.\n const selection = doc.getSelection()!;\n const range = doc.createRange();\n range.setStart(span, 0);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n}\n\n/** The collapsed, in-editor caret range, or undefined when there is a selection or none. */\nfunction collapsedCaret(editor: HTMLElement): Range | undefined {\n const selection = editor.ownerDocument.getSelection();\n if (!selection || selection.rangeCount === 0) return;\n const range = selection.getRangeAt(0);\n if (!range.collapsed || !editor.contains(range.startContainer)) return;\n return range;\n}\n\n/** The direct child of `editor` that contains `node` (or `node` itself), else null. */\nfunction topBlock(editor: HTMLElement, node: Node): Node | null {\n let current: Node = node;\n while (current.parentNode && current.parentNode !== editor)\n current = current.parentNode;\n return current.parentNode === editor ? current : null;\n}\n\n/** A text node or text span holding no visible character (only zero-width spacers). */\nfunction isBlankText(node: Node): boolean {\n if (node.nodeType === Node.TEXT_NODE)\n return stripZwsp((node as CharacterData).data) === '';\n return (\n node instanceof Element &&\n node.matches(TEXT_SELECTOR) &&\n stripZwsp(node.textContent ?? '') === ''\n );\n}\n\n/** The nearest sibling block on `direction`, skipping blank text spacers. */\nfunction meaningfulSibling(\n block: Node,\n direction: 'backward' | 'forward',\n): Node | null {\n let sibling =\n direction === 'backward' ? block.previousSibling : block.nextSibling;\n while (sibling && isBlankText(sibling))\n sibling =\n direction === 'backward' ? sibling.previousSibling : sibling.nextSibling;\n return sibling;\n}\n\n/** The node immediately on `direction` of the caret, only when no visible character separates them. */\nfunction caretSideNode(\n editor: HTMLElement,\n range: Range,\n direction: 'backward' | 'forward',\n): Node | null {\n const { startContainer: container, startOffset: offset } = range;\n if (container.nodeType === Node.TEXT_NODE) {\n const text = (container as CharacterData).data;\n const side =\n direction === 'backward' ? text.slice(0, offset) : text.slice(offset);\n if (stripZwsp(side).length > 0) return null;\n // An in-editor text node always has a top block (itself or its wrapping span).\n return meaningfulSibling(topBlock(editor, container)!, direction);\n }\n const child = container.childNodes[\n direction === 'backward' ? offset - 1 : offset\n ] as Node | undefined;\n if (child) {\n // `child` is a descendant of the in-editor caret container, so it has a top block.\n const block = topBlock(editor, child)!;\n return isBlankText(child) ? meaningfulSibling(block, direction) : block;\n }\n const block = topBlock(editor, container);\n return block ? meaningfulSibling(block, direction) : null;\n}\n\n/** The atomic token chip adjacent to a collapsed caret on `direction`, if any. */\nfunction adjacentToken(\n editor: HTMLElement,\n direction: 'backward' | 'forward',\n): HTMLElement | undefined {\n const range = collapsedCaret(editor);\n if (!range) return;\n const node = caretSideNode(editor, range, direction);\n if (!node) return;\n const base = node instanceof Element ? node : node.parentElement;\n const chip = base?.closest<HTMLElement>(TOKEN_SELECTOR) ?? null;\n return chip && editor.contains(chip) ? chip : undefined;\n}\n\n/** Move the caret to just after an atomic token chip so typed text lands after it.\n * Only reached after {@link collapsedCaret} already found a live selection, and the\n * chip is a direct block of the editor. */\nfunction placeCaretAfterToken(editor: HTMLElement, chip: HTMLElement): void {\n const selection = editor.ownerDocument.getSelection()!;\n const range = editor.ownerDocument.createRange();\n range.setStartAfter(topBlock(editor, chip)!);\n range.collapse(true);\n selection.removeAllRanges();\n selection.addRange(range);\n editor.focus({ preventScroll: true });\n}\n\n/**\n * Wire every TokenSearchField under `root`: submit on Enter, preserve the caret across\n * controlled token deletion, and (by default) manage the collapsible field's transient\n * expand/collapse/focus. Returns a {@link TokenSearchFieldsHandle} — a disposer that also\n * exposes the managed `expanded` state per field id.\n */\nexport function wireTokenSearchFields(\n root: HTMLElement,\n {\n models = {},\n onSubmit,\n onEdit,\n collapsible = true,\n keyboard = false,\n }: WireTokenSearchFieldsOptions = {},\n): TokenSearchFieldsHandle {\n const managed = collapsible !== false;\n const config = typeof collapsible === 'object' ? collapsible : {};\n const expandOnActivate = managed && (config.expandOnActivate ?? true);\n const collapseOnEmptyBlur = managed && (config.collapseOnEmptyBlur ?? true);\n const collapseOnEscape = managed && (config.collapseOnEscape ?? true);\n const manageFocus = managed && (config.manageFocus ?? true);\n const keepOpenOn = config.keepOpenOn;\n const keyboardOn = keyboard !== false || Object.keys(models).length > 0;\n const keyboardConfig = typeof keyboard === 'object' ? keyboard : undefined;\n const removeAdjacentToken =\n keyboardOn && (keyboardConfig?.removeAdjacentToken ?? true);\n const moveCaretPastToken =\n keyboardOn && (keyboardConfig?.moveCaretPastToken ?? true);\n const onRemoveToken = keyboardConfig?.onRemoveToken;\n const adopted = config.signals ?? {};\n const created = new Map<string, Signal<boolean>>();\n let disposed = false;\n let pointerActivationTarget: Element | null = null;\n\n /** True when focus moving to `element` should keep an empty field expanded. */\n const isExemptTarget = (element: Element | null): boolean => {\n if (!element) return false;\n if (element.closest('[data-token-search-keep-open]')) return true;\n return keepOpenOn ? keepOpenOn(element) : false;\n };\n\n // WebKit can report `focusout.relatedTarget === null` while a pointer is\n // moving focus into a sibling button. Preserve the actual activation target\n // across that focus transition so a keep-open surface cannot be collapsed\n // (and removed) between pointerdown and click.\n const trackPointerActivation = (event: Event) => {\n pointerActivationTarget =\n event.target instanceof Element ? event.target : null;\n };\n const clearPointerActivation = () => {\n pointerActivationTarget = null;\n };\n const clearPointerActivationAfterDefault = () => {\n view().queueMicrotask(clearPointerActivation);\n };\n\n const signalFor = (id: string): Signal<boolean> => {\n const own = adopted[id];\n if (own) return own;\n let field = created.get(id);\n if (!field) {\n field = signal(false);\n created.set(id, field);\n }\n return field;\n };\n const setExpanded = (id: string, next: boolean) => {\n const state = signalFor(id);\n if (state.value !== next) state.value = next;\n };\n const view = () => root.ownerDocument.defaultView!;\n const focusAfterRender = (id: string, selector: string) => {\n view().requestAnimationFrame(() => {\n if (disposed) return;\n const target = root.querySelector<HTMLElement>(\n `[data-component=\"token-search-field\"][data-token-search-id=\"${CSS.escape(id)}\"] ${selector}`,\n );\n if (!target) return;\n if (target.matches('[data-token-search-editor]'))\n placeTokenSearchCaret(target);\n else target.focus();\n });\n };\n const openField = (id: string) => {\n setExpanded(id, true);\n if (manageFocus) focusAfterRender(id, '[data-token-search-editor]');\n };\n const closeField = (id: string) => {\n setExpanded(id, false);\n if (manageFocus) focusAfterRender(id, '.kui-token-search__expand');\n };\n\n const clearing = new Map<string, () => void>();\n const pending = new Map<string, PendingTokenDeletion>();\n const deleting = new Map<string, () => void>();\n const selectAllIntents = new WeakSet<HTMLElement>();\n // editorFromEvent's selector guarantees this data attribute is present.\n const intentId = (editor: HTMLElement): string =>\n editor.dataset.tokenSearchEditor!;\n const captureDeletion = (editor: HTMLElement, selectedAll?: boolean) => {\n if (editor.ownerDocument.activeElement !== editor) return;\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n const offset = selectedAll ? 0 : caretQueryOffset(editor);\n if (!id || offset === undefined || field?.dataset.disabled === 'true')\n return;\n pending.set(id, {\n id,\n offset,\n tokenCount: editor.querySelectorAll(\n '[data-component=\"token-search-token\"]',\n ).length,\n selectedAll: selectedAll ?? selectionCoversEditor(editor),\n });\n };\n const onBeforeInput = (event: Event) => {\n const editor = editorFromEvent(root, event);\n if (editor && (event as InputEvent).inputType.startsWith('delete'))\n captureDeletion(editor);\n };\n const restoreDeletion = (\n editor: HTMLElement,\n deletion: PendingTokenDeletion,\n ) => {\n deleting.get(deletion.id)?.();\n const stop = () => {\n observer.disconnect();\n view().clearTimeout(timeout);\n deleting.delete(deletion.id);\n };\n const restore = () => {\n const replacement = replacementEditor(root, deletion.id);\n // A native input can drain microtasks between capture and bubble listeners.\n // Wait for the actual replacement, including one rendered by a later listener.\n if (!replacement || replacement === editor) return;\n stop();\n const active = replacement.ownerDocument.activeElement;\n if (\n active !== editor &&\n active !== replacement &&\n active !== replacement.ownerDocument.body\n )\n return;\n placeTokenSearchCaret(replacement, deletion.offset);\n };\n const observer = new MutationObserver(restore);\n observer.observe(root, { childList: true, subtree: true });\n // The input task owns synchronous controlled rendering. Expiration only\n // disconnects observation; it cannot move a later selection or steal focus.\n const timeout = view().setTimeout(stop, 0);\n deleting.set(deletion.id, stop);\n };\n const onInput = (event: Event) => {\n const editor = editorFromEvent(root, event);\n if (!editor) return;\n const editorId = intentId(editor);\n const inputType = (event as InputEvent).inputType;\n if (!inputType.startsWith('delete')) selectAllIntents.delete(editor);\n const deletion = pending.get(editorId);\n if (inputType.startsWith('delete'))\n normalizeEmptiedEditor(editor, deletion?.selectedAll);\n const restore =\n deletion &&\n (deletion.selectedAll ||\n editor.querySelectorAll(TOKEN_SELECTOR).length < deletion.tokenCount);\n // Own the replacement before application listeners synchronously render.\n // A populated field can be visually open while its adopted signal is false.\n if (restore) {\n restoreDeletion(editor, deletion);\n if (\n manageFocus &&\n editor.closest<HTMLElement>('[data-component=\"token-search-field\"]')\n ?.dataset.collapsible === 'true'\n )\n setExpanded(editorId, true);\n }\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (id && field?.dataset.disabled !== 'true') {\n const model = models[id];\n if (model) {\n const before = editor.querySelectorAll(TOKEN_SELECTOR).length;\n const current = readTokenSearchField(editor, model.state.value.tokens);\n const input = event as InputEvent;\n const commit =\n (typeof input.data === 'string' && /\\s$/.test(input.data)) ||\n (input.inputType === 'insertFromPaste' && /\\s$/.test(current.query));\n model.edit(current, commit);\n if (model.state.value.tokens.length > before)\n focusAfterRender(id, '[data-token-search-editor]');\n }\n if (onEdit) onEdit({ id, editor, event: event as InputEvent });\n }\n pending.delete(editorId);\n };\n root.addEventListener('beforeinput', onBeforeInput, true);\n root.addEventListener('input', onInput, true);\n\n const clearSelectAllIntent = (event: Event) => {\n const editor = editorFromEvent(root, event);\n if (editor) selectAllIntents.delete(editor);\n };\n const trackSelectAllIntent = (event: Event) => {\n const keyboardEvent = event as KeyboardEvent;\n const editor = editorFromEvent(root, event);\n if (!editor || keyboardEvent.isComposing) return;\n const fullDeletionInputType =\n keyboardEvent.key === 'Backspace'\n ? 'deleteContentBackward'\n : keyboardEvent.key === 'Delete'\n ? 'deleteContentForward'\n : undefined;\n if (\n keyboardEvent.key.toLowerCase() === 'a' &&\n (keyboardEvent.ctrlKey || keyboardEvent.metaKey) &&\n !keyboardEvent.altKey &&\n !keyboardEvent.shiftKey\n ) {\n // Capture this before target/bubble handlers can stop propagation.\n selectAllIntents.add(editor);\n return;\n }\n if (fullDeletionInputType && selectAllIntents.delete(editor)) {\n if (editor.parentElement?.dataset.disabled === 'true') return;\n // Native mixed-contenteditable deletion is not reliable: Linux engines\n // can leave contenteditable=false chips behind, and a controlled render\n // then restores them from application state. The preceding shortcut is\n // an unambiguous full-delete request, so own that transition and publish\n // the same bubbling input contract the native edit would have produced.\n keyboardEvent.preventDefault();\n captureDeletion(editor, true);\n normalizeEmptiedEditor(editor, true);\n editor.dispatchEvent(\n new InputEvent('input', {\n bubbles: true,\n inputType: fullDeletionInputType,\n }),\n );\n return;\n }\n // Any intervening keyboard action consumes the shortcut intent. Printable\n // replacement typing clears it here before the browser's input event; the\n // input listener also covers paste, drop, and other non-keyboard edits.\n if (!fullDeletionInputType) selectAllIntents.delete(editor);\n };\n root.addEventListener('keydown', trackSelectAllIntent, true);\n root.addEventListener('pointerdown', clearSelectAllIntent, true);\n root.addEventListener('focusout', clearSelectAllIntent, true);\n\n const disposers: Array<() => void> = [\n () => {\n pending.clear();\n for (const stop of deleting.values()) stop();\n },\n () => root.removeEventListener('beforeinput', onBeforeInput, true),\n () => root.removeEventListener('input', onInput, true),\n () => root.removeEventListener('keydown', trackSelectAllIntent, true),\n () => root.removeEventListener('pointerdown', clearSelectAllIntent, true),\n () => root.removeEventListener('focusout', clearSelectAllIntent, true),\n ];\n\n disposers.push(\n delegate(\n root,\n 'keydown',\n '[data-token-search-editor]',\n (event, element) => {\n const keyboardEvent = event as KeyboardEvent;\n const editor = element as HTMLElement;\n if (keyboardEvent.isComposing) return;\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (!id || field?.dataset.disabled === 'true') return;\n if (keyboardEvent.key === 'Enter') {\n keyboardEvent.preventDefault();\n const model = models[id];\n if (model)\n model.submit(\n readTokenSearchField(editor, model.state.value.tokens),\n );\n onSubmit?.({ id, editor });\n return;\n }\n if (models[id] && keyboardEvent.key === 'ArrowDown') {\n const first = field.querySelector<HTMLButtonElement>(\n '[data-token-search-suggestion]',\n );\n if (first) {\n keyboardEvent.preventDefault();\n first.focus();\n return;\n }\n }\n if (models[id] && keyboardEvent.key === 'Escape') models[id].dismiss();\n if (\n removeAdjacentToken &&\n (keyboardEvent.key === 'Backspace' || keyboardEvent.key === 'Delete')\n ) {\n const direction =\n keyboardEvent.key === 'Backspace' ? 'backward' : 'forward';\n const chip = adjacentToken(editor, direction);\n if (chip) {\n keyboardEvent.preventDefault();\n const removal: TokenSearchTokenRemoval = {\n id,\n value: chip.dataset.tokenValue ?? '',\n editor,\n direction,\n };\n models[id]?.remove(removal.value);\n onRemoveToken?.(removal);\n return;\n }\n }\n if (moveCaretPastToken && keyboardEvent.key === 'ArrowRight') {\n const chip = adjacentToken(editor, 'forward');\n if (chip) {\n keyboardEvent.preventDefault();\n placeCaretAfterToken(editor, chip);\n return;\n }\n }\n if (\n collapseOnEscape &&\n keyboardEvent.key === 'Escape' &&\n field?.dataset.collapsible === 'true' &&\n editorIsEmpty(editor)\n ) {\n keyboardEvent.preventDefault();\n closeField(id);\n }\n },\n ),\n );\n\n if (Object.keys(models).length > 0) {\n disposers.push(\n delegate(\n root,\n 'keydown',\n '[data-token-search-suggestion]',\n (event, element) => {\n const keyboard = event as KeyboardEvent;\n const button = element as HTMLButtonElement;\n const buttons = [\n ...button.parentElement!.querySelectorAll<HTMLButtonElement>(\n '[data-token-search-suggestion]',\n ),\n ];\n const index = buttons.indexOf(button);\n if (keyboard.key === 'Escape') {\n keyboard.preventDefault();\n button\n .closest<HTMLElement>('[data-component=\"token-search-field\"]')\n ?.querySelector<HTMLElement>('[data-token-search-editor]')\n ?.focus();\n } else if (\n keyboard.key === 'ArrowDown' ||\n keyboard.key === 'ArrowUp'\n ) {\n keyboard.preventDefault();\n buttons[\n (index +\n (keyboard.key === 'ArrowDown' ? 1 : buttons.length - 1)) %\n buttons.length\n ]?.focus();\n }\n },\n ),\n delegate(\n root,\n 'click',\n '[data-token-search-suggestion]',\n (_event, element) => {\n const field = element.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n const value = (element as HTMLElement).dataset.tokenSearchSuggestion;\n if (!id || !value || field?.dataset.disabled === 'true') return;\n models[id]?.choose(value);\n focusAfterRender(id, '[data-token-search-editor]');\n },\n ),\n delegate(\n root,\n 'click',\n '.kui-token-search__token-edit',\n (_event, element) => {\n const field = element.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n const value = (element as HTMLElement).dataset.tokenValue;\n if (\n !id ||\n !value ||\n field?.dataset.disabled === 'true' ||\n !models[id]\n )\n return;\n models[id].expandToken(value);\n focusAfterRender(id, '[data-token-search-editor]');\n },\n ),\n delegate(\n root,\n 'click',\n '.kui-token-search__token-remove',\n (_event, element) => {\n const field = element.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n const value = (element as HTMLElement).dataset.tokenValue;\n if (id && value && field?.dataset.disabled !== 'true')\n models[id]?.remove(value);\n },\n ),\n delegate(root, 'click', '.kui-token-search__clear', (_event, element) => {\n const field = element.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (id && field?.dataset.disabled !== 'true') models[id]?.clear();\n }),\n );\n }\n\n if (expandOnActivate) {\n disposers.push(\n delegate(\n root,\n 'click',\n '.kui-token-search__expand',\n (_event, element) => {\n // The selector guarantees a collapsible field ancestor; only skip a disabled one.\n const field = (element as HTMLElement).closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (id && field?.dataset.disabled !== 'true') openField(id);\n },\n ),\n );\n }\n\n if (manageFocus) {\n disposers.push(\n () => {\n for (const stop of clearing.values()) stop();\n },\n delegateCapture(\n root,\n 'click',\n '.kui-token-search__clear',\n (_event, element) => {\n const field = element.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (\n !id ||\n field.dataset.collapsible !== 'true' ||\n field.dataset.disabled === 'true'\n )\n return;\n const editor = replacementEditor(root, id);\n clearing.get(id)?.();\n const stop = () => {\n observer.disconnect();\n view().clearTimeout(timeout);\n clearing.delete(id);\n };\n const ownsFocus = (replacement: HTMLElement) => {\n const active = root.ownerDocument.activeElement;\n return (\n active === editor ||\n active === element ||\n active === replacement ||\n active === root.ownerDocument.body\n );\n };\n const observer = new MutationObserver(() => {\n const replacement = replacementEditor(root, id);\n if (!replacement || replacement === editor) return;\n stop();\n if (ownsFocus(replacement)) placeTokenSearchCaret(replacement);\n });\n // Native clicks can drain microtasks between capture and bubble listeners.\n // Observe the actual controlled replacement before the app clears; a frame\n // is too late because the next shortcut-letter input may reach the page.\n observer.observe(root, { childList: true, subtree: true });\n const timeout = view().setTimeout(stop, 0);\n clearing.set(id, stop);\n setExpanded(id, true);\n const current = replacementEditor(root, id);\n // Keyboard activation may start on the clear button. Own the current\n // editor now, and its replacement at the mutation checkpoint. Expiration\n // only disconnects observation; it never moves a later caret or focus.\n if (current && ownsFocus(current)) placeTokenSearchCaret(current);\n },\n ),\n );\n }\n\n if (collapseOnEmptyBlur) {\n root.ownerDocument.addEventListener(\n 'pointerdown',\n trackPointerActivation,\n true,\n );\n root.ownerDocument.addEventListener(\n 'pointerup',\n clearPointerActivationAfterDefault,\n true,\n );\n root.ownerDocument.addEventListener(\n 'pointercancel',\n clearPointerActivation,\n true,\n );\n root.ownerDocument.addEventListener('click', clearPointerActivation, true);\n disposers.push(\n () =>\n root.ownerDocument.removeEventListener(\n 'pointerdown',\n trackPointerActivation,\n true,\n ),\n () =>\n root.ownerDocument.removeEventListener(\n 'pointerup',\n clearPointerActivationAfterDefault,\n true,\n ),\n () =>\n root.ownerDocument.removeEventListener(\n 'pointercancel',\n clearPointerActivation,\n true,\n ),\n () =>\n root.ownerDocument.removeEventListener(\n 'click',\n clearPointerActivation,\n true,\n ),\n );\n // Pressing an in-field control (clear, trailing, token, or the trigger) must not\n // blur the editor — otherwise the transient blur would collapse the field before\n // the control's own handler runs. Keeping focus also keeps the click firing.\n disposers.push(\n delegate(\n root,\n 'mousedown',\n '[data-component=\"token-search-field\"][data-collapsible=\"true\"] button',\n (event) => {\n event.preventDefault();\n },\n ),\n );\n disposers.push(\n delegate(\n root,\n 'focusout',\n '[data-token-search-editor]',\n (event, element) => {\n const editor = element as HTMLElement;\n const field = editor.closest<HTMLElement>(\n '[data-component=\"token-search-field\"]',\n );\n const id = field?.dataset.tokenSearchId;\n if (\n !id ||\n field?.dataset.collapsible !== 'true' ||\n field.dataset.disabled === 'true'\n )\n return;\n const relatedTarget = (event as FocusEvent).relatedTarget;\n const next =\n relatedTarget instanceof Element\n ? relatedTarget\n : pointerActivationTarget;\n if (!next && (clearing.has(id) || (manageFocus && deleting.has(id))))\n return;\n if (next instanceof Node && field.contains(next)) return;\n if (isExemptTarget(next instanceof Element ? next : null)) return;\n if (!editorIsEmpty(editor)) return;\n view().queueMicrotask(() => {\n const active = field.ownerDocument.activeElement;\n if (!field.contains(active) && !isExemptTarget(active))\n setExpanded(id, false);\n });\n },\n ),\n );\n }\n\n const dispose = () => {\n disposed = true;\n for (const stop of disposers.splice(0)) stop();\n };\n const handle = (() => dispose()) as TokenSearchFieldsHandle;\n handle.dispose = dispose;\n handle.expanded = (id) => (managed ? signalFor(id) : undefined);\n handle.open = (id) => {\n if (managed && !disposed) openField(id);\n };\n handle.close = (id) => {\n if (managed && !disposed) closeField(id);\n };\n return handle;\n}\n"]}
@@ -17,11 +17,16 @@ function entryKey(entry) {
17
17
  entry.action ?? "",
18
18
  entry.value ?? "",
19
19
  entry.disabled ? "1" : "0",
20
+ entry.checked ? "1" : "0",
21
+ entry.tone ?? "",
22
+ entry.disabledReason ?? "",
20
23
  String(entry.icon ?? ""),
21
- JSON.stringify(entry.attributes ?? {})
24
+ String(entry.details ?? ""),
25
+ JSON.stringify(entry.attributes ?? {}),
26
+ ...(entry.submenu ?? []).map(entryKey)
22
27
  ].join("");
23
28
  }
24
- function renderEntry(entry) {
29
+ function renderEntry(entry, nested = false) {
25
30
  if (entry.kind === "divider") return /* @__PURE__ */ jsx("wa-divider", {});
26
31
  if (entry.kind === "heading")
27
32
  return /* @__PURE__ */ jsx("div", { class: "kui-popup-menu__heading", children: entry.label });
@@ -29,16 +34,31 @@ function renderEntry(entry) {
29
34
  "wa-dropdown-item",
30
35
  {
31
36
  ...entry.attributes ?? {},
37
+ slot: nested ? "submenu" : void 0,
32
38
  "data-action": entry.action,
33
39
  value: entry.value,
40
+ type: entry.checked === void 0 ? void 0 : "checkbox",
41
+ checked: entry.checked,
42
+ variant: entry.tone === "danger" ? "danger" : void 0,
34
43
  disabled: entry.disabled,
44
+ title: entry.disabled ? entry.disabledReason : void 0,
35
45
  children: [
36
46
  entry.icon ? /* @__PURE__ */ jsx("span", { slot: "icon", class: "kui-popup-menu__icon", children: entry.icon }) : null,
37
- entry.label
47
+ entry.label,
48
+ entry.details ? /* @__PURE__ */ jsx("span", { slot: "details", class: "kui-popup-menu__details", children: entry.details }) : entry.submenu ? /* @__PURE__ */ jsx("span", { slot: "details" }) : null,
49
+ entry.submenu?.map((child) => renderEntry(child, true))
38
50
  ]
39
51
  }
40
52
  );
41
53
  }
54
+ function openPopupMenuAt(menu, x, y) {
55
+ menu.style.setProperty("--kui-popup-menu-context-x", `${x}px`);
56
+ menu.style.setProperty("--kui-popup-menu-context-y", `${y}px`);
57
+ menu.open = true;
58
+ }
59
+ function closePopupMenu(menu) {
60
+ menu.open = false;
61
+ }
42
62
  function PopupMenu({
43
63
  text,
44
64
  label,
@@ -48,7 +68,8 @@ function PopupMenu({
48
68
  caret = true,
49
69
  disabled = false,
50
70
  rootAttributes = {},
51
- slot
71
+ slot,
72
+ context = false
52
73
  }) {
53
74
  const key = `kui-popup-menu-${contentKey([
54
75
  text ?? "",
@@ -56,6 +77,7 @@ function PopupMenu({
56
77
  String(icon ?? ""),
57
78
  String(caret),
58
79
  String(disabled),
80
+ String(context),
59
81
  ...items.map(entryKey)
60
82
  ])}`;
61
83
  return /* @__PURE__ */ jsxs(
@@ -67,10 +89,21 @@ function PopupMenu({
67
89
  "data-component": "popup-menu",
68
90
  "data-key": key,
69
91
  "data-morph-skip-children": true,
92
+ "data-trigger": context ? "context" : "button",
70
93
  placement,
71
94
  slot,
72
95
  children: [
73
- /* @__PURE__ */ jsxs(
96
+ context ? /* @__PURE__ */ jsx(
97
+ "button",
98
+ {
99
+ type: "button",
100
+ slot: "trigger",
101
+ class: "kui-popup-menu__context-anchor",
102
+ "aria-label": label,
103
+ "aria-hidden": "true",
104
+ tabindex: -1
105
+ }
106
+ ) : /* @__PURE__ */ jsxs(
74
107
  "wa-button",
75
108
  {
76
109
  slot: "trigger",
@@ -83,12 +116,12 @@ function PopupMenu({
83
116
  ]
84
117
  }
85
118
  ),
86
- items.map(renderEntry)
119
+ items.map((entry) => renderEntry(entry))
87
120
  ]
88
121
  }
89
122
  );
90
123
  }
91
124
 
92
- export { PopupMenu };
125
+ export { PopupMenu, closePopupMenu, openPopupMenuAt };
93
126
 
94
- //# sourceMappingURL=chunk-WLG6SSNT.js.map
127
+ //# sourceMappingURL=chunk-UWONG4QE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/popup-menu.tsx"],"names":[],"mappings":"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","file":"chunk-UWONG4QE.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport type PopupMenuPlacement =\n 'bottom-start' | 'bottom' | 'bottom-end' | 'top-start' | 'top' | 'top-end';\n\ntype PopupMenuDataAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: never;\n 'data-component'?: never;\n 'data-key'?: never;\n 'data-morph-skip-children'?: never;\n }\n>;\n\n/** One command in the menu. */\nexport interface PopupMenuItem {\n kind?: 'item';\n label: string;\n /** Delegated `data-action` the app handles when the item is chosen. */\n action?: string;\n /** Native `wa-dropdown-item` value, reported by its `wa-select` event. */\n value?: string;\n /** Leading icon, typically a `LucideIcon`; it is placed in the item's icon slot. */\n icon?: SafeHtml;\n /** A checked menu choice, including nested choices. */\n checked?: boolean;\n /** Trailing safe content, such as a selected-choice tick. */\n details?: SafeHtml;\n /** Destructive command styling. */\n tone?: 'default' | 'danger';\n disabled?: boolean;\n /** Native tooltip text for a disabled command. */\n disabledReason?: string;\n /** Application `data-*` metadata such as a record id. */\n attributes?: PopupMenuDataAttributes;\n /** Child commands opened by hover or keyboard navigation. */\n submenu?: readonly PopupMenuItem[];\n}\n\n/** A labeled group heading; items that follow it belong to the group. */\nexport interface PopupMenuHeading {\n kind: 'heading';\n label: string;\n}\n\n/** A separator between groups of items. */\nexport interface PopupMenuDivider {\n kind: 'divider';\n}\n\nexport type PopupMenuEntry =\n PopupMenuItem | PopupMenuHeading | PopupMenuDivider;\n\ntype PopupMenuTriggerName =\n | {\n /** Visible trigger text, which is also its accessible name. */\n text: string;\n label?: never;\n }\n | {\n text?: never;\n /**\n * Accessible name of an icon-only trigger, rendered as visually hidden\n * slotted text (a Web Awesome button takes its name from its content).\n */\n label: string;\n };\n\ntype PopupMenuTrigger =\n | (PopupMenuTriggerName & { context?: false })\n | {\n context: true;\n label: string;\n text?: never;\n icon?: never;\n caret?: never;\n disabled?: never;\n };\n\nexport type PopupMenuProps = PopupMenuTrigger & {\n /** Trigger icon, typically a `LucideIcon`, before any visible text. */\n icon?: KerfUiContent;\n items: readonly PopupMenuEntry[];\n /** Where the menu opens relative to its trigger. Defaults to `bottom-start`. */\n placement?: PopupMenuPlacement;\n /** Show the disclosure caret after the trigger content. Defaults to true. */\n caret?: boolean;\n disabled?: boolean;\n /** Application `data-*` metadata on the menu root. */\n rootAttributes?: PopupMenuDataAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n};\n\n/** A short, stable FNV-1a digest of the trigger and item structure. */\nfunction contentKey(parts: readonly string[]): string {\n let hash = 0x811c9dc5;\n for (const character of parts.join('\\u0000')) {\n hash ^= character.codePointAt(0)!;\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0).toString(36);\n}\n\nfunction entryKey(entry: PopupMenuEntry): string {\n if (entry.kind === 'divider') return '-';\n if (entry.kind === 'heading') return `#${entry.label}`;\n return [\n entry.label,\n entry.action ?? '',\n entry.value ?? '',\n entry.disabled ? '1' : '0',\n entry.checked ? '1' : '0',\n entry.tone ?? '',\n entry.disabledReason ?? '',\n String(entry.icon ?? ''),\n String(entry.details ?? ''),\n JSON.stringify(entry.attributes ?? {}),\n ...(entry.submenu ?? []).map(entryKey),\n ].join('\\u0001');\n}\n\nfunction renderEntry(entry: PopupMenuEntry, nested = false) {\n if (entry.kind === 'divider') return <wa-divider></wa-divider>;\n // A group title styled like the Select's group title. It is not a slotted\n // h1-h6, whose Web Awesome group-label metrics are !important.\n if (entry.kind === 'heading')\n return <div class=\"kui-popup-menu__heading\">{entry.label}</div>;\n return (\n <wa-dropdown-item\n {...(entry.attributes ?? {})}\n slot={nested ? 'submenu' : undefined}\n data-action={entry.action}\n value={entry.value}\n type={entry.checked === undefined ? undefined : 'checkbox'}\n checked={entry.checked}\n variant={entry.tone === 'danger' ? 'danger' : undefined}\n disabled={entry.disabled}\n title={entry.disabled ? entry.disabledReason : undefined}\n >\n {entry.icon ? (\n <span slot=\"icon\" class=\"kui-popup-menu__icon\">\n {entry.icon}\n </span>\n ) : null}\n {entry.label}\n {entry.details ? (\n <span slot=\"details\" class=\"kui-popup-menu__details\">\n {entry.details}\n </span>\n ) : entry.submenu ? (\n <span slot=\"details\"></span>\n ) : null}\n {entry.submenu?.map((child) => renderEntry(child, true))}\n </wa-dropdown-item>\n );\n}\n\n/** A rendered context PopupMenu with Web Awesome's controlled open state. */\nexport type PopupMenuElement = HTMLElement & { open: boolean };\n\n/** Open a context PopupMenu at viewport pointer coordinates. */\nexport function openPopupMenuAt(\n menu: PopupMenuElement,\n x: number,\n y: number,\n): void {\n menu.style.setProperty('--kui-popup-menu-context-x', `${x}px`);\n menu.style.setProperty('--kui-popup-menu-context-y', `${y}px`);\n menu.open = true;\n}\n\n/** Close a programmatically opened PopupMenu. */\nexport function closePopupMenu(menu: PopupMenuElement): void {\n menu.open = false;\n}\n\n/**\n * An action menu: a trigger button that opens a list of commands. Renders the\n * `wa-dropdown` root directly, so a `single` `ToolbarControlGroup` (with\n * `nestedDropdown`) or a `PopupSurface` sizes and insets it as usual. Items\n * dispatch through delegated `data-action`s; the app owns the commands and any\n * open-state reaction. Import `@kerfjs/ui/popup-menu/register` once to register\n * the Web Awesome elements.\n */\nexport function PopupMenu({\n text,\n label,\n icon,\n items,\n placement = 'bottom-start',\n caret = true,\n disabled = false,\n rootAttributes = {},\n slot,\n context = false,\n}: PopupMenuProps) {\n // Web Awesome owns the trigger and item DOM once upgraded, so the morph\n // skips the children; the content key rebuilds the menu when they change.\n const key = `kui-popup-menu-${contentKey([\n text ?? '',\n label ?? '',\n String(icon ?? ''),\n String(caret),\n String(disabled),\n String(context),\n ...items.map(entryKey),\n ])}`;\n // size=\"m\" is Web Awesome's reflected default; rendering it keeps a\n // re-render's morph from stripping it and forcing a Lit update.\n return (\n <wa-dropdown\n size=\"m\"\n {...rootAttributes}\n class=\"kui-popup-menu\"\n data-component=\"popup-menu\"\n data-key={key}\n data-morph-skip-children\n data-trigger={context ? 'context' : 'button'}\n placement={placement}\n slot={slot}\n >\n {context ? (\n <button\n type=\"button\"\n slot=\"trigger\"\n class=\"kui-popup-menu__context-anchor\"\n aria-label={label}\n aria-hidden=\"true\"\n tabindex={-1}\n ></button>\n ) : (\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n with-caret={caret}\n disabled={disabled}\n >\n {icon}\n {text ? (\n <span>{text}</span>\n ) : (\n <span class=\"kui-popup-menu__label\">{label}</span>\n )}\n </wa-button>\n )}\n {items.map((entry) => renderEntry(entry))}\n </wa-dropdown>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { Text } from './chunk-24PHKUR3.js';
1
+ import { Text } from './chunk-UXT7TE6B.js';
2
2
  import { DisclosureArrow } from './chunk-KROD7KZK.js';
3
3
  import { Skeleton } from './chunk-AHEG27M7.js';
4
4
  import { Badge } from './chunk-MP2GDBQZ.js';
@@ -153,4 +153,4 @@ function ListHeader({
153
153
 
154
154
  export { ListHeader };
155
155
 
156
- //# sourceMappingURL=chunk-553ASUK6.js.map
156
+ //# sourceMappingURL=chunk-UX2VVXZ3.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/list-header.tsx"],"names":[],"mappings":"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","file":"chunk-553ASUK6.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Badge, type BadgeTone } from './badge.js';\nimport { em } from './css-values.js';\nimport { DisclosureArrow } from './disclosure-arrow.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\nimport { Text } from './text.js';\nimport type { HeadingLevel } from './toolbar-text.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-has-badge',\n 'data-has-count',\n 'data-density',\n 'data-divider',\n 'data-inline',\n 'data-width',\n 'data-indicator-tone',\n 'data-toggle',\n]);\nconst PROTECTED_TRIGGER_DATA_ATTRIBUTES = new Set([\n 'data-action',\n 'data-kui-disabled',\n]);\n\ntype ListHeaderRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-has-badge'?: never;\n 'data-has-count'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-inline'?: never;\n 'data-width'?: never;\n 'data-indicator-tone'?: never;\n 'data-toggle'?: never;\n }\n>;\n\ntype ListHeaderTriggerAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\ninterface ListHeaderBaseProps {\n label: string;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Shrink-wrap the header without its default outer margin, border, or padding. */\n inline?: boolean;\n /** Fill the available row or shrink-wrap while retaining normal header geometry. */\n width?: 'fill' | 'content';\n indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';\n /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */\n placeholder?: boolean;\n rootAttributes?: ListHeaderRootAttributes;\n triggerAttributes?: ListHeaderTriggerAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ntype ListHeaderModeProps =\n | {\n /** Render the title as a controlled disclosure trigger. */\n toggle: true;\n /** A toggle's label is its button text, not a heading. */\n headingLevel?: never;\n action: string;\n expanded: boolean;\n actionIcon?: SafeHtml;\n actionLabel?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a separately named trailing action. */\n toggle?: false;\n /**\n * Native heading level (`h1`–`h6`) of the label. Default `2`. Match the\n * document outline; the visual treatment does not change.\n */\n headingLevel?: HeadingLevel;\n action: string;\n actionLabel: string;\n actionIcon: SafeHtml;\n expanded?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a passive section heading. */\n toggle?: false;\n /**\n * Native heading level (`h1`–`h6`) of the label. Default `2`. Match the\n * document outline; the visual treatment does not change.\n */\n headingLevel?: HeadingLevel;\n action?: never;\n actionLabel?: never;\n actionIcon?: never;\n expanded?: never;\n actionDisabled?: never;\n disabledReason?: never;\n };\n\ntype ListHeaderIndicatorProps =\n | { count: number; countLabel: string; badge?: never; status?: never }\n | { count?: never; countLabel?: never; badge: SafeHtml; status?: never }\n | { count?: never; countLabel?: never; badge?: never; status?: SafeHtml };\n\nexport type ListHeaderProps = ListHeaderBaseProps &\n ListHeaderIndicatorProps &\n ListHeaderModeProps;\n\nexport function ListHeader({\n label,\n headingLevel = 2,\n count,\n countLabel,\n badge,\n status,\n density = 'standard',\n divider = 'none',\n inline = false,\n width = 'fill',\n indicatorTone = 'neutral',\n action,\n actionLabel,\n actionIcon,\n actionDisabled = false,\n disabledReason,\n expanded,\n toggle = false,\n placeholder = false,\n rootAttributes = {},\n triggerAttributes = {},\n slot,\n}: ListHeaderProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTriggerAttributes = filterControlAttributes(\n triggerAttributes,\n PROTECTED_TRIGGER_DATA_ATTRIBUTES,\n );\n const normalizedCount =\n typeof count === 'number' && Number.isSafeInteger(count) && count >= 0\n ? count\n : undefined;\n const normalizedCountLabel =\n normalizedCount === undefined\n ? undefined\n : typeof countLabel === 'string' && countLabel.trim()\n ? countLabel\n : String(normalizedCount);\n const renderedBadge =\n normalizedCount === undefined ? (status ?? badge) : undefined;\n const renderedActionIcon =\n actionIcon ??\n (toggle ? <DisclosureArrow open={Boolean(expanded)} /> : undefined);\n const accessibleLabel =\n normalizedCount === undefined\n ? undefined\n : `${label}, ${normalizedCountLabel}`;\n const badgeTone: BadgeTone =\n indicatorTone === 'accent' ? 'brand' : indicatorTone;\n const indicator = placeholder ? (\n (normalizedCount !== undefined || renderedBadge) && (\n <Badge size=\"compact\" tone={badgeTone}>\n <Skeleton width={em(1.75)} />\n </Badge>\n )\n ) : normalizedCount === undefined ? (\n renderedBadge && (\n <Badge size=\"compact\" tone={badgeTone}>\n {renderedBadge}\n </Badge>\n )\n ) : (\n <Badge size=\"compact\" tone={badgeTone} ariaHidden>\n {normalizedCount}\n </Badge>\n );\n const busy = placeholder ? ('true' as const) : undefined;\n if (toggle) {\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-width={width}\n data-indicator-tone={indicatorTone}\n data-toggle=\"true\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n slot={slot}\n >\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__title kui-list-header__toggle\"\n data-action={placeholder ? undefined : action}\n title={actionDisabled ? disabledReason : undefined}\n disabled={actionDisabled || placeholder || undefined}\n data-kui-disabled={actionDisabled ? 'true' : undefined}\n aria-label={accessibleLabel}\n aria-expanded={String(Boolean(expanded))}\n >\n <Text variant=\"span\">{label}</Text>\n {indicator}\n {renderedActionIcon && (\n <span class=\"kui-list-header__action-layer\">\n {renderedActionIcon}\n </span>\n )}\n </button>\n </header>\n );\n }\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-width={width}\n data-indicator-tone={indicatorTone}\n data-toggle=\"false\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n slot={slot}\n >\n <div class=\"kui-list-header__title\">\n <Text\n variant={`h${headingLevel}`}\n border=\"none\"\n aria-label={accessibleLabel}\n >\n {label}\n </Text>\n {indicator}\n </div>\n {action && (\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__action\"\n data-action={placeholder ? undefined : action}\n aria-label={actionLabel}\n title={actionDisabled ? disabledReason : actionLabel}\n disabled={actionDisabled || placeholder || undefined}\n data-kui-disabled={actionDisabled ? 'true' : undefined}\n >\n {renderedActionIcon}\n </button>\n )}\n </header>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/list-header.tsx"],"names":[],"mappings":";;;;;;;;AAaA,IAAM,8BAAA,uBAAqC,GAAA,CAAI;AAAA,EAC7C,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAC,CAAA;AACD,IAAM,iCAAA,uBAAwC,GAAA,CAAI;AAAA,EAChD,aAAA;AAAA,EACA;AACF,CAAC,CAAA;AAkGM,SAAS,UAAA,CAAW;AAAA,EACzB,KAAA;AAAA,EACA,YAAA,GAAe,CAAA;AAAA,EACf,KAAA;AAAA,EACA,UAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA,GAAU,UAAA;AAAA,EACV,OAAA,GAAU,MAAA;AAAA,EACV,MAAA,GAAS,KAAA;AAAA,EACT,KAAA,GAAQ,MAAA;AAAA,EACR,aAAA,GAAgB,SAAA;AAAA,EAChB,MAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA,GAAiB,KAAA;AAAA,EACjB,cAAA;AAAA,EACA,QAAA;AAAA,EACA,MAAA,GAAS,KAAA;AAAA,EACT,WAAA,GAAc,KAAA;AAAA,EACd,iBAAiB,EAAC;AAAA,EAClB,oBAAoB,EAAC;AAAA,EACrB;AACF,CAAA,EAAoB;AAClB,EAAA,MAAM,uBAAA,GAA0B,oBAAA;AAAA,IAC9B,cAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,0BAAA,GAA6B,uBAAA;AAAA,IACjC,iBAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,MAAM,eAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IAAY,MAAA,CAAO,cAAc,KAAK,CAAA,IAAK,KAAA,IAAS,CAAA,GACjE,KAAA,GACA,MAAA;AACN,EAAA,MAAM,oBAAA,GACJ,eAAA,KAAoB,MAAA,GAChB,MAAA,GACA,OAAO,UAAA,KAAe,QAAA,IAAY,UAAA,CAAW,IAAA,EAAK,GAChD,UAAA,GACA,MAAA,CAAO,eAAe,CAAA;AAC9B,EAAA,MAAM,aAAA,GACJ,eAAA,KAAoB,MAAA,GAAa,MAAA,IAAU,KAAA,GAAS,MAAA;AACtD,EAAA,MAAM,kBAAA,GACJ,eACC,MAAA,mBAAS,GAAA,CAAC,mBAAgB,IAAA,EAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG,CAAA,GAAK,MAAA,CAAA;AAC3D,EAAA,MAAM,kBACJ,eAAA,KAAoB,MAAA,GAChB,SACA,CAAA,EAAG,KAAK,KAAK,oBAAoB,CAAA,CAAA;AACvC,EAAA,MAAM,SAAA,GACJ,aAAA,KAAkB,QAAA,GAAW,OAAA,GAAU,aAAA;AACzC,EAAA,MAAM,YAAY,WAAA,GAAA,CACf,eAAA,KAAoB,MAAA,IAAa,aAAA,yBAC/B,KAAA,EAAA,EAAM,IAAA,EAAK,SAAA,EAAU,IAAA,EAAM,WAC1B,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,OAAO,EAAA,CAAG,IAAI,GAAG,CAAA,EAC7B,CAAA,GAEA,eAAA,KAAoB,MAAA,GACtB,iCACE,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAK,SAAA,EAAU,MAAM,SAAA,EACzB,QAAA,EAAA,aAAA,EACH,CAAA,mBAGF,GAAA,CAAC,SAAM,IAAA,EAAK,SAAA,EAAU,MAAM,SAAA,EAAW,UAAA,EAAU,MAC9C,QAAA,EAAA,eAAA,EACH,CAAA;AAEF,EAAA,MAAM,IAAA,GAAO,cAAe,MAAA,GAAmB,MAAA;AAC/C,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACE,GAAG,uBAAA;AAAA,QACJ,KAAA,EAAM,iBAAA;AAAA,QACN,gBAAA,EAAe,aAAA;AAAA,QACf,gBAAA,EAAgB,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAC,CAAA;AAAA,QAC7C,gBAAA,EAAgB,MAAA,CAAO,eAAA,KAAoB,MAAS,CAAA;AAAA,QACpD,cAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAc,OAAA;AAAA,QACd,aAAA,EAAa,OAAO,MAAM,CAAA;AAAA,QAC1B,YAAA,EAAY,KAAA;AAAA,QACZ,qBAAA,EAAqB,aAAA;AAAA,QACrB,aAAA,EAAY,MAAA;AAAA,QACZ,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,QACzC,WAAA,EAAW,IAAA;AAAA,QACX,IAAA;AAAA,QAEA,QAAA,kBAAA,IAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACE,GAAG,0BAAA;AAAA,YACJ,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,gDAAA;AAAA,YACN,aAAA,EAAa,cAAc,MAAA,GAAY,MAAA;AAAA,YACvC,KAAA,EAAO,iBAAiB,cAAA,GAAiB,MAAA;AAAA,YACzC,QAAA,EAAU,kBAAkB,WAAA,IAAe,MAAA;AAAA,YAC3C,mBAAA,EAAmB,iBAAiB,MAAA,GAAS,MAAA;AAAA,YAC7C,YAAA,EAAY,eAAA;AAAA,YACZ,eAAA,EAAe,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAC,CAAA;AAAA,YAEvC,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,OAAA,EAAQ,MAAA,EAAQ,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,cAC3B,SAAA;AAAA,cACA,kBAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,KAAA,EAAM,iCACT,QAAA,EAAA,kBAAA,EACH;AAAA;AAAA;AAAA;AAEJ;AAAA,KACF;AAAA,EAEJ;AACA,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,uBAAA;AAAA,MACJ,KAAA,EAAM,iBAAA;AAAA,MACN,gBAAA,EAAe,aAAA;AAAA,MACf,gBAAA,EAAgB,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAC,CAAA;AAAA,MAC7C,gBAAA,EAAgB,MAAA,CAAO,eAAA,KAAoB,MAAS,CAAA;AAAA,MACpD,cAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAc,OAAA;AAAA,MACd,aAAA,EAAa,OAAO,MAAM,CAAA;AAAA,MAC1B,YAAA,EAAY,KAAA;AAAA,MACZ,qBAAA,EAAqB,aAAA;AAAA,MACrB,aAAA,EAAY,OAAA;AAAA,MACZ,kBAAA,EAAkB,cAAc,MAAA,GAAS,MAAA;AAAA,MACzC,WAAA,EAAW,IAAA;AAAA,MACX,IAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,OAAM,wBAAA,EACT,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,IAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,IAAI,YAAY,CAAA,CAAA;AAAA,cACzB,MAAA,EAAO,MAAA;AAAA,cACP,YAAA,EAAY,eAAA;AAAA,cAEX,QAAA,EAAA;AAAA;AAAA,WACH;AAAA,UACC;AAAA,SAAA,EACH,CAAA;AAAA,QACC,MAAA,oBACC,GAAA;AAAA,UAAC,QAAA;AAAA,UAAA;AAAA,YACE,GAAG,0BAAA;AAAA,YACJ,IAAA,EAAK,QAAA;AAAA,YACL,KAAA,EAAM,yBAAA;AAAA,YACN,aAAA,EAAa,cAAc,MAAA,GAAY,MAAA;AAAA,YACvC,YAAA,EAAY,WAAA;AAAA,YACZ,KAAA,EAAO,iBAAiB,cAAA,GAAiB,WAAA;AAAA,YACzC,QAAA,EAAU,kBAAkB,WAAA,IAAe,MAAA;AAAA,YAC3C,mBAAA,EAAmB,iBAAiB,MAAA,GAAS,MAAA;AAAA,YAE5C,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,GAEJ;AAEJ","file":"chunk-UX2VVXZ3.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { Badge, type BadgeTone } from './badge.js';\nimport { em } from './css-values.js';\nimport { DisclosureArrow } from './disclosure-arrow.js';\nimport {\n filterControlAttributes,\n filterDataAttributes,\n} from './extension-attributes.js';\nimport { Skeleton } from './skeleton.js';\nimport { Text } from './text.js';\nimport type { HeadingLevel } from './toolbar-text.js';\n\nconst PROTECTED_ROOT_DATA_ATTRIBUTES = new Set([\n 'data-component',\n 'data-action',\n 'data-has-badge',\n 'data-has-count',\n 'data-density',\n 'data-divider',\n 'data-inline',\n 'data-width',\n 'data-indicator-tone',\n 'data-toggle',\n]);\nconst PROTECTED_TRIGGER_DATA_ATTRIBUTES = new Set([\n 'data-action',\n 'data-kui-disabled',\n]);\n\ntype ListHeaderRootAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-component'?: never;\n 'data-action'?: never;\n 'data-has-badge'?: never;\n 'data-has-count'?: never;\n 'data-density'?: never;\n 'data-divider'?: never;\n 'data-inline'?: never;\n 'data-width'?: never;\n 'data-indicator-tone'?: never;\n 'data-toggle'?: never;\n }\n>;\n\ntype ListHeaderTriggerAttributes = Readonly<\n Record<`data-${string}`, string | undefined> & {\n 'data-action'?: never;\n 'data-kui-disabled'?: never;\n popoverTarget?: string;\n popoverTargetAction?: 'toggle' | 'show' | 'hide';\n 'aria-controls'?: string;\n 'aria-haspopup'?: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | 'true';\n }\n>;\n\ninterface ListHeaderBaseProps {\n label: string;\n density?: 'standard' | 'compact';\n divider?: 'none' | 'before' | 'after' | 'both';\n /** Shrink-wrap the header without its default outer margin, border, or padding. */\n inline?: boolean;\n /** Fill the available row or shrink-wrap while retaining normal header geometry. */\n width?: 'fill' | 'content';\n indicatorTone?: 'neutral' | 'accent' | 'pop' | 'danger';\n /** Render as an unanimated loading skeleton: keep the label and action affordance, disable interaction. */\n placeholder?: boolean;\n rootAttributes?: ListHeaderRootAttributes;\n triggerAttributes?: ListHeaderTriggerAttributes;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\ntype ListHeaderModeProps =\n | {\n /** Render the title as a controlled disclosure trigger. */\n toggle: true;\n /** A toggle's label is its button text, not a heading. */\n headingLevel?: never;\n action: string;\n expanded: boolean;\n actionIcon?: SafeHtml;\n actionLabel?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a separately named trailing action. */\n toggle?: false;\n /**\n * Native heading level (`h1`–`h6`) of the label. Default `2`. Match the\n * document outline; the visual treatment does not change.\n */\n headingLevel?: HeadingLevel;\n action: string;\n actionLabel: string;\n actionIcon: SafeHtml;\n expanded?: never;\n actionDisabled?: boolean;\n disabledReason?: string;\n }\n | {\n /** Render a passive section heading. */\n toggle?: false;\n /**\n * Native heading level (`h1`–`h6`) of the label. Default `2`. Match the\n * document outline; the visual treatment does not change.\n */\n headingLevel?: HeadingLevel;\n action?: never;\n actionLabel?: never;\n actionIcon?: never;\n expanded?: never;\n actionDisabled?: never;\n disabledReason?: never;\n };\n\ntype ListHeaderIndicatorProps =\n | { count: number; countLabel: string; badge?: never; status?: never }\n | { count?: never; countLabel?: never; badge: SafeHtml; status?: never }\n | { count?: never; countLabel?: never; badge?: never; status?: SafeHtml };\n\nexport type ListHeaderProps = ListHeaderBaseProps &\n ListHeaderIndicatorProps &\n ListHeaderModeProps;\n\nexport function ListHeader({\n label,\n headingLevel = 2,\n count,\n countLabel,\n badge,\n status,\n density = 'standard',\n divider = 'none',\n inline = false,\n width = 'fill',\n indicatorTone = 'neutral',\n action,\n actionLabel,\n actionIcon,\n actionDisabled = false,\n disabledReason,\n expanded,\n toggle = false,\n placeholder = false,\n rootAttributes = {},\n triggerAttributes = {},\n slot,\n}: ListHeaderProps) {\n const extensionRootAttributes = filterDataAttributes(\n rootAttributes,\n PROTECTED_ROOT_DATA_ATTRIBUTES,\n );\n const extensionTriggerAttributes = filterControlAttributes(\n triggerAttributes,\n PROTECTED_TRIGGER_DATA_ATTRIBUTES,\n );\n const normalizedCount =\n typeof count === 'number' && Number.isSafeInteger(count) && count >= 0\n ? count\n : undefined;\n const normalizedCountLabel =\n normalizedCount === undefined\n ? undefined\n : typeof countLabel === 'string' && countLabel.trim()\n ? countLabel\n : String(normalizedCount);\n const renderedBadge =\n normalizedCount === undefined ? (status ?? badge) : undefined;\n const renderedActionIcon =\n actionIcon ??\n (toggle ? <DisclosureArrow open={Boolean(expanded)} /> : undefined);\n const accessibleLabel =\n normalizedCount === undefined\n ? undefined\n : `${label}, ${normalizedCountLabel}`;\n const badgeTone: BadgeTone =\n indicatorTone === 'accent' ? 'brand' : indicatorTone;\n const indicator = placeholder ? (\n (normalizedCount !== undefined || renderedBadge) && (\n <Badge size=\"compact\" tone={badgeTone}>\n <Skeleton width={em(1.75)} />\n </Badge>\n )\n ) : normalizedCount === undefined ? (\n renderedBadge && (\n <Badge size=\"compact\" tone={badgeTone}>\n {renderedBadge}\n </Badge>\n )\n ) : (\n <Badge size=\"compact\" tone={badgeTone} ariaHidden>\n {normalizedCount}\n </Badge>\n );\n const busy = placeholder ? ('true' as const) : undefined;\n if (toggle) {\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-width={width}\n data-indicator-tone={indicatorTone}\n data-toggle=\"true\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n slot={slot}\n >\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__title kui-list-header__toggle\"\n data-action={placeholder ? undefined : action}\n title={actionDisabled ? disabledReason : undefined}\n disabled={actionDisabled || placeholder || undefined}\n data-kui-disabled={actionDisabled ? 'true' : undefined}\n aria-label={accessibleLabel}\n aria-expanded={String(Boolean(expanded))}\n >\n <Text variant=\"span\">{label}</Text>\n {indicator}\n {renderedActionIcon && (\n <span class=\"kui-list-header__action-layer\">\n {renderedActionIcon}\n </span>\n )}\n </button>\n </header>\n );\n }\n return (\n <header\n {...extensionRootAttributes}\n class=\"kui-list-header\"\n data-component=\"list-header\"\n data-has-badge={String(Boolean(renderedBadge))}\n data-has-count={String(normalizedCount !== undefined)}\n data-density={density}\n data-divider={divider}\n data-inline={String(inline)}\n data-width={width}\n data-indicator-tone={indicatorTone}\n data-toggle=\"false\"\n data-placeholder={placeholder ? 'true' : undefined}\n aria-busy={busy}\n slot={slot}\n >\n <div class=\"kui-list-header__title\">\n <Text\n variant={`h${headingLevel}`}\n border=\"none\"\n aria-label={accessibleLabel}\n >\n {label}\n </Text>\n {indicator}\n </div>\n {action && (\n <button\n {...extensionTriggerAttributes}\n type=\"button\"\n class=\"kui-list-header__action\"\n data-action={placeholder ? undefined : action}\n aria-label={actionLabel}\n title={actionDisabled ? disabledReason : actionLabel}\n disabled={actionDisabled || placeholder || undefined}\n data-kui-disabled={actionDisabled ? 'true' : undefined}\n >\n {renderedActionIcon}\n </button>\n )}\n </header>\n );\n}\n"]}
@@ -30,4 +30,4 @@ function Text({
30
30
 
31
31
  export { Text };
32
32
 
33
- //# sourceMappingURL=chunk-24PHKUR3.js.map
33
+ //# sourceMappingURL=chunk-UXT7TE6B.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/text.tsx"],"names":[],"mappings":";;;AAsCO,SAAS,IAAA,CAAK;AAAA,EACnB,SAAS,OAAA,GAAU,GAAA;AAAA,EACnB,IAAA,GAAO,SAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,IAAA,GAAO,SAAA;AAAA,EACP,MAAA,GAAS,aAAA;AAAA,EACT,QAAA;AAAA,EACA,OAAO,UAAA,GAAa,EAAA;AAAA,EACpB,SAAA,GAAY,EAAA;AAAA,EACZ,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,MAAM,OAAA,GAAU,CAAC,UAAA,EAAY,UAAA,EAAY,SAAS,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC5E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACE,GAAG,UAAA;AAAA,MACJ,KAAA,EAAO,OAAA;AAAA,MACP,gBAAA,EAAe,MAAA;AAAA,MACf,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,IAAA;AAAA,MACX,aAAA,EAAa,MAAA;AAAA,MAEZ;AAAA;AAAA,GACH;AAEJ","file":"chunk-UXT7TE6B.js","sourcesContent":["import type { KerfBaseAttrs } from 'kerfjs/jsx-runtime';\n\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport type TextVariant =\n 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span';\nexport type TextTone = 'default' | 'quiet' | 'danger';\nexport type TextSize = 'compact' | 'default' | 'large' | 'xlarge';\nexport type TextFont = 'default' | 'monospace';\nexport type TextBorder = 'transparent' | 'none';\n\nexport type TextContent =\n KerfUiContent | string | number | readonly TextContent[];\n\nexport type TextProps = Omit<\n KerfBaseAttrs,\n 'children' | 'class' | 'className'\n> & {\n /** Native heading, paragraph, or inline span element to render. Defaults to `p`. */\n variant?: TextVariant;\n /** Semantic foreground treatment. Defaults to the inherited foreground. */\n tone?: TextTone;\n /** Text sizing independent of the native semantic element. */\n size?: TextSize;\n /** Font family independent of the native semantic element. */\n font?: TextFont;\n /** Transparent alignment border or no border when embedded in owner chrome. */\n border?: TextBorder;\n children: TextContent;\n class?: string;\n className?: string;\n};\n\n/**\n * Semantic heading, paragraph, or inline text. Block variants use the standard\n * content-item padding; `span` adds no box geometry.\n * All ordinary native heading/paragraph attributes pass through to the element.\n */\nexport function Text({\n variant: Variant = 'p',\n tone = 'default',\n size = 'default',\n font = 'default',\n border = 'transparent',\n children,\n class: classValue = '',\n className = '',\n ...attributes\n}: TextProps) {\n const classes = ['kui-text', classValue, className].filter(Boolean).join(' ');\n return (\n <Variant\n {...attributes}\n class={classes}\n data-component=\"text\"\n data-tone={tone}\n data-size={size}\n data-font={font}\n data-border={border}\n >\n {children}\n </Variant>\n );\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ToolbarText } from './chunk-XDKAYSVD.js';
2
- import { ToolbarControlGroup } from './chunk-ZIYOJFZD.js';
2
+ import { ToolbarControlGroup } from './chunk-7JUBXOIV.js';
3
3
  import { Toolbar } from './chunk-6YFHCLHG.js';
4
4
  import { LucideIcon } from './chunk-4R777DUZ.js';
5
5
  import { ChevronLeft } from 'lucide';
@@ -112,4 +112,4 @@ function NavStack({
112
112
 
113
113
  export { NavStack };
114
114
 
115
- //# sourceMappingURL=chunk-PWXNJS2B.js.map
115
+ //# sourceMappingURL=chunk-W4XKTST6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-PWXNJS2B.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from './toolbar-text.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n content: KerfUiContent;\n /** Title shown in the top toolbar for this view. */\n title?: string;\n /** Leading groups for this view's top toolbar, after the back control and before the title. */\n leading?: KerfUiContent;\n /** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */\n center?: KerfUiContent;\n /** Trailing actions for this view's top toolbar. */\n toolbar?: KerfUiContent;\n /** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */\n bottomToolbar?: KerfUiContent;\n}\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: KerfUiContent;\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `leading` / `center` / `toolbar`\n * content fills the zones, and `toolbarConfig` configures it. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n hideToolbar = false,\n bottomToolbar,\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={toolbarConfig.label}\n dividerSides={toolbarConfig.dividerSides}\n centerAlign={toolbarConfig.centerAlign}\n responsive={toolbarConfig.responsive}\n responsiveAt={toolbarConfig.responsiveAt}\n safeAreaEdges={\n toolbarConfig.safeAreaEdges ?? DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {top?.leading}\n <ToolbarText\n text={top?.title ?? ''}\n size={toolbarConfig.titleSize ?? 'large'}\n headingLevel={toolbarConfig.headingLevel}\n fill\n />\n </>\n }\n center={top?.center}\n trailing={top?.toolbar}\n />\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n aria-hidden={String(index !== topIndex)}\n >\n {view.content}\n </article>\n ))}\n </div>\n {(top?.bottomToolbar ?? bottomToolbar) && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n {top?.bottomToolbar ?? bottomToolbar}\n </footer>\n )}\n </section>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/nav-stack.tsx"],"names":[],"mappings":"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","file":"chunk-W4XKTST6.js","sourcesContent":["import { ChevronLeft } from 'lucide';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { KerfUiContent } from './semantic-content.js';\nimport { Toolbar, type ToolbarConfig } from './toolbar.js';\nimport { ToolbarControlGroup } from './toolbar-control-group.js';\nimport {\n type HeadingLevel,\n ToolbarText,\n type ToolbarTextSize,\n} from './toolbar-text.js';\n\n/**\n * One entry in a {@link NavStack}. The app owns the stack as an array (usually a\n * signal); `NavStack` renders it and `wireNavStack` animates the transitions.\n */\nexport interface NavStackView {\n /** Stable identity for keyed reconcile and transition direction. */\n key: string;\n content: KerfUiContent;\n /** Title shown in the top toolbar for this view. */\n title?: string;\n /** Leading groups for this view's top toolbar, after the back control and before the title. */\n leading?: KerfUiContent;\n /** Center content for this view's top toolbar (placed per `toolbarConfig.centerAlign`). */\n center?: KerfUiContent;\n /** Trailing actions for this view's top toolbar. */\n toolbar?: KerfUiContent;\n /** Bottom toolbar for this view. Cross-fades with the top chrome on navigation. */\n bottomToolbar?: KerfUiContent;\n}\n\n/**\n * The top toolbar's configuration. Its `ToolbarConfig` forwards to the real\n * `Toolbar` the stack renders; by default that toolbar draws no divider and\n * claims the top and side safe-area edges the stack still touches.\n */\nexport interface NavStackToolbarConfig extends ToolbarConfig {\n /** Accessible name of the top toolbar (default: none). */\n label?: string;\n /** Size of the view title's `ToolbarText` (default `large`). */\n titleSize?: ToolbarTextSize;\n /** Expose the view title as a heading at this level (default: a plain span). */\n headingLevel?: HeadingLevel;\n}\n\nexport interface NavStackProps {\n id: string;\n /** Accessible name for the stack region. */\n label: string;\n /** The stack, root first; the last entry is the active top view. */\n views: NavStackView[];\n /** Accessible label for the icon-only back control (default \"Back\"). */\n backLabel?: string;\n /** The back control's icon (default a chevron-left `LucideIcon`). */\n backIcon?: KerfUiContent;\n /**\n * Visible text beside the back icon, such as the previous view's title\n * (default: icon only). When set, the text names the control and\n * `backLabel` is not used.\n */\n backText?: string;\n /** The top toolbar's configuration, forwarded to its `Toolbar`. */\n toolbarConfig?: NavStackToolbarConfig;\n /** Hide the top toolbar entirely (rare — a fully custom-chrome view). */\n hideToolbar?: boolean;\n /** Optional persistent bottom toolbar used when the active view does not provide one. */\n bottomToolbar?: KerfUiContent;\n /**\n * The line under the top chrome and over the bottom toolbar, where they\n * meet the active view. `scroll` (default) shows the chrome's line only\n * while the view's content is scrolled beneath it, and the bottom\n * toolbar's only while more content lies below — never when the content\n * fits — once `wireScrollDividers` (`@kerfjs/ui/wire-scroll-dividers`) is\n * wired above the stack; unwired, neither shows. `always` shows both\n * without the wiring; `none` neither, even when wired. The line is drawn\n * inside the chrome, so no state moves the chrome or the content. A\n * `toolbarConfig.dividerSides` edge is the Toolbar's own and is unaffected.\n */\n chromeDividers?: 'scroll' | 'always' | 'none';\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\nconst DEFAULT_SAFE_AREA_EDGES = [\n 'block-start',\n 'inline-start',\n 'inline-end',\n] as const;\n\n/**\n * A navigation stack (iOS-style push/pop). Renders every entry stacked, the last\n * one active; `@kerfjs/ui/wire-nav-stack`'s `wireNavStack` slides the content and\n * cross-fades the chrome across a change. Its top chrome is a real `Toolbar`: the\n * back control and title lead, the active view's `leading` / `center` / `toolbar`\n * content fills the zones, and `toolbarConfig` configures it. A single-pane\n * layout is a `NavStack` with one entry. See `docs/23-app-layouts.md` §3.1.\n */\nexport function NavStack({\n id,\n label,\n views,\n backLabel = 'Back',\n backIcon,\n backText,\n toolbarConfig = {},\n hideToolbar = false,\n bottomToolbar,\n chromeDividers = 'scroll',\n className = '',\n slot,\n}: NavStackProps) {\n const topIndex = views.length - 1;\n const top = views[topIndex];\n const canPop = views.length > 1;\n return (\n <section\n class={`kui-nav-stack ${className}`.trim()}\n id={id}\n data-component=\"nav-stack\"\n data-nav-stack-id={id}\n data-depth={String(views.length)}\n data-chrome-dividers={\n chromeDividers === 'always' || chromeDividers === 'none'\n ? chromeDividers\n : undefined\n }\n aria-label={label}\n slot={slot}\n >\n {!hideToolbar && (\n <div class=\"kui-nav-stack__chrome\" data-nav-stack-chrome>\n <Toolbar\n label={toolbarConfig.label}\n dividerSides={toolbarConfig.dividerSides}\n centerAlign={toolbarConfig.centerAlign}\n responsive={toolbarConfig.responsive}\n responsiveAt={toolbarConfig.responsiveAt}\n safeAreaEdges={\n toolbarConfig.safeAreaEdges ?? DEFAULT_SAFE_AREA_EDGES\n }\n leading={\n <>\n {canPop && (\n <ToolbarControlGroup\n appearance=\"borderless\"\n shape=\"rounded\"\n content={backText ? 'mixed' : 'icon'}\n single\n >\n <button\n type=\"button\"\n class=\"kui-nav-stack__back\"\n data-nav-back\n aria-label={backText ? undefined : backLabel}\n >\n {backIcon ?? (\n <LucideIcon\n icon={ChevronLeft}\n name=\"chevron-left\"\n className=\"kui-nav-stack__back-icon\"\n />\n )}\n {backText ? <span>{backText}</span> : null}\n </button>\n </ToolbarControlGroup>\n )}\n {top?.leading}\n <ToolbarText\n text={top?.title ?? ''}\n size={toolbarConfig.titleSize ?? 'large'}\n headingLevel={toolbarConfig.headingLevel}\n fill\n />\n </>\n }\n center={top?.center}\n trailing={top?.toolbar}\n />\n </div>\n )}\n <div class=\"kui-nav-stack__viewport\" data-nav-stack-viewport>\n {views.map((view, index) => (\n <article\n class=\"kui-nav-stack__view\"\n data-key={view.key}\n data-nav-key={view.key}\n data-nav-active={String(index === topIndex)}\n aria-hidden={String(index !== topIndex)}\n >\n {view.content}\n </article>\n ))}\n </div>\n {(top?.bottomToolbar ?? bottomToolbar) && (\n <footer class=\"kui-nav-stack__bottom\" data-nav-stack-bottom>\n {top?.bottomToolbar ?? bottomToolbar}\n </footer>\n )}\n </section>\n );\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import { SafeHtml } from 'kerfjs';
2
2
  import { PaneConfig } from './pane.js';
3
- import { P as PanelSide, a as PanelToolbar, b as PanelToggle } from './panel-toolbar-BN4x0rth.js';
4
- export { c as collapsiblePanelToggleIcon } from './panel-toolbar-BN4x0rth.js';
3
+ import { P as PanelSide, a as PanelToolbar, b as PanelToggle } from './panel-toolbar-DqwtBxQL.js';
4
+ export { c as collapsiblePanelToggleIcon } from './panel-toolbar-DqwtBxQL.js';
5
5
  import { ResizableRegionSeparator, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionPresentation, ResizableRegionRestorePosition } from './resizable-region.js';
6
6
  import { K as KerfUiContent } from './semantic-content-BbzjvSu9.js';
7
7
  import './lucide-icon.js';
@@ -14,10 +14,10 @@ type CollapsiblePanelSide = PanelSide;
14
14
  /** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */
15
15
  type CollapsiblePanelToolbarToggle = PanelToggle;
16
16
  /**
17
- * A panel's composed top toolbar. `title` and `panelOnly` groups lead it and
18
- * are available only while the panel is open; `constant` groups and the
19
- * standard `toggle` trail it while open and move to the app's work-area
20
- * toolbar — through {@link CollapsiblePanelRelocated} — while it is collapsed.
17
+ * A panel's composed top toolbar. Its groups occupy `leading`, `center`, and
18
+ * `trailing` while open; groups marked `relocateOnCollapse` and the standard
19
+ * toggle move to the work-area toolbar through
20
+ * {@link CollapsiblePanelRelocated} while it is collapsed.
21
21
  */
22
22
  type CollapsiblePanelToolbar = PanelToolbar;
23
23
  interface CollapsiblePanelToggleProps {
@@ -60,7 +60,7 @@ interface CollapsiblePanelProps {
60
60
  * The panel's top toolbar, composed so its groups follow the panel's open
61
61
  * state. With it, `children` renders in a `Pane` below the toolbar; render
62
62
  * {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the
63
- * `constant` groups and toggle stay reachable while the panel is collapsed.
63
+ * marked groups and toggle stay reachable while the panel is collapsed.
64
64
  */
65
65
  toolbar?: CollapsiblePanelToolbar;
66
66
  /** Optional bottom toolbar under a `toolbar` panel's content. */
@@ -109,7 +109,7 @@ interface CollapsiblePanelRelocatedProps {
109
109
  toolbar: CollapsiblePanelToolbar;
110
110
  }
111
111
  /**
112
- * A collapsed {@link CollapsiblePanel}'s `constant` groups and standard
112
+ * A collapsed {@link CollapsiblePanel}'s marked groups and standard
113
113
  * toggle, for the app's work-area toolbar — nothing while the panel is open.
114
114
  * Put it first in the leading zone for a left rail, last in the trailing zone
115
115
  * for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`
@@ -1,5 +1,5 @@
1
- import { collapsiblePanelToggleIcon, composedPanelBody, relocatedPanelGroups } from './chunk-XCO6YCYM.js';
2
- export { collapsiblePanelToggleIcon } from './chunk-XCO6YCYM.js';
1
+ import { collapsiblePanelToggleIcon, composedPanelBody, relocatedPanelGroups } from './chunk-QPUPLNNB.js';
2
+ export { collapsiblePanelToggleIcon } from './chunk-QPUPLNNB.js';
3
3
 
4
4
 
5
5
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":"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","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n collapsiblePanelToggleIcon,\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type {\n ResizableRegionCollapseMotion,\n ResizableRegionContentOverflow,\n ResizableRegionPresentation,\n ResizableRegionRestorePosition,\n ResizableRegionSeparator,\n} from './resizable-region.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport { collapsiblePanelToggleIcon } from './panel-toolbar.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = PanelSide;\n\n/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */\nexport type CollapsiblePanelToolbarToggle = PanelToggle;\n\n/**\n * A panel's composed top toolbar. `title` and `panelOnly` groups lead it and\n * are available only while the panel is open; `constant` groups and the\n * standard `toggle` trail it while open and move to the app's work-area\n * toolbar — through {@link CollapsiblePanelRelocated} — while it is collapsed.\n */\nexport type CollapsiblePanelToolbar = PanelToolbar;\n\n/** A CollapsiblePanel toggle's `wireSidebar` hook. */\nconst toggleAttributes = (panelId: string): PanelToggleAttributes => ({\n 'data-collapsible-target': panelId,\n // Keyed, so the morph never reuses a (possibly focused) toggle's button for\n // another control as the toggle moves between toolbars.\n 'data-key': `${panelId}-toggle`,\n});\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n slot,\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n slot={slot}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: KerfUiContent;\n /**\n * The panel's top toolbar, composed so its groups follow the panel's open\n * state. With it, `children` renders in a `Pane` below the toolbar; render\n * {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the\n * `constant` groups and toggle stay reachable while the panel is collapsed.\n */\n toolbar?: CollapsiblePanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `children` renders as given.\n */\n pane?: PaneConfig;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /** Control shown while collapsed, in a safe-area-aware corner of the panel's container (not the viewport). */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). Bottom-drawer content stays anchored\n * to the panel's fixed bottom edge, so the track cannot move its layout origin\n * underneath the transform transition. A collapsed panel renders `inert` (with\n * `aria-hidden`), so neither Tab, pointer, nor assistive technology reaches\n * content that has slid out of view; its `restoreControl` renders outside the\n * panel and stays reachable.\n * The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n toolbar,\n footer,\n pane,\n separator = 'auto',\n collapseMotion = 'slide',\n contentOverflow = 'clip',\n presentation = 'inline',\n restoreControl,\n restorePosition = side === 'left' ? 'bottom-start' : 'bottom-end',\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <>\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n data-separator={separator}\n data-collapse-motion={collapseMotion}\n data-content-overflow={contentOverflow}\n data-presentation={presentation}\n aria-label={label || undefined}\n aria-hidden={\n collapsed || presentation === 'hidden' ? 'true' : undefined\n }\n inert={collapsed}\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">\n {toolbar\n ? composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes: toggleAttributes(id),\n pane,\n footer,\n content: children,\n })\n : children}\n </div>\n </aside>\n {collapsed && restoreControl && presentation !== 'hidden' && (\n <div\n class=\"kui-collapsible-panel__restore\"\n data-panel-restore={id}\n data-position={restorePosition}\n >\n {restoreControl}\n </div>\n )}\n </>\n );\n}\n\nexport interface CollapsiblePanelRelocatedProps {\n /** The panel's `id`. */\n panelId: string;\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state. */\n collapsed: boolean;\n /** The same `toolbar` the panel receives. */\n toolbar: CollapsiblePanelToolbar;\n}\n\n/**\n * A collapsed {@link CollapsiblePanel}'s `constant` groups and standard\n * toggle, for the app's work-area toolbar — nothing while the panel is open.\n * Put it first in the leading zone for a left rail, last in the trailing zone\n * for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`\n * `restoreControl`) for a bottom drawer. `wireSidebar` hands focus to it when\n * the panel closes from its own toggle.\n */\nexport function CollapsiblePanelRelocated({\n panelId,\n side,\n collapsed,\n toolbar,\n}: CollapsiblePanelRelocatedProps) {\n return (\n <>\n {relocatedPanelGroups(\n toolbar,\n side,\n collapsed,\n toggleAttributes(panelId),\n )}\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/collapsible-panel.tsx"],"names":[],"mappings":"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","file":"collapsible-panel.js","sourcesContent":["import type { SafeHtml } from 'kerfjs';\n\nimport { LucideIcon } from './lucide-icon.js';\nimport type { PaneConfig } from './pane.js';\nimport {\n collapsiblePanelToggleIcon,\n composedPanelBody,\n type PanelSide,\n type PanelToggle,\n type PanelToggleAttributes,\n type PanelToolbar,\n relocatedPanelGroups,\n} from './panel-toolbar.js';\nimport type {\n ResizableRegionCollapseMotion,\n ResizableRegionContentOverflow,\n ResizableRegionPresentation,\n ResizableRegionRestorePosition,\n ResizableRegionSeparator,\n} from './resizable-region.js';\nimport type { KerfUiContent } from './semantic-content.js';\n\nexport { collapsiblePanelToggleIcon } from './panel-toolbar.js';\n\n/** Which edge a {@link CollapsiblePanel} docks to. */\nexport type CollapsiblePanelSide = PanelSide;\n\n/** The standard toggle a panel toolbar renders (see {@link CollapsiblePanelToolbar}). */\nexport type CollapsiblePanelToolbarToggle = PanelToggle;\n\n/**\n * A panel's composed top toolbar. Its groups occupy `leading`, `center`, and\n * `trailing` while open; groups marked `relocateOnCollapse` and the standard\n * toggle move to the work-area toolbar through\n * {@link CollapsiblePanelRelocated} while it is collapsed.\n */\nexport type CollapsiblePanelToolbar = PanelToolbar;\n\n/** A CollapsiblePanel toggle's `wireSidebar` hook. */\nconst toggleAttributes = (panelId: string): PanelToggleAttributes => ({\n 'data-collapsible-target': panelId,\n // Keyed, so the morph never reuses a (possibly focused) toggle's button for\n // another control as the toggle moves between toolbars.\n 'data-key': `${panelId}-toggle`,\n});\n\nexport interface CollapsiblePanelToggleProps {\n /** The panel this toggle controls. */\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state (drives the icon direction). */\n collapsed: boolean;\n /** `data-action` the button carries so `wireSidebar` can delegate its click. */\n action: string;\n /** The panel id the button targets (`data-tab-panel`-style: `data-collapsible-panel`). */\n panelId?: string;\n /** Accessible label; defaults to \"Collapse\"/\"Expand\". */\n label?: string;\n className?: string;\n /** Native named-slot assignment when composed inside a web component. */\n slot?: string;\n}\n\n/**\n * A standard collapse/expand toggle button for a {@link CollapsiblePanel}: the\n * recognizable per-side icon (see {@link collapsiblePanelToggleIcon}) plus the\n * `data-action` / `aria-expanded` `wireSidebar` reads. Placement is the app's —\n * put it in the panel's own header (to collapse) and somewhere always-visible\n * (to expand while collapsed).\n */\nexport function CollapsiblePanelToggle({\n side,\n collapsed,\n action,\n panelId,\n label,\n className = '',\n slot,\n}: CollapsiblePanelToggleProps) {\n const glyph = collapsiblePanelToggleIcon(side, collapsed);\n const accessible = label ?? (collapsed ? 'Expand' : 'Collapse');\n return (\n <button\n type=\"button\"\n class={`kui-collapsible-panel__toggle ${className}`.trim()}\n data-action={action}\n data-collapsible-target={panelId}\n aria-expanded={String(!collapsed)}\n aria-label={accessible}\n slot={slot}\n >\n <LucideIcon icon={glyph.icon} name={glyph.name} />\n </button>\n );\n}\n\nexport interface CollapsiblePanelProps {\n /** A stable id for the panel — `wireSidebar` targets it and toggles reference it. */\n id: string;\n /** Which edge the panel docks to: a left/right rail or a bottom drawer. */\n side: CollapsiblePanelSide;\n /** Whether the panel is currently collapsed (the app owns this signal). */\n collapsed?: boolean;\n /** Rail width or drawer height in px. Overrides the CSS default. */\n size?: number;\n /** Accessible label for the panel region. */\n label?: string;\n /** Panel content. */\n children?: KerfUiContent;\n /**\n * The panel's top toolbar, composed so its groups follow the panel's open\n * state. With it, `children` renders in a `Pane` below the toolbar; render\n * {@link CollapsiblePanelRelocated} in the app's work-area toolbar so the\n * marked groups and toggle stay reachable while the panel is collapsed.\n */\n toolbar?: CollapsiblePanelToolbar;\n /** Optional bottom toolbar under a `toolbar` panel's content. */\n footer?: KerfUiContent;\n /**\n * Configuration for a `toolbar` panel's `Pane` (`contentElement`,\n * `contentLabel`, `separators`, `safeAreaEdges`, `chromeDividers`) — for example\n * `{ contentElement: 'nav', contentLabel: 'Sections' }` for a navigation\n * rail. Omitted or `undefined` fields keep the `Pane` defaults. Ignored\n * without a `toolbar`, where `children` renders as given.\n */\n pane?: PaneConfig;\n separator?: ResizableRegionSeparator;\n collapseMotion?: ResizableRegionCollapseMotion;\n contentOverflow?: ResizableRegionContentOverflow;\n presentation?: ResizableRegionPresentation;\n /** Control shown while collapsed, in a safe-area-aware corner of the panel's container (not the viewport). */\n restoreControl?: SafeHtml;\n restorePosition?: ResizableRegionRestorePosition;\n className?: string;\n}\n\n/**\n * A standalone collapsible side rail or bottom drawer, outside the full\n * {@link Workbench} shell. It owns only the presentation: a fixed-size content\n * area that stays laid out while the panel's track snaps to zero and the content\n * slides out via `transform` (one reflow, composited — the same technique\n * `Workbench` and the catalog sidebar use). Bottom-drawer content stays anchored\n * to the panel's fixed bottom edge, so the track cannot move its layout origin\n * underneath the transform transition. A collapsed panel renders `inert` (with\n * `aria-hidden`), so neither Tab, pointer, nor assistive technology reaches\n * content that has slid out of view; its `restoreControl` renders outside the\n * panel and stays reachable.\n * The app owns the `collapsed` signal;\n * pair it with `wireSidebar` for the toggle, focus, compact-overlay, keyboard,\n * and persistence semantics, and with `CollapsiblePanelToggle` for the standard\n * affordance. See `ui/docs/collapsible-panel.md` and `docs/23-app-layouts.md`.\n */\nexport function CollapsiblePanel({\n id,\n side,\n collapsed = false,\n size,\n label,\n children,\n toolbar,\n footer,\n pane,\n separator = 'auto',\n collapseMotion = 'slide',\n contentOverflow = 'clip',\n presentation = 'inline',\n restoreControl,\n restorePosition = side === 'left' ? 'bottom-start' : 'bottom-end',\n className = '',\n}: CollapsiblePanelProps) {\n const sizeVar =\n side === 'bottom'\n ? '--kui-collapsible-panel-height'\n : '--kui-collapsible-panel-width';\n return (\n <>\n <aside\n class={`kui-collapsible-panel kui-collapsible-panel--${side} ${className}`.trim()}\n data-component=\"collapsible-panel\"\n data-collapsible-panel={id}\n data-side={side}\n data-collapsed={String(collapsed)}\n data-separator={separator}\n data-collapse-motion={collapseMotion}\n data-content-overflow={contentOverflow}\n data-presentation={presentation}\n aria-label={label || undefined}\n aria-hidden={\n collapsed || presentation === 'hidden' ? 'true' : undefined\n }\n inert={collapsed}\n style={size ? `${sizeVar}: ${size}px` : undefined}\n >\n <div class=\"kui-collapsible-panel__content\">\n {toolbar\n ? composedPanelBody({\n toolbar,\n side,\n collapsed,\n attributes: toggleAttributes(id),\n pane,\n footer,\n content: children,\n })\n : children}\n </div>\n </aside>\n {collapsed && restoreControl && presentation !== 'hidden' && (\n <div\n class=\"kui-collapsible-panel__restore\"\n data-panel-restore={id}\n data-position={restorePosition}\n >\n {restoreControl}\n </div>\n )}\n </>\n );\n}\n\nexport interface CollapsiblePanelRelocatedProps {\n /** The panel's `id`. */\n panelId: string;\n side: CollapsiblePanelSide;\n /** The panel's current collapsed state. */\n collapsed: boolean;\n /** The same `toolbar` the panel receives. */\n toolbar: CollapsiblePanelToolbar;\n}\n\n/**\n * A collapsed {@link CollapsiblePanel}'s marked groups and standard\n * toggle, for the app's work-area toolbar — nothing while the panel is open.\n * Put it first in the leading zone for a left rail, last in the trailing zone\n * for a right rail, and last in a bottom toolbar (or a `FloatingToolbar`\n * `restoreControl`) for a bottom drawer. `wireSidebar` hands focus to it when\n * the panel closes from its own toggle.\n */\nexport function CollapsiblePanelRelocated({\n panelId,\n side,\n collapsed,\n toolbar,\n}: CollapsiblePanelRelocatedProps) {\n return (\n <>\n {relocatedPanelGroups(\n toolbar,\n side,\n collapsed,\n toggleAttributes(panelId),\n )}\n </>\n );\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ export { ListItem, ListItemProps } from './list-item.js';
15
15
  export { LoadingSpinner, LoadingSpinnerProps } from './loading-spinner.js';
16
16
  export { LucideIcon, LucideIconProps, LucideNode } from './lucide-icon.js';
17
17
  export { Pane, PaneChromeDividers, PaneChromePlacement, PaneConfig, PaneContentElement, PaneElement, PaneProps, PaneSeparatorSide } from './pane.js';
18
- export { PopupMenu, PopupMenuDivider, PopupMenuEntry, PopupMenuHeading, PopupMenuItem, PopupMenuPlacement, PopupMenuProps } from './popup-menu.js';
18
+ export { PopupMenu, PopupMenuDivider, PopupMenuElement, PopupMenuEntry, PopupMenuHeading, PopupMenuItem, PopupMenuPlacement, PopupMenuProps, closePopupMenu, openPopupMenuAt } from './popup-menu.js';
19
19
  export { ResizableRegion, ResizableRegionAxis, ResizableRegionCollapseMotion, ResizableRegionContentOverflow, ResizableRegionEdge, ResizableRegionPresentation, ResizableRegionProps, ResizableRegionResponsiveFillAt, ResizableRegionRestorePosition, ResizableRegionSeparator, clampRegionSize, resizeRegionFromPointer } from './resizable-region.js';
20
20
  export { Row, RowProps } from './row.js';
21
21
  export { SegmentedControl, SegmentedControlAppearance, SegmentedControlChoice, SegmentedControlLayout, SegmentedControlProps, SegmentedControlShape, SegmentedControlSize } from './segmented-control.js';
@@ -28,7 +28,7 @@ export { SunkenPanel, SunkenPanelProps, SunkenPanelShape } from './sunken-panel.
28
28
  export { DialogSurface, DialogSurfacePresentation, DialogSurfaceProps, DialogSurfaceSize, PopupSurface, PopupSurfaceInset, PopupSurfaceProps, SurfaceInset } from './surface-scaffold.js';
29
29
  export { TabActivation, TabBar, TabBarAllocation, TabBarPresentation, TabBarProps, TabBarTrailingPlacement } from './tab-bar.js';
30
30
  export { Text, TextContent, TextFont, TextProps, TextSize, TextTone, TextVariant } from './text.js';
31
- export { TokenSearchEditorAttributes, TokenSearchField, TokenSearchFieldProps, TokenSearchFieldValue, TokenSearchToken, placeTokenSearchCaret, readTokenSearchField } from './token-search-field.js';
31
+ export { T as TokenSearchEditorAttributes, a as TokenSearchField, b as TokenSearchFieldProps, c as TokenSearchFieldValue, d as TokenSearchModel, e as TokenSearchModelOptions, f as TokenSearchResolvedToken, g as TokenSearchRule, h as TokenSearchState, i as TokenSearchSuggestion, j as TokenSearchToken, k as createTokenSearchModel, p as placeTokenSearchCaret, r as readTokenSearchField } from './token-search-field-CCke1yvQ.js';
32
32
  export { Toolbar, ToolbarConfig, ToolbarProps } from './toolbar.js';
33
33
  export { ToolbarActionLink, ToolbarActionLinkProps, ToolbarControlGroup, ToolbarControlGroupAppearance, ToolbarControlGroupButtonAppearance, ToolbarControlGroupContent, ToolbarControlGroupDensity, ToolbarControlGroupMenuInset, ToolbarControlGroupOverflow, ToolbarControlGroupProps, ToolbarControlGroupSelectedChrome, ToolbarControlGroupSelectedTone, ToolbarControlGroupShape, ToolbarControlGroupSize, ToolbarControlGroupTone, ToolbarControlGroupVisibility } from './toolbar-control-group.js';
34
34
  export { HeadingLevel, ToolbarText, ToolbarTextProps, ToolbarTextSize } from './toolbar-text.js';