@vielzeug/refine 2.2.3 → 2.2.4

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 (136) hide show
  1. package/dist/accordion.cjs +1 -1
  2. package/dist/accordion.cjs.map +1 -1
  3. package/dist/accordion.js +2 -2
  4. package/dist/accordion.js.map +1 -1
  5. package/dist/carousel.cjs +25 -24
  6. package/dist/carousel.cjs.map +1 -1
  7. package/dist/carousel.js +125 -135
  8. package/dist/carousel.js.map +1 -1
  9. package/dist/combobox.cjs +14 -14
  10. package/dist/combobox.cjs.map +1 -1
  11. package/dist/combobox.js +88 -98
  12. package/dist/combobox.js.map +1 -1
  13. package/dist/content/carousel/carousel.d.ts.map +1 -1
  14. package/dist/content/list/_list-item-reveal.cjs +1 -1
  15. package/dist/content/list/_list-item-reveal.cjs.map +1 -1
  16. package/dist/content/list/_list-item-reveal.d.ts +3 -3
  17. package/dist/content/list/_list-item-reveal.d.ts.map +1 -1
  18. package/dist/content/list/_list-item-reveal.js +22 -22
  19. package/dist/content/list/_list-item-reveal.js.map +1 -1
  20. package/dist/content/list/list-item.d.ts.map +1 -1
  21. package/dist/core/focus.cjs +1 -1
  22. package/dist/core/focus.cjs.map +1 -1
  23. package/dist/core/focus.d.ts.map +1 -1
  24. package/dist/core/focus.js +21 -20
  25. package/dist/core/focus.js.map +1 -1
  26. package/dist/core/index.d.ts +2 -3
  27. package/dist/core/index.d.ts.map +1 -1
  28. package/dist/core/nav.cjs +1 -1
  29. package/dist/core/nav.cjs.map +1 -1
  30. package/dist/core/nav.d.ts +3 -62
  31. package/dist/core/nav.d.ts.map +1 -1
  32. package/dist/core/nav.js +41 -124
  33. package/dist/core/nav.js.map +1 -1
  34. package/dist/core/option-list.cjs +1 -1
  35. package/dist/core/option-list.cjs.map +1 -1
  36. package/dist/core/option-list.d.ts +5 -5
  37. package/dist/core/option-list.d.ts.map +1 -1
  38. package/dist/core/option-list.js +14 -13
  39. package/dist/core/option-list.js.map +1 -1
  40. package/dist/core/overlay.cjs +1 -1
  41. package/dist/core/overlay.cjs.map +1 -1
  42. package/dist/core/overlay.d.ts +0 -8
  43. package/dist/core/overlay.d.ts.map +1 -1
  44. package/dist/core/overlay.js +1 -3
  45. package/dist/core/overlay.js.map +1 -1
  46. package/dist/custom-elements.json +3397 -3452
  47. package/dist/drawer.cjs +6 -6
  48. package/dist/drawer.cjs.map +1 -1
  49. package/dist/drawer.js +65 -75
  50. package/dist/drawer.js.map +1 -1
  51. package/dist/feedback/skeleton/skeleton.d.ts.map +1 -1
  52. package/dist/feedback/toast/toast.d.ts.map +1 -1
  53. package/dist/grid.cjs +2 -2
  54. package/dist/grid.cjs.map +1 -1
  55. package/dist/grid.js +42 -41
  56. package/dist/grid.js.map +1 -1
  57. package/dist/layout/grid/grid.d.ts.map +1 -1
  58. package/dist/layout/navbar/navbar.d.ts.map +1 -1
  59. package/dist/layout/sidebar/sidebar.d.ts.map +1 -1
  60. package/dist/list-item.cjs +2 -6
  61. package/dist/list-item.cjs.map +1 -1
  62. package/dist/list-item.js +40 -39
  63. package/dist/list-item.js.map +1 -1
  64. package/dist/list.cjs +1 -1
  65. package/dist/list.cjs.map +1 -1
  66. package/dist/list.js +2 -2
  67. package/dist/list.js.map +1 -1
  68. package/dist/menu.cjs +5 -5
  69. package/dist/menu.cjs.map +1 -1
  70. package/dist/menu.js +59 -59
  71. package/dist/menu.js.map +1 -1
  72. package/dist/navbar.cjs +9 -9
  73. package/dist/navbar.cjs.map +1 -1
  74. package/dist/navbar.js +124 -116
  75. package/dist/navbar.js.map +1 -1
  76. package/dist/otp-input.cjs +1 -1
  77. package/dist/otp-input.cjs.map +1 -1
  78. package/dist/otp-input.js +2 -2
  79. package/dist/otp-input.js.map +1 -1
  80. package/dist/overlay/drawer/drawer.d.ts.map +1 -1
  81. package/dist/overlay/menu/menu.d.ts.map +1 -1
  82. package/dist/radio-group.cjs +1 -1
  83. package/dist/radio-group.cjs.map +1 -1
  84. package/dist/radio-group.js +2 -3
  85. package/dist/radio-group.js.map +1 -1
  86. package/dist/radio.cjs +1 -1
  87. package/dist/radio.cjs.map +1 -1
  88. package/dist/radio.js +12 -11
  89. package/dist/radio.js.map +1 -1
  90. package/dist/rating.cjs +1 -1
  91. package/dist/rating.cjs.map +1 -1
  92. package/dist/rating.js +1 -1
  93. package/dist/rating.js.map +1 -1
  94. package/dist/refine.cjs +188 -195
  95. package/dist/refine.cjs.map +1 -1
  96. package/dist/refine.iife.js +212 -219
  97. package/dist/refine.iife.js.map +1 -1
  98. package/dist/refine.js +392 -399
  99. package/dist/refine.js.map +1 -1
  100. package/dist/select.cjs +1 -1
  101. package/dist/select.cjs.map +1 -1
  102. package/dist/select.js +1 -0
  103. package/dist/select.js.map +1 -1
  104. package/dist/sidebar.cjs +16 -16
  105. package/dist/sidebar.cjs.map +1 -1
  106. package/dist/sidebar.js +106 -91
  107. package/dist/sidebar.js.map +1 -1
  108. package/dist/skeleton.cjs +3 -3
  109. package/dist/skeleton.cjs.map +1 -1
  110. package/dist/skeleton.js +8 -7
  111. package/dist/skeleton.js.map +1 -1
  112. package/dist/stepper.cjs +1 -1
  113. package/dist/stepper.cjs.map +1 -1
  114. package/dist/stepper.js +3 -3
  115. package/dist/stepper.js.map +1 -1
  116. package/dist/tabs.cjs +1 -1
  117. package/dist/tabs.cjs.map +1 -1
  118. package/dist/tabs.js +4 -5
  119. package/dist/tabs.js.map +1 -1
  120. package/dist/toast.cjs +13 -17
  121. package/dist/toast.cjs.map +1 -1
  122. package/dist/toast.js +86 -85
  123. package/dist/toast.js.map +1 -1
  124. package/package.json +9 -6
  125. package/dist/core/swipe.cjs +0 -2
  126. package/dist/core/swipe.cjs.map +0 -1
  127. package/dist/core/swipe.d.ts +0 -40
  128. package/dist/core/swipe.d.ts.map +0 -1
  129. package/dist/core/swipe.js +0 -63
  130. package/dist/core/swipe.js.map +0 -1
  131. package/dist/core/typeahead.cjs +0 -2
  132. package/dist/core/typeahead.cjs.map +0 -1
  133. package/dist/core/typeahead.d.ts +0 -53
  134. package/dist/core/typeahead.d.ts.map +0 -1
  135. package/dist/core/typeahead.js +0 -23
  136. package/dist/core/typeahead.js.map +0 -1
package/dist/core/nav.cjs CHANGED
@@ -1,2 +1,2 @@
1
- const e=require("./keyboard.cjs"),t=require("./typeahead.cjs");let n=require("@vielzeug/ripple");var r=(e,t,n)=>{for(let r=t;r<e.length;r++)if(n(e[r],r))return r;return-1},i=(e,t,n)=>{for(let r=t;r>=0;r--)if(n(e[r],r))return r;return-1},a={both:{first:[`Home`],last:[`End`],next:[`ArrowDown`,`ArrowRight`],prev:[`ArrowUp`,`ArrowLeft`]},horizontal:{first:[`Home`],last:[`End`],next:[`ArrowRight`],prev:[`ArrowLeft`]},vertical:{first:[`Home`],last:[`End`],next:[`ArrowDown`],prev:[`ArrowUp`]}},o={both:{first:[`Home`],last:[`End`],next:[`ArrowDown`,`ArrowLeft`],prev:[`ArrowUp`,`ArrowRight`]},horizontal:{first:[`Home`],last:[`End`],next:[`ArrowLeft`],prev:[`ArrowRight`]},vertical:a.vertical},s=e=>typeof e==`object`&&!!e&&`disabled`in e,c=c=>{let l=(0,n.signal)(-1),u=(e,t)=>c.isItemDisabled?.(e,t)??(s(e)?e.disabled:!1),d=(e,t,n)=>(e>=0&&(l.value=e,c.onNavigate?.(t,e,n)),e),f=(e,t,n)=>n===`forward`?r(e,t,(e,t)=>!u(e,t)):i(e,t,(e,t)=>!u(e,t)),p=e=>{if(e<0)return _(),-1;let t=c.getItems();if(!t.length)return-1;let n=Math.min(e,t.length-1);return u(t[n],n)?-1:(l.value=n,n)},m=(e,t)=>{let n=c.getItems(),r=l.value;if(!n.length)return-1;let i=r<0?e===`forward`?0:n.length-1:e===`forward`?r+1:r-1,a=f(n,i,e),o=e===`forward`?`next`:`prev`;if(a>=0)return d(a,o,t);if(c.loop){let r=e===`forward`?0:n.length-1,i=f(n,r,e);if(i>=0)return d(i,o,t)}return r},h=e=>{let t=c.getItems();if(!t.length)return-1;if(e===`first`){let e=f(t,0,`forward`);return d(e,`first`)}if(e===`last`){let e=f(t,t.length-1,`backward`);return d(e,`last`)}return m(e===`next`?`forward`:`backward`)},g=()=>{let e=c.getItems(),t=l.value;return t>=0&&t<e.length?e[t]:void 0},_=()=>{l.value=-1},v=()=>!!c.disabled?.value,y=()=>typeof c.orientation==`function`?c.orientation():c.orientation??`vertical`,b=()=>typeof c.direction==`function`?c.direction():c.direction??`ltr`,x=()=>{let e=c.keys,t=(b()===`rtl`?o:a)[y()],n={first:e?.first??t.first,last:e?.last??t.last,next:e?.next??t.next,prev:e?.prev??t.prev},r={};for(let e of[`next`,`prev`,`first`,`last`])for(let t of n[e])r[t]=t=>{if(e===`first`||e===`last`){let n=c.getItems();if(!n.length)return;let r=e===`first`?f(n,0,`forward`):f(n,n.length-1,`backward`);d(r,e,t)}else m(e===`next`?`forward`:`backward`,t)};return r},S=c.getItemLabel?t.createTypeahead({getIndex:()=>l.value,getItemLabel:c.getItemLabel,getItems:c.getItems,isItemDisabled:(e,t)=>u(e,t),onNavigate:(e,t)=>{v()||(l.value=e,c.onNavigate?.(`typeahead`,e,t))}}):null,C=typeof c.orientation==`function`||typeof c.direction==`function`?null:x(),w=t=>{let n=C??x();return e.dispatchKeyboardAction(t,{disabled:c.disabled,keymap:n})?!0:S?.handleKeydown(t)??!1},T=!1,E=()=>{T||(T=!0,S?.reset())};return c.signal&&c.signal.addEventListener(`abort`,E,{once:!0}),{dispose:E,get disposed(){return T},focusedIndex:l,getActiveItem:g,handleKeydown:w,navigate:h,reset:_,set:p,[Symbol.dispose]:E}};exports.createListControl=c;
1
+ let e=require("@vielzeug/ripple"),t=require("@vielzeug/focus");var n=n=>{let r=(0,e.signal)(-1),i,a=(0,t.createListNavigation)({direction:n.direction,disabled:()=>!!n.disabled?.value,getItems:n.getItems,isItemDisabled:n.isItemDisabled,keys:n.keys,loop:n.loop,onNavigate:e=>{r.value=e.index,n.onNavigate?.(e)},orientation:n.orientation,typeahead:n.typeahead}),o=()=>{r.value=a.getIndex()},s=e=>{let t=a.set(e);return o(),t},c=e=>{let t=a.navigate(e);return o(),t},l=()=>{a.reset(),o()},u=e=>{let t=a.handleKeydown(e);return o(),t},d=()=>{a.dispose(),o(),i?.(),i=void 0};return n.signal?.aborted?d():n.signal&&(n.signal?.addEventListener(`abort`,d,{once:!0}),i=()=>n.signal?.removeEventListener(`abort`,d)),{dispose:d,get disposed(){return a.disposed},focusedIndex:r,getActiveItem:()=>a.getActiveItem(),handleKeydown:u,navigate:c,reset:l,set:s,[Symbol.dispose]:d}};exports.createListControl=n;
2
2
  //# sourceMappingURL=nav.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav.cjs","names":[],"sources":["../../src/core/nav.ts"],"sourcesContent":["import { type Readable, signal } from '@vielzeug/ripple';\n\nimport { dispatchKeyboardAction } from './keyboard';\nimport { createTypeahead } from './typeahead';\n\n// ── Private array search helpers ────────────────────────────────────────────\nconst findForward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\nconst findBackward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/**\n * Arrow-key and Home/End navigation actions. Separate from `ListKeyAction` so\n * keymap declarations never need `Exclude<ListKeyAction, 'typeahead'>`.\n */\nexport type ListNavigationAction = 'first' | 'last' | 'next' | 'prev';\n\n/**\n * All possible navigation action names, including `'typeahead'` (character-key\n * search). Used in `onNavigate` callbacks where both nav and typeahead are valid.\n */\nexport type ListKeyAction = ListNavigationAction | 'typeahead';\n\n/**\n * Orientation-aware default key bindings for list navigation.\n * - `'vertical'` (default): Up/Down arrows, Home/End\n * - `'horizontal'`: Left/Right arrows, Home/End\n * - `'both'`: all four arrow keys + Home/End\n */\nconst DEFAULT_KEYS: Record<'both' | 'horizontal' | 'vertical', Record<ListNavigationAction, string[]>> = {\n both: { first: ['Home'], last: ['End'], next: ['ArrowDown', 'ArrowRight'], prev: ['ArrowUp', 'ArrowLeft'] },\n horizontal: { first: ['Home'], last: ['End'], next: ['ArrowRight'], prev: ['ArrowLeft'] },\n vertical: { first: ['Home'], last: ['End'], next: ['ArrowDown'], prev: ['ArrowUp'] },\n};\n\n/**\n * RTL mirror of `DEFAULT_KEYS`'s horizontal component (per WAI-ARIA APG — tabs/radiogroup\n * flip Left/Right in `dir=\"rtl\"` so \"next\" always advances in reading order, not screen-space\n * direction). Only the Left/Right bindings differ; Home/End and the vertical arrows are\n * direction-independent and stay identical to `DEFAULT_KEYS`.\n */\nconst DEFAULT_KEYS_RTL: Record<'both' | 'horizontal' | 'vertical', Record<ListNavigationAction, string[]>> = {\n both: { first: ['Home'], last: ['End'], next: ['ArrowDown', 'ArrowLeft'], prev: ['ArrowUp', 'ArrowRight'] },\n horizontal: { first: ['Home'], last: ['End'], next: ['ArrowLeft'], prev: ['ArrowRight'] },\n vertical: DEFAULT_KEYS.vertical,\n};\n\nexport type ListNavigationOptions<T> = {\n /**\n * Text direction, used to mirror the default Left/Right arrow-key bindings for\n * `'horizontal'`/`'both'` orientation (WAI-ARIA APG: `dir=\"rtl\"` flips which arrow key\n * means \"next\" vs \"prev\"). Pass a getter for dynamic/reactive direction (e.g. derived from\n * `elementDirection(getHost())`, since a `dir` ancestor attribute can change at runtime).\n * Has no effect when an explicit `keys` override is provided. Defaults to `'ltr'`.\n */\n direction?: 'ltr' | 'rtl' | (() => 'ltr' | 'rtl');\n disabled?: Readable<boolean | undefined>;\n /**\n * Returns a plain-text label for an item used by typeahead search.\n * When provided, pressing a printable character key jumps to the first enabled\n * item whose label starts with the accumulated type buffer (500 ms reset window).\n * Omit for contexts where the host element is a text input (e.g. combobox).\n */\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n /** Override default key bindings for navigation actions. */\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n /**\n * Called when navigation lands on a new index.\n * `event` is the originating `KeyboardEvent`, or `undefined` for programmatic navigation.\n * Use to sync side-effects such as focusing a DOM element.\n */\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n /**\n * Axis the list navigates along. Controls which arrow keys are treated as\n * `next`/`prev` when no explicit `keys` override is provided.\n * Pass a getter function for dynamic/reactive orientation (e.g. driven by a prop signal).\n *\n * - `'vertical'` (default): ↑↓ arrows\n * - `'horizontal'`: ←→ arrows\n * - `'both'`: all four arrow keys\n */\n orientation?: 'both' | 'horizontal' | 'vertical' | (() => 'both' | 'horizontal' | 'vertical');\n /** `AbortSignal` from the component lifecycle. Disposes typeahead timer on abort. */\n signal?: AbortSignal;\n};\n\nexport type ListControl<T> = {\n [Symbol.dispose](): void;\n /** Disposes the internal typeahead timer. Alias for `dispose()`. Conforms to the monorepo disposal convention. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** Current focused index. `-1` when nothing is focused. */\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n /**\n * Programmatically navigate to a named position.\n * Always fires `onNavigate` — consistent with keyboard navigation.\n * Returns the resolved index, or `-1` if no enabled item was found.\n */\n navigate(action: ListNavigationAction): number;\n /** Reset focused index to `-1`. */\n reset(): void;\n /**\n * Set focus to the item at `index`. Returns the resolved index.\n * Pass a negative index to clear focus (same as `reset()`).\n */\n set(index: number): number;\n};\n\nconst hasDisabledProp = (item: unknown): item is { disabled: boolean } =>\n typeof item === 'object' && item !== null && 'disabled' in item;\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const _index = signal(-1);\n\n const isItemDisabled = (item: T, index: number): boolean =>\n options.isItemDisabled?.(item, index) ?? (hasDisabledProp(item) ? item.disabled : false);\n\n const commitIndex = (idx: number, action: ListKeyAction, event?: KeyboardEvent): number => {\n if (idx >= 0) {\n _index.value = idx;\n options.onNavigate?.(action, idx, event);\n }\n\n return idx;\n };\n\n const findEnabledIndex = (items: T[], start: number, direction: 'forward' | 'backward'): number => {\n if (direction === 'forward') return findForward(items, start, (item, i) => !isItemDisabled(item, i));\n\n return findBackward(items, start, (item, i) => !isItemDisabled(item, i));\n };\n\n const set = (index: number): number => {\n if (index < 0) {\n reset();\n\n return -1;\n }\n\n const items = options.getItems();\n\n if (!items.length) return -1;\n\n const clamped = Math.min(index, items.length - 1);\n\n if (isItemDisabled(items[clamped], clamped)) return -1;\n\n _index.value = clamped;\n\n return clamped;\n };\n\n const move = (direction: 'forward' | 'backward', event?: KeyboardEvent): number => {\n const items = options.getItems();\n const current = _index.value;\n\n if (!items.length) return -1;\n\n const start: number =\n current < 0\n ? direction === 'forward'\n ? 0\n : items.length - 1\n : direction === 'forward'\n ? current + 1\n : current - 1;\n const idx = findEnabledIndex(items, start, direction);\n const action: ListNavigationAction = direction === 'forward' ? 'next' : 'prev';\n\n if (idx >= 0) return commitIndex(idx, action, event);\n\n if (options.loop) {\n const wrapStart = direction === 'forward' ? 0 : items.length - 1;\n const wrapped = findEnabledIndex(items, wrapStart, direction);\n\n if (wrapped >= 0) return commitIndex(wrapped, action, event);\n }\n\n return current;\n };\n\n const navigate = (action: ListNavigationAction): number => {\n const items = options.getItems();\n\n if (!items.length) return -1;\n\n if (action === 'first') {\n const idx = findEnabledIndex(items, 0, 'forward');\n\n return commitIndex(idx, 'first');\n }\n\n if (action === 'last') {\n const idx = findEnabledIndex(items, items.length - 1, 'backward');\n\n return commitIndex(idx, 'last');\n }\n\n return move(action === 'next' ? 'forward' : 'backward');\n };\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = _index.value;\n\n return index >= 0 && index < items.length ? items[index] : undefined;\n };\n\n const reset = (): void => {\n _index.value = -1;\n };\n\n // ── Keyboard handling ──────────────────────────────────────────────────────\n\n const isKeyDisabled = (): boolean => Boolean(options.disabled?.value);\n\n const resolveOrientation = (): 'both' | 'horizontal' | 'vertical' =>\n typeof options.orientation === 'function' ? options.orientation() : (options.orientation ?? 'vertical');\n\n const resolveDirection = (): 'ltr' | 'rtl' =>\n typeof options.direction === 'function' ? options.direction() : (options.direction ?? 'ltr');\n\n const buildKeymap = (): Record<string, (keyboardEvent: KeyboardEvent) => void> => {\n const keys = options.keys;\n const keyTable = resolveDirection() === 'rtl' ? DEFAULT_KEYS_RTL : DEFAULT_KEYS;\n const orientationDefaults = keyTable[resolveOrientation()];\n const resolved = {\n first: keys?.first ?? orientationDefaults.first,\n last: keys?.last ?? orientationDefaults.last,\n next: keys?.next ?? orientationDefaults.next,\n prev: keys?.prev ?? orientationDefaults.prev,\n };\n const km: Record<string, (keyboardEvent: KeyboardEvent) => void> = {};\n\n for (const action of ['next', 'prev', 'first', 'last'] as const) {\n for (const key of resolved[action]) {\n km[key] = (keyboardEvent: KeyboardEvent) => {\n if (action === 'first' || action === 'last') {\n const items = options.getItems();\n\n if (!items.length) return;\n\n const idx =\n action === 'first'\n ? findEnabledIndex(items, 0, 'forward')\n : findEnabledIndex(items, items.length - 1, 'backward');\n\n commitIndex(idx, action, keyboardEvent);\n } else {\n move(action === 'next' ? 'forward' : 'backward', keyboardEvent);\n }\n };\n }\n }\n\n return km;\n };\n\n // ── Typeahead ──────────────────────────────────────────────────────────────\n\n const typeahead = options.getItemLabel\n ? createTypeahead({\n getIndex: () => _index.value,\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: (item, index) => isItemDisabled(item, index),\n onNavigate: (index, event) => {\n if (!isKeyDisabled()) {\n _index.value = index;\n options.onNavigate?.('typeahead', index, event);\n }\n },\n })\n : null;\n\n // Keymap depends on both orientation and direction — if either is dynamic, rebuild on every\n // keydown instead of caching once.\n const isDynamicKeymap = typeof options.orientation === 'function' || typeof options.direction === 'function';\n const _staticKeymap: Record<string, (e: KeyboardEvent) => void> | null = isDynamicKeymap ? null : buildKeymap();\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const km = _staticKeymap ?? buildKeymap();\n\n if (dispatchKeyboardAction(event, { disabled: options.disabled, keymap: km })) return true;\n\n return typeahead?.handleKeydown(event) ?? false;\n };\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n typeahead?.reset();\n };\n\n if (options.signal) {\n options.signal.addEventListener('abort', dispose, { once: true });\n }\n\n return {\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: _index,\n getActiveItem,\n handleKeydown,\n navigate,\n reset,\n set,\n [Symbol.dispose]: dispose,\n };\n};\n"],"mappings":"iGAMA,IAAM,GAAkB,EAAY,EAAe,IAA2D,CAC5G,IAAK,IAAI,EAAM,EAAO,EAAM,EAAM,OAAQ,IACxC,GAAI,EAAU,EAAM,GAAM,CAAG,EAAG,OAAO,EAGzC,MAAO,EACT,EAEM,GAAmB,EAAY,EAAe,IAA2D,CAC7G,IAAK,IAAI,EAAM,EAAO,GAAO,EAAG,IAC9B,GAAI,EAAU,EAAM,GAAM,CAAG,EAAG,OAAO,EAGzC,MAAO,EACT,EAsBM,EAAmG,CACvG,KAAM,CAAE,MAAO,CAAC,MAAM,EAAG,KAAM,CAAC,KAAK,EAAG,KAAM,CAAC,YAAa,YAAY,EAAG,KAAM,CAAC,UAAW,WAAW,CAAE,EAC1G,WAAY,CAAE,MAAO,CAAC,MAAM,EAAG,KAAM,CAAC,KAAK,EAAG,KAAM,CAAC,YAAY,EAAG,KAAM,CAAC,WAAW,CAAE,EACxF,SAAU,CAAE,MAAO,CAAC,MAAM,EAAG,KAAM,CAAC,KAAK,EAAG,KAAM,CAAC,WAAW,EAAG,KAAM,CAAC,SAAS,CAAE,CACrF,EAQM,EAAuG,CAC3G,KAAM,CAAE,MAAO,CAAC,MAAM,EAAG,KAAM,CAAC,KAAK,EAAG,KAAM,CAAC,YAAa,WAAW,EAAG,KAAM,CAAC,UAAW,YAAY,CAAE,EAC1G,WAAY,CAAE,MAAO,CAAC,MAAM,EAAG,KAAM,CAAC,KAAK,EAAG,KAAM,CAAC,WAAW,EAAG,KAAM,CAAC,YAAY,CAAE,EACxF,SAAU,EAAa,QACzB,EAqEM,EAAmB,GACvB,OAAO,GAAS,YAAY,GAAiB,aAAc,EAEhD,EAAwB,GAAsD,CACzF,IAAM,GAAA,EAAS,EAAA,OAAA,CAAO,EAAE,EAElB,GAAkB,EAAS,IAC/B,EAAQ,iBAAiB,EAAM,CAAK,IAAM,EAAgB,CAAI,EAAI,EAAK,SAAW,IAE9E,GAAe,EAAa,EAAuB,KACnD,GAAO,IACT,EAAO,MAAQ,EACf,EAAQ,aAAa,EAAQ,EAAK,CAAK,GAGlC,GAGH,GAAoB,EAAY,EAAe,IAC/C,IAAc,UAAkB,EAAY,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAe,EAAM,CAAC,CAAC,EAE5F,EAAa,EAAO,GAAQ,EAAM,IAAM,CAAC,EAAe,EAAM,CAAC,CAAC,EAGnE,EAAO,GAA0B,CACrC,GAAI,EAAQ,EAGV,OAFA,EAAM,EAEC,GAGT,IAAM,EAAQ,EAAQ,SAAS,EAE/B,GAAI,CAAC,EAAM,OAAQ,MAAO,GAE1B,IAAM,EAAU,KAAK,IAAI,EAAO,EAAM,OAAS,CAAC,EAMhD,OAJI,EAAe,EAAM,GAAU,CAAO,EAAU,IAEpD,EAAO,MAAQ,EAER,EACT,EAEM,GAAQ,EAAmC,IAAkC,CACjF,IAAM,EAAQ,EAAQ,SAAS,EACzB,EAAU,EAAO,MAEvB,GAAI,CAAC,EAAM,OAAQ,MAAO,GAE1B,IAAM,EACJ,EAAU,EACN,IAAc,UACZ,EACA,EAAM,OAAS,EACjB,IAAc,UACZ,EAAU,EACV,EAAU,EACZ,EAAM,EAAiB,EAAO,EAAO,CAAS,EAC9C,EAA+B,IAAc,UAAY,OAAS,OAExE,GAAI,GAAO,EAAG,OAAO,EAAY,EAAK,EAAQ,CAAK,EAEnD,GAAI,EAAQ,KAAM,CAChB,IAAM,EAAY,IAAc,UAAY,EAAI,EAAM,OAAS,EACzD,EAAU,EAAiB,EAAO,EAAW,CAAS,EAE5D,GAAI,GAAW,EAAG,OAAO,EAAY,EAAS,EAAQ,CAAK,CAC7D,CAEA,OAAO,CACT,EAEM,EAAY,GAAyC,CACzD,IAAM,EAAQ,EAAQ,SAAS,EAE/B,GAAI,CAAC,EAAM,OAAQ,MAAO,GAE1B,GAAI,IAAW,QAAS,CACtB,IAAM,EAAM,EAAiB,EAAO,EAAG,SAAS,EAEhD,OAAO,EAAY,EAAK,OAAO,CACjC,CAEA,GAAI,IAAW,OAAQ,CACrB,IAAM,EAAM,EAAiB,EAAO,EAAM,OAAS,EAAG,UAAU,EAEhE,OAAO,EAAY,EAAK,MAAM,CAChC,CAEA,OAAO,EAAK,IAAW,OAAS,UAAY,UAAU,CACxD,EAEM,MAAqC,CACzC,IAAM,EAAQ,EAAQ,SAAS,EACzB,EAAQ,EAAO,MAErB,OAAO,GAAS,GAAK,EAAQ,EAAM,OAAS,EAAM,GAAS,IAAA,EAC7D,EAEM,MAAoB,CACxB,EAAO,MAAQ,EACjB,EAIM,MAA+B,EAAQ,EAAQ,UAAU,MAEzD,MACJ,OAAO,EAAQ,aAAgB,WAAa,EAAQ,YAAY,EAAK,EAAQ,aAAe,WAExF,MACJ,OAAO,EAAQ,WAAc,WAAa,EAAQ,UAAU,EAAK,EAAQ,WAAa,MAElF,MAA4E,CAChF,IAAM,EAAO,EAAQ,KAEf,GADW,EAAiB,IAAM,MAAQ,EAAmB,EAAA,CAC9B,EAAmB,GAClD,EAAW,CACf,MAAO,GAAM,OAAS,EAAoB,MAC1C,KAAM,GAAM,MAAQ,EAAoB,KACxC,KAAM,GAAM,MAAQ,EAAoB,KACxC,KAAM,GAAM,MAAQ,EAAoB,IAC1C,EACM,EAA6D,CAAC,EAEpE,IAAK,IAAM,IAAU,CAAC,OAAQ,OAAQ,QAAS,MAAM,EACnD,IAAK,IAAM,KAAO,EAAS,GACzB,EAAG,GAAQ,GAAiC,CAC1C,GAAI,IAAW,SAAW,IAAW,OAAQ,CAC3C,IAAM,EAAQ,EAAQ,SAAS,EAE/B,GAAI,CAAC,EAAM,OAAQ,OAEnB,IAAM,EACJ,IAAW,QACP,EAAiB,EAAO,EAAG,SAAS,EACpC,EAAiB,EAAO,EAAM,OAAS,EAAG,UAAU,EAE1D,EAAY,EAAK,EAAQ,CAAa,CACxC,MACE,EAAK,IAAW,OAAS,UAAY,WAAY,CAAa,CAElE,EAIJ,OAAO,CACT,EAIM,EAAY,EAAQ,aACtB,EAAA,gBAAgB,CACd,aAAgB,EAAO,MACvB,aAAc,EAAQ,aACtB,SAAU,EAAQ,SAClB,gBAAiB,EAAM,IAAU,EAAe,EAAM,CAAK,EAC3D,YAAa,EAAO,IAAU,CACvB,EAAc,IACjB,EAAO,MAAQ,EACf,EAAQ,aAAa,YAAa,EAAO,CAAK,EAElD,CACF,CAAC,EACD,KAKE,EADkB,OAAO,EAAQ,aAAgB,YAAc,OAAO,EAAQ,WAAc,WACP,KAAO,EAAY,EAExG,EAAiB,GAAkC,CACvD,IAAM,EAAK,GAAiB,EAAY,EAIxC,OAFI,EAAA,uBAAuB,EAAO,CAAE,SAAU,EAAQ,SAAU,OAAQ,CAAG,CAAC,EAAU,GAE/E,GAAW,cAAc,CAAK,GAAK,EAC5C,EAEI,EAAW,GAET,MAAsB,CACtB,IAEJ,EAAW,GACX,GAAW,MAAM,EACnB,EAMA,OAJI,EAAQ,QACV,EAAQ,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAG3D,CACL,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAAc,EACd,gBACA,gBACA,WACA,QACA,OACC,OAAO,SAAU,CACpB,CACF"}
1
+ {"version":3,"file":"nav.cjs","names":[],"sources":["../../src/core/nav.ts"],"sourcesContent":["import {\n createListNavigation,\n type ListNavigationOptions as FocusListNavigationOptions,\n type ListKeyAction,\n type ListNavigation,\n type ListNavigationAction,\n type ListNavigationChange,\n type ListNavigationTypeaheadOptions,\n} from '@vielzeug/focus';\nimport { type Readable, signal } from '@vielzeug/ripple';\n\nexport type ListNavigationOptions<T> = Omit<FocusListNavigationOptions<T>, 'disabled'> & {\n disabled?: Readable<boolean | undefined>;\n};\n\nexport type ListControl<T> = {\n [Symbol.dispose](): void;\n dispose(): void;\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n navigate(action: ListNavigationAction): number;\n reset(): void;\n set(index: number): number;\n};\n\nexport type { ListKeyAction, ListNavigationAction, ListNavigationChange, ListNavigationTypeaheadOptions };\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const focusedIndex = signal(-1);\n let removeAbortListener: (() => void) | undefined;\n const navigation: ListNavigation<T> = createListNavigation<T>({\n direction: options.direction,\n disabled: () => Boolean(options.disabled?.value),\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop,\n onNavigate: (change) => {\n focusedIndex.value = change.index;\n options.onNavigate?.(change);\n },\n orientation: options.orientation,\n typeahead: options.typeahead,\n });\n\n const syncIndex = (): void => {\n focusedIndex.value = navigation.getIndex();\n };\n\n const set = (index: number): number => {\n const next = navigation.set(index);\n\n syncIndex();\n\n return next;\n };\n\n const navigate = (action: ListNavigationAction): number => {\n const next = navigation.navigate(action);\n\n syncIndex();\n\n return next;\n };\n\n const reset = (): void => {\n navigation.reset();\n syncIndex();\n };\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const handled = navigation.handleKeydown(event);\n\n syncIndex();\n\n return handled;\n };\n\n const dispose = (): void => {\n navigation.dispose();\n syncIndex();\n removeAbortListener?.();\n removeAbortListener = undefined;\n };\n\n if (options.signal?.aborted) {\n dispose();\n } else if (options.signal) {\n options.signal?.addEventListener('abort', dispose, { once: true });\n removeAbortListener = () => options.signal?.removeEventListener('abort', dispose);\n }\n\n return {\n dispose,\n get disposed() {\n return navigation.disposed;\n },\n focusedIndex,\n getActiveItem: () => navigation.getActiveItem(),\n handleKeydown,\n navigate,\n reset,\n set,\n [Symbol.dispose]: dispose,\n };\n};\n"],"mappings":"+DA6BA,IAAa,EAAwB,GAAsD,CACzF,IAAM,GAAA,EAAe,EAAA,OAAA,CAAO,EAAE,EAC1B,EACE,GAAA,EAAgC,EAAA,qBAAA,CAAwB,CAC5D,UAAW,EAAQ,UACnB,aAAgB,EAAQ,EAAQ,UAAU,MAC1C,SAAU,EAAQ,SAClB,eAAgB,EAAQ,eACxB,KAAM,EAAQ,KACd,KAAM,EAAQ,KACd,WAAa,GAAW,CACtB,EAAa,MAAQ,EAAO,MAC5B,EAAQ,aAAa,CAAM,CAC7B,EACA,YAAa,EAAQ,YACrB,UAAW,EAAQ,SACrB,CAAC,EAEK,MAAwB,CAC5B,EAAa,MAAQ,EAAW,SAAS,CAC3C,EAEM,EAAO,GAA0B,CACrC,IAAM,EAAO,EAAW,IAAI,CAAK,EAIjC,OAFA,EAAU,EAEH,CACT,EAEM,EAAY,GAAyC,CACzD,IAAM,EAAO,EAAW,SAAS,CAAM,EAIvC,OAFA,EAAU,EAEH,CACT,EAEM,MAAoB,CACxB,EAAW,MAAM,EACjB,EAAU,CACZ,EAEM,EAAiB,GAAkC,CACvD,IAAM,EAAU,EAAW,cAAc,CAAK,EAI9C,OAFA,EAAU,EAEH,CACT,EAEM,MAAsB,CAC1B,EAAW,QAAQ,EACnB,EAAU,EACV,IAAsB,EACtB,EAAsB,IAAA,EACxB,EASA,OAPI,EAAQ,QAAQ,QAClB,EAAQ,EACC,EAAQ,SACjB,EAAQ,QAAQ,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EACjE,MAA4B,EAAQ,QAAQ,oBAAoB,QAAS,CAAO,GAG3E,CACL,UACA,IAAI,UAAW,CACb,OAAO,EAAW,QACpB,EACA,eACA,kBAAqB,EAAW,cAAc,EAC9C,gBACA,WACA,QACA,OACC,OAAO,SAAU,CACpB,CACF"}
@@ -1,78 +1,19 @@
1
+ import { type ListNavigationOptions as FocusListNavigationOptions, type ListKeyAction, type ListNavigationAction, type ListNavigationChange, type ListNavigationTypeaheadOptions } from '@vielzeug/focus';
1
2
  import { type Readable } from '@vielzeug/ripple';
2
- /**
3
- * Arrow-key and Home/End navigation actions. Separate from `ListKeyAction` so
4
- * keymap declarations never need `Exclude<ListKeyAction, 'typeahead'>`.
5
- */
6
- export type ListNavigationAction = 'first' | 'last' | 'next' | 'prev';
7
- /**
8
- * All possible navigation action names, including `'typeahead'` (character-key
9
- * search). Used in `onNavigate` callbacks where both nav and typeahead are valid.
10
- */
11
- export type ListKeyAction = ListNavigationAction | 'typeahead';
12
- export type ListNavigationOptions<T> = {
13
- /**
14
- * Text direction, used to mirror the default Left/Right arrow-key bindings for
15
- * `'horizontal'`/`'both'` orientation (WAI-ARIA APG: `dir="rtl"` flips which arrow key
16
- * means "next" vs "prev"). Pass a getter for dynamic/reactive direction (e.g. derived from
17
- * `elementDirection(getHost())`, since a `dir` ancestor attribute can change at runtime).
18
- * Has no effect when an explicit `keys` override is provided. Defaults to `'ltr'`.
19
- */
20
- direction?: 'ltr' | 'rtl' | (() => 'ltr' | 'rtl');
3
+ export type ListNavigationOptions<T> = Omit<FocusListNavigationOptions<T>, 'disabled'> & {
21
4
  disabled?: Readable<boolean | undefined>;
22
- /**
23
- * Returns a plain-text label for an item used by typeahead search.
24
- * When provided, pressing a printable character key jumps to the first enabled
25
- * item whose label starts with the accumulated type buffer (500 ms reset window).
26
- * Omit for contexts where the host element is a text input (e.g. combobox).
27
- */
28
- getItemLabel?: (item: T, index: number) => string;
29
- getItems: () => T[];
30
- isItemDisabled?: (item: T, index: number) => boolean;
31
- /** Override default key bindings for navigation actions. */
32
- keys?: Partial<Record<ListNavigationAction, string[]>>;
33
- loop?: boolean;
34
- /**
35
- * Called when navigation lands on a new index.
36
- * `event` is the originating `KeyboardEvent`, or `undefined` for programmatic navigation.
37
- * Use to sync side-effects such as focusing a DOM element.
38
- */
39
- onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;
40
- /**
41
- * Axis the list navigates along. Controls which arrow keys are treated as
42
- * `next`/`prev` when no explicit `keys` override is provided.
43
- * Pass a getter function for dynamic/reactive orientation (e.g. driven by a prop signal).
44
- *
45
- * - `'vertical'` (default): ↑↓ arrows
46
- * - `'horizontal'`: ←→ arrows
47
- * - `'both'`: all four arrow keys
48
- */
49
- orientation?: 'both' | 'horizontal' | 'vertical' | (() => 'both' | 'horizontal' | 'vertical');
50
- /** `AbortSignal` from the component lifecycle. Disposes typeahead timer on abort. */
51
- signal?: AbortSignal;
52
5
  };
53
6
  export type ListControl<T> = {
54
7
  [Symbol.dispose](): void;
55
- /** Disposes the internal typeahead timer. Alias for `dispose()`. Conforms to the monorepo disposal convention. */
56
8
  dispose(): void;
57
- /** `true` after `dispose()` has been called. */
58
9
  readonly disposed: boolean;
59
- /** Current focused index. `-1` when nothing is focused. */
60
10
  readonly focusedIndex: Readable<number>;
61
11
  getActiveItem(): T | undefined;
62
12
  handleKeydown(event: KeyboardEvent): boolean;
63
- /**
64
- * Programmatically navigate to a named position.
65
- * Always fires `onNavigate` — consistent with keyboard navigation.
66
- * Returns the resolved index, or `-1` if no enabled item was found.
67
- */
68
13
  navigate(action: ListNavigationAction): number;
69
- /** Reset focused index to `-1`. */
70
14
  reset(): void;
71
- /**
72
- * Set focus to the item at `index`. Returns the resolved index.
73
- * Pass a negative index to clear focus (same as `reset()`).
74
- */
75
15
  set(index: number): number;
76
16
  };
17
+ export type { ListKeyAction, ListNavigationAction, ListNavigationChange, ListNavigationTypeaheadOptions };
77
18
  export declare const createListControl: <T>(options: ListNavigationOptions<T>) => ListControl<T>;
78
19
  //# sourceMappingURL=nav.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../src/core/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAwBzD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,WAAW,CAAC;AA0B/D,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC;IAClD,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACzC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IACrD,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,aAAa,KAAK,IAAI,CAAC;IACnF;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,CAAC,MAAM,MAAM,GAAG,YAAY,GAAG,UAAU,CAAC,CAAC;IAC9F,qFAAqF;IACrF,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACzB,kHAAkH;IAClH,OAAO,IAAI,IAAI,CAAC;IAChB,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxC,aAAa,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/B,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAAC;IAC/C,mCAAmC;IACnC,KAAK,IAAI,IAAI,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B,CAAC;AAKF,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CA2MrF,CAAC"}
1
+ {"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../src/core/nav.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,qBAAqB,IAAI,0BAA0B,EACxD,KAAK,aAAa,EAElB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACpC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,QAAQ,EAAU,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG;IACvF,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;IACzB,OAAO,IAAI,IAAI,CAAC;IAChB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACxC,aAAa,IAAI,CAAC,GAAG,SAAS,CAAC;IAC/B,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAAC;IAC/C,KAAK,IAAI,IAAI,CAAC;IACd,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B,CAAC;AAEF,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,8BAA8B,EAAE,CAAC;AAE1G,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,SAAS,qBAAqB,CAAC,CAAC,CAAC,KAAG,WAAW,CAAC,CAAC,CA8ErF,CAAC"}
package/dist/core/nav.js CHANGED
@@ -1,133 +1,50 @@
1
- import { dispatchKeyboardAction as e } from "./keyboard.js";
2
- import { createTypeahead as t } from "./typeahead.js";
3
- import { signal as n } from "@vielzeug/ripple";
1
+ import { signal as e } from "@vielzeug/ripple";
2
+ import { createListNavigation as t } from "@vielzeug/focus";
4
3
  //#region src/core/nav.ts
5
- var r = (e, t, n) => {
6
- for (let r = t; r < e.length; r++) if (n(e[r], r)) return r;
7
- return -1;
8
- }, i = (e, t, n) => {
9
- for (let r = t; r >= 0; r--) if (n(e[r], r)) return r;
10
- return -1;
11
- }, a = {
12
- both: {
13
- first: ["Home"],
14
- last: ["End"],
15
- next: ["ArrowDown", "ArrowRight"],
16
- prev: ["ArrowUp", "ArrowLeft"]
17
- },
18
- horizontal: {
19
- first: ["Home"],
20
- last: ["End"],
21
- next: ["ArrowRight"],
22
- prev: ["ArrowLeft"]
23
- },
24
- vertical: {
25
- first: ["Home"],
26
- last: ["End"],
27
- next: ["ArrowDown"],
28
- prev: ["ArrowUp"]
29
- }
30
- }, o = {
31
- both: {
32
- first: ["Home"],
33
- last: ["End"],
34
- next: ["ArrowDown", "ArrowLeft"],
35
- prev: ["ArrowUp", "ArrowRight"]
36
- },
37
- horizontal: {
38
- first: ["Home"],
39
- last: ["End"],
40
- next: ["ArrowLeft"],
41
- prev: ["ArrowRight"]
42
- },
43
- vertical: a.vertical
44
- }, s = (e) => typeof e == "object" && !!e && "disabled" in e, c = (c) => {
45
- let l = n(-1), u = (e, t) => c.isItemDisabled?.(e, t) ?? (s(e) ? e.disabled : !1), d = (e, t, n) => (e >= 0 && (l.value = e, c.onNavigate?.(t, e, n)), e), f = (e, t, n) => n === "forward" ? r(e, t, (e, t) => !u(e, t)) : i(e, t, (e, t) => !u(e, t)), p = (e) => {
46
- if (e < 0) return _(), -1;
47
- let t = c.getItems();
48
- if (!t.length) return -1;
49
- let n = Math.min(e, t.length - 1);
50
- return u(t[n], n) ? -1 : (l.value = n, n);
51
- }, m = (e, t) => {
52
- let n = c.getItems(), r = l.value;
53
- if (!n.length) return -1;
54
- let i = r < 0 ? e === "forward" ? 0 : n.length - 1 : e === "forward" ? r + 1 : r - 1, a = f(n, i, e), o = e === "forward" ? "next" : "prev";
55
- if (a >= 0) return d(a, o, t);
56
- if (c.loop) {
57
- let r = e === "forward" ? 0 : n.length - 1, i = f(n, r, e);
58
- if (i >= 0) return d(i, o, t);
59
- }
60
- return r;
61
- }, h = (e) => {
62
- let t = c.getItems();
63
- if (!t.length) return -1;
64
- if (e === "first") {
65
- let e = f(t, 0, "forward");
66
- return d(e, "first");
67
- }
68
- if (e === "last") {
69
- let e = f(t, t.length - 1, "backward");
70
- return d(e, "last");
71
- }
72
- return m(e === "next" ? "forward" : "backward");
73
- }, g = () => {
74
- let e = c.getItems(), t = l.value;
75
- return t >= 0 && t < e.length ? e[t] : void 0;
76
- }, _ = () => {
77
- l.value = -1;
78
- }, v = () => !!c.disabled?.value, y = () => typeof c.orientation == "function" ? c.orientation() : c.orientation ?? "vertical", b = () => typeof c.direction == "function" ? c.direction() : c.direction ?? "ltr", x = () => {
79
- let e = c.keys, t = (b() === "rtl" ? o : a)[y()], n = {
80
- first: e?.first ?? t.first,
81
- last: e?.last ?? t.last,
82
- next: e?.next ?? t.next,
83
- prev: e?.prev ?? t.prev
84
- }, r = {};
85
- for (let e of [
86
- "next",
87
- "prev",
88
- "first",
89
- "last"
90
- ]) for (let t of n[e]) r[t] = (t) => {
91
- if (e === "first" || e === "last") {
92
- let n = c.getItems();
93
- if (!n.length) return;
94
- let r = e === "first" ? f(n, 0, "forward") : f(n, n.length - 1, "backward");
95
- d(r, e, t);
96
- } else m(e === "next" ? "forward" : "backward", t);
97
- };
98
- return r;
99
- }, S = c.getItemLabel ? t({
100
- getIndex: () => l.value,
101
- getItemLabel: c.getItemLabel,
102
- getItems: c.getItems,
103
- isItemDisabled: (e, t) => u(e, t),
104
- onNavigate: (e, t) => {
105
- v() || (l.value = e, c.onNavigate?.("typeahead", e, t));
106
- }
107
- }) : null, C = typeof c.orientation == "function" || typeof c.direction == "function" ? null : x(), w = (t) => {
108
- let n = C ?? x();
109
- return e(t, {
110
- disabled: c.disabled,
111
- keymap: n
112
- }) ? !0 : S?.handleKeydown(t) ?? !1;
113
- }, T = !1, E = () => {
114
- T || (T = !0, S?.reset());
4
+ var n = (n) => {
5
+ let r = e(-1), i, a = t({
6
+ direction: n.direction,
7
+ disabled: () => !!n.disabled?.value,
8
+ getItems: n.getItems,
9
+ isItemDisabled: n.isItemDisabled,
10
+ keys: n.keys,
11
+ loop: n.loop,
12
+ onNavigate: (e) => {
13
+ r.value = e.index, n.onNavigate?.(e);
14
+ },
15
+ orientation: n.orientation,
16
+ typeahead: n.typeahead
17
+ }), o = () => {
18
+ r.value = a.getIndex();
19
+ }, s = (e) => {
20
+ let t = a.set(e);
21
+ return o(), t;
22
+ }, c = (e) => {
23
+ let t = a.navigate(e);
24
+ return o(), t;
25
+ }, l = () => {
26
+ a.reset(), o();
27
+ }, u = (e) => {
28
+ let t = a.handleKeydown(e);
29
+ return o(), t;
30
+ }, d = () => {
31
+ a.dispose(), o(), i?.(), i = void 0;
115
32
  };
116
- return c.signal && c.signal.addEventListener("abort", E, { once: !0 }), {
117
- dispose: E,
33
+ return n.signal?.aborted ? d() : n.signal && (n.signal?.addEventListener("abort", d, { once: !0 }), i = () => n.signal?.removeEventListener("abort", d)), {
34
+ dispose: d,
118
35
  get disposed() {
119
- return T;
36
+ return a.disposed;
120
37
  },
121
- focusedIndex: l,
122
- getActiveItem: g,
123
- handleKeydown: w,
124
- navigate: h,
125
- reset: _,
126
- set: p,
127
- [Symbol.dispose]: E
38
+ focusedIndex: r,
39
+ getActiveItem: () => a.getActiveItem(),
40
+ handleKeydown: u,
41
+ navigate: c,
42
+ reset: l,
43
+ set: s,
44
+ [Symbol.dispose]: d
128
45
  };
129
46
  };
130
47
  //#endregion
131
- export { c as createListControl };
48
+ export { n as createListControl };
132
49
 
133
50
  //# sourceMappingURL=nav.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nav.js","names":[],"sources":["../../src/core/nav.ts"],"sourcesContent":["import { type Readable, signal } from '@vielzeug/ripple';\n\nimport { dispatchKeyboardAction } from './keyboard';\nimport { createTypeahead } from './typeahead';\n\n// ── Private array search helpers ────────────────────────────────────────────\nconst findForward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx < items.length; idx++) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\nconst findBackward = <T>(items: T[], start: number, predicate: (item: T, index: number) => boolean): number => {\n for (let idx = start; idx >= 0; idx--) {\n if (predicate(items[idx], idx)) return idx;\n }\n\n return -1;\n};\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\n/**\n * Arrow-key and Home/End navigation actions. Separate from `ListKeyAction` so\n * keymap declarations never need `Exclude<ListKeyAction, 'typeahead'>`.\n */\nexport type ListNavigationAction = 'first' | 'last' | 'next' | 'prev';\n\n/**\n * All possible navigation action names, including `'typeahead'` (character-key\n * search). Used in `onNavigate` callbacks where both nav and typeahead are valid.\n */\nexport type ListKeyAction = ListNavigationAction | 'typeahead';\n\n/**\n * Orientation-aware default key bindings for list navigation.\n * - `'vertical'` (default): Up/Down arrows, Home/End\n * - `'horizontal'`: Left/Right arrows, Home/End\n * - `'both'`: all four arrow keys + Home/End\n */\nconst DEFAULT_KEYS: Record<'both' | 'horizontal' | 'vertical', Record<ListNavigationAction, string[]>> = {\n both: { first: ['Home'], last: ['End'], next: ['ArrowDown', 'ArrowRight'], prev: ['ArrowUp', 'ArrowLeft'] },\n horizontal: { first: ['Home'], last: ['End'], next: ['ArrowRight'], prev: ['ArrowLeft'] },\n vertical: { first: ['Home'], last: ['End'], next: ['ArrowDown'], prev: ['ArrowUp'] },\n};\n\n/**\n * RTL mirror of `DEFAULT_KEYS`'s horizontal component (per WAI-ARIA APG — tabs/radiogroup\n * flip Left/Right in `dir=\"rtl\"` so \"next\" always advances in reading order, not screen-space\n * direction). Only the Left/Right bindings differ; Home/End and the vertical arrows are\n * direction-independent and stay identical to `DEFAULT_KEYS`.\n */\nconst DEFAULT_KEYS_RTL: Record<'both' | 'horizontal' | 'vertical', Record<ListNavigationAction, string[]>> = {\n both: { first: ['Home'], last: ['End'], next: ['ArrowDown', 'ArrowLeft'], prev: ['ArrowUp', 'ArrowRight'] },\n horizontal: { first: ['Home'], last: ['End'], next: ['ArrowLeft'], prev: ['ArrowRight'] },\n vertical: DEFAULT_KEYS.vertical,\n};\n\nexport type ListNavigationOptions<T> = {\n /**\n * Text direction, used to mirror the default Left/Right arrow-key bindings for\n * `'horizontal'`/`'both'` orientation (WAI-ARIA APG: `dir=\"rtl\"` flips which arrow key\n * means \"next\" vs \"prev\"). Pass a getter for dynamic/reactive direction (e.g. derived from\n * `elementDirection(getHost())`, since a `dir` ancestor attribute can change at runtime).\n * Has no effect when an explicit `keys` override is provided. Defaults to `'ltr'`.\n */\n direction?: 'ltr' | 'rtl' | (() => 'ltr' | 'rtl');\n disabled?: Readable<boolean | undefined>;\n /**\n * Returns a plain-text label for an item used by typeahead search.\n * When provided, pressing a printable character key jumps to the first enabled\n * item whose label starts with the accumulated type buffer (500 ms reset window).\n * Omit for contexts where the host element is a text input (e.g. combobox).\n */\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n isItemDisabled?: (item: T, index: number) => boolean;\n /** Override default key bindings for navigation actions. */\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n /**\n * Called when navigation lands on a new index.\n * `event` is the originating `KeyboardEvent`, or `undefined` for programmatic navigation.\n * Use to sync side-effects such as focusing a DOM element.\n */\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n /**\n * Axis the list navigates along. Controls which arrow keys are treated as\n * `next`/`prev` when no explicit `keys` override is provided.\n * Pass a getter function for dynamic/reactive orientation (e.g. driven by a prop signal).\n *\n * - `'vertical'` (default): ↑↓ arrows\n * - `'horizontal'`: ←→ arrows\n * - `'both'`: all four arrow keys\n */\n orientation?: 'both' | 'horizontal' | 'vertical' | (() => 'both' | 'horizontal' | 'vertical');\n /** `AbortSignal` from the component lifecycle. Disposes typeahead timer on abort. */\n signal?: AbortSignal;\n};\n\nexport type ListControl<T> = {\n [Symbol.dispose](): void;\n /** Disposes the internal typeahead timer. Alias for `dispose()`. Conforms to the monorepo disposal convention. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n /** Current focused index. `-1` when nothing is focused. */\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n /**\n * Programmatically navigate to a named position.\n * Always fires `onNavigate` — consistent with keyboard navigation.\n * Returns the resolved index, or `-1` if no enabled item was found.\n */\n navigate(action: ListNavigationAction): number;\n /** Reset focused index to `-1`. */\n reset(): void;\n /**\n * Set focus to the item at `index`. Returns the resolved index.\n * Pass a negative index to clear focus (same as `reset()`).\n */\n set(index: number): number;\n};\n\nconst hasDisabledProp = (item: unknown): item is { disabled: boolean } =>\n typeof item === 'object' && item !== null && 'disabled' in item;\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const _index = signal(-1);\n\n const isItemDisabled = (item: T, index: number): boolean =>\n options.isItemDisabled?.(item, index) ?? (hasDisabledProp(item) ? item.disabled : false);\n\n const commitIndex = (idx: number, action: ListKeyAction, event?: KeyboardEvent): number => {\n if (idx >= 0) {\n _index.value = idx;\n options.onNavigate?.(action, idx, event);\n }\n\n return idx;\n };\n\n const findEnabledIndex = (items: T[], start: number, direction: 'forward' | 'backward'): number => {\n if (direction === 'forward') return findForward(items, start, (item, i) => !isItemDisabled(item, i));\n\n return findBackward(items, start, (item, i) => !isItemDisabled(item, i));\n };\n\n const set = (index: number): number => {\n if (index < 0) {\n reset();\n\n return -1;\n }\n\n const items = options.getItems();\n\n if (!items.length) return -1;\n\n const clamped = Math.min(index, items.length - 1);\n\n if (isItemDisabled(items[clamped], clamped)) return -1;\n\n _index.value = clamped;\n\n return clamped;\n };\n\n const move = (direction: 'forward' | 'backward', event?: KeyboardEvent): number => {\n const items = options.getItems();\n const current = _index.value;\n\n if (!items.length) return -1;\n\n const start: number =\n current < 0\n ? direction === 'forward'\n ? 0\n : items.length - 1\n : direction === 'forward'\n ? current + 1\n : current - 1;\n const idx = findEnabledIndex(items, start, direction);\n const action: ListNavigationAction = direction === 'forward' ? 'next' : 'prev';\n\n if (idx >= 0) return commitIndex(idx, action, event);\n\n if (options.loop) {\n const wrapStart = direction === 'forward' ? 0 : items.length - 1;\n const wrapped = findEnabledIndex(items, wrapStart, direction);\n\n if (wrapped >= 0) return commitIndex(wrapped, action, event);\n }\n\n return current;\n };\n\n const navigate = (action: ListNavigationAction): number => {\n const items = options.getItems();\n\n if (!items.length) return -1;\n\n if (action === 'first') {\n const idx = findEnabledIndex(items, 0, 'forward');\n\n return commitIndex(idx, 'first');\n }\n\n if (action === 'last') {\n const idx = findEnabledIndex(items, items.length - 1, 'backward');\n\n return commitIndex(idx, 'last');\n }\n\n return move(action === 'next' ? 'forward' : 'backward');\n };\n\n const getActiveItem = (): T | undefined => {\n const items = options.getItems();\n const index = _index.value;\n\n return index >= 0 && index < items.length ? items[index] : undefined;\n };\n\n const reset = (): void => {\n _index.value = -1;\n };\n\n // ── Keyboard handling ──────────────────────────────────────────────────────\n\n const isKeyDisabled = (): boolean => Boolean(options.disabled?.value);\n\n const resolveOrientation = (): 'both' | 'horizontal' | 'vertical' =>\n typeof options.orientation === 'function' ? options.orientation() : (options.orientation ?? 'vertical');\n\n const resolveDirection = (): 'ltr' | 'rtl' =>\n typeof options.direction === 'function' ? options.direction() : (options.direction ?? 'ltr');\n\n const buildKeymap = (): Record<string, (keyboardEvent: KeyboardEvent) => void> => {\n const keys = options.keys;\n const keyTable = resolveDirection() === 'rtl' ? DEFAULT_KEYS_RTL : DEFAULT_KEYS;\n const orientationDefaults = keyTable[resolveOrientation()];\n const resolved = {\n first: keys?.first ?? orientationDefaults.first,\n last: keys?.last ?? orientationDefaults.last,\n next: keys?.next ?? orientationDefaults.next,\n prev: keys?.prev ?? orientationDefaults.prev,\n };\n const km: Record<string, (keyboardEvent: KeyboardEvent) => void> = {};\n\n for (const action of ['next', 'prev', 'first', 'last'] as const) {\n for (const key of resolved[action]) {\n km[key] = (keyboardEvent: KeyboardEvent) => {\n if (action === 'first' || action === 'last') {\n const items = options.getItems();\n\n if (!items.length) return;\n\n const idx =\n action === 'first'\n ? findEnabledIndex(items, 0, 'forward')\n : findEnabledIndex(items, items.length - 1, 'backward');\n\n commitIndex(idx, action, keyboardEvent);\n } else {\n move(action === 'next' ? 'forward' : 'backward', keyboardEvent);\n }\n };\n }\n }\n\n return km;\n };\n\n // ── Typeahead ──────────────────────────────────────────────────────────────\n\n const typeahead = options.getItemLabel\n ? createTypeahead({\n getIndex: () => _index.value,\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: (item, index) => isItemDisabled(item, index),\n onNavigate: (index, event) => {\n if (!isKeyDisabled()) {\n _index.value = index;\n options.onNavigate?.('typeahead', index, event);\n }\n },\n })\n : null;\n\n // Keymap depends on both orientation and direction — if either is dynamic, rebuild on every\n // keydown instead of caching once.\n const isDynamicKeymap = typeof options.orientation === 'function' || typeof options.direction === 'function';\n const _staticKeymap: Record<string, (e: KeyboardEvent) => void> | null = isDynamicKeymap ? null : buildKeymap();\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const km = _staticKeymap ?? buildKeymap();\n\n if (dispatchKeyboardAction(event, { disabled: options.disabled, keymap: km })) return true;\n\n return typeahead?.handleKeydown(event) ?? false;\n };\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n typeahead?.reset();\n };\n\n if (options.signal) {\n options.signal.addEventListener('abort', dispose, { once: true });\n }\n\n return {\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: _index,\n getActiveItem,\n handleKeydown,\n navigate,\n reset,\n set,\n [Symbol.dispose]: dispose,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"nav.js","names":[],"sources":["../../src/core/nav.ts"],"sourcesContent":["import {\n createListNavigation,\n type ListNavigationOptions as FocusListNavigationOptions,\n type ListKeyAction,\n type ListNavigation,\n type ListNavigationAction,\n type ListNavigationChange,\n type ListNavigationTypeaheadOptions,\n} from '@vielzeug/focus';\nimport { type Readable, signal } from '@vielzeug/ripple';\n\nexport type ListNavigationOptions<T> = Omit<FocusListNavigationOptions<T>, 'disabled'> & {\n disabled?: Readable<boolean | undefined>;\n};\n\nexport type ListControl<T> = {\n [Symbol.dispose](): void;\n dispose(): void;\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n navigate(action: ListNavigationAction): number;\n reset(): void;\n set(index: number): number;\n};\n\nexport type { ListKeyAction, ListNavigationAction, ListNavigationChange, ListNavigationTypeaheadOptions };\n\nexport const createListControl = <T>(options: ListNavigationOptions<T>): ListControl<T> => {\n const focusedIndex = signal(-1);\n let removeAbortListener: (() => void) | undefined;\n const navigation: ListNavigation<T> = createListNavigation<T>({\n direction: options.direction,\n disabled: () => Boolean(options.disabled?.value),\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop,\n onNavigate: (change) => {\n focusedIndex.value = change.index;\n options.onNavigate?.(change);\n },\n orientation: options.orientation,\n typeahead: options.typeahead,\n });\n\n const syncIndex = (): void => {\n focusedIndex.value = navigation.getIndex();\n };\n\n const set = (index: number): number => {\n const next = navigation.set(index);\n\n syncIndex();\n\n return next;\n };\n\n const navigate = (action: ListNavigationAction): number => {\n const next = navigation.navigate(action);\n\n syncIndex();\n\n return next;\n };\n\n const reset = (): void => {\n navigation.reset();\n syncIndex();\n };\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n const handled = navigation.handleKeydown(event);\n\n syncIndex();\n\n return handled;\n };\n\n const dispose = (): void => {\n navigation.dispose();\n syncIndex();\n removeAbortListener?.();\n removeAbortListener = undefined;\n };\n\n if (options.signal?.aborted) {\n dispose();\n } else if (options.signal) {\n options.signal?.addEventListener('abort', dispose, { once: true });\n removeAbortListener = () => options.signal?.removeEventListener('abort', dispose);\n }\n\n return {\n dispose,\n get disposed() {\n return navigation.disposed;\n },\n focusedIndex,\n getActiveItem: () => navigation.getActiveItem(),\n handleKeydown,\n navigate,\n reset,\n set,\n [Symbol.dispose]: dispose,\n };\n};\n"],"mappings":";;;AA6BA,IAAa,KAAwB,MAAsD;CACzF,IAAM,IAAe,EAAO,EAAE,GAC1B,GACE,IAAgC,EAAwB;EAC5D,WAAW,EAAQ;EACnB,gBAAgB,EAAQ,EAAQ,UAAU;EAC1C,UAAU,EAAQ;EAClB,gBAAgB,EAAQ;EACxB,MAAM,EAAQ;EACd,MAAM,EAAQ;EACd,aAAa,MAAW;GAEtB,AADA,EAAa,QAAQ,EAAO,OAC5B,EAAQ,aAAa,CAAM;EAC7B;EACA,aAAa,EAAQ;EACrB,WAAW,EAAQ;CACrB,CAAC,GAEK,UAAwB;EAC5B,EAAa,QAAQ,EAAW,SAAS;CAC3C,GAEM,KAAO,MAA0B;EACrC,IAAM,IAAO,EAAW,IAAI,CAAK;EAIjC,OAFA,EAAU,GAEH;CACT,GAEM,KAAY,MAAyC;EACzD,IAAM,IAAO,EAAW,SAAS,CAAM;EAIvC,OAFA,EAAU,GAEH;CACT,GAEM,UAAoB;EAExB,AADA,EAAW,MAAM,GACjB,EAAU;CACZ,GAEM,KAAiB,MAAkC;EACvD,IAAM,IAAU,EAAW,cAAc,CAAK;EAI9C,OAFA,EAAU,GAEH;CACT,GAEM,UAAsB;EAI1B,AAHA,EAAW,QAAQ,GACnB,EAAU,GACV,IAAsB,GACtB,IAAsB,KAAA;CACxB;CASA,OAPI,EAAQ,QAAQ,UAClB,EAAQ,IACC,EAAQ,WACjB,EAAQ,QAAQ,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,GACjE,UAA4B,EAAQ,QAAQ,oBAAoB,SAAS,CAAO,IAG3E;EACL;EACA,IAAI,WAAW;GACb,OAAO,EAAW;EACpB;EACA;EACA,qBAAqB,EAAW,cAAc;EAC9C;EACA;EACA;EACA;GACC,OAAO,UAAU;CACpB;AACF"}
@@ -1,2 +1,2 @@
1
- const e=require("../errors.cjs"),t=require("./overlay.cjs"),n=require("./nav.cjs"),r=require("./positioner.cjs");let i=require("@vielzeug/ripple");var a=a=>{if(typeof a.getBoundary!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getBoundary is required`);if(typeof a.getPanel!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getPanel is required`);if(typeof a.getReference!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getReference is required`);let o=(0,i.signal)(!1),s=(0,i.computed)(()=>String(o.value)),c=null,l=r.createDropdownPositioner({...a.positioning,getFloating:a.getPanel,getReference:a.getReference}),u=()=>{a.getFocusedOptionElement?.()?.scrollIntoView({block:`nearest`})},d=n.createListControl({disabled:(0,i.computed)(()=>!o.value),getItemLabel:a.getItemLabel,getItems:a.getItems,isItemDisabled:a.isItemDisabled,keys:a.keys,loop:a.loop??!0,onNavigate:(e,t,n)=>{u(),t>=0&&a.onNavigate?.(e,t,n)},orientation:a.orientation,signal:a.signal}),f=(0,i.computed)(()=>{let e=d.focusedIndex.value;return a.getOptionId&&o.value&&e>=0?a.getOptionId(e):null}),p=()=>typeof a.restoreFocus==`function`?a.restoreFocus():a.restoreFocus??!0,m=(e=`programmatic`,n=!0)=>{o.value&&(o.value=!1,d.reset(),c?.(),c=null,n&&p()&&a.getTrigger&&t.restoreTriggerFocus(a.getTrigger),a.onClose?.(e))},h=(e=`programmatic`)=>{a.isDisabled?.()||o.value||(o.value=!0,l.update(),c=l.startAutoUpdate?.()??null,a.onOpen?.(e))},g=(e=`click`,t=`trigger`)=>{o.value?m(t):h(e)};t.createOutsidePointerDismissal({getTargets:()=>[a.getBoundary(),a.getPanel()],isActive:()=>o.value,onDismiss:()=>m(`outsideClick`),signal:a.signal});let _=!1,v=()=>{_||(_=!0,o.value&&(o.value=!1,d.reset(),c?.(),c=null))};return a.signal.addEventListener(`abort`,v,{once:!0}),{ariaActiveDescendant:f,ariaExpanded:s,close:m,dispose:v,get disposed(){return _},focusedIndex:d.focusedIndex,getActiveItem:d.getActiveItem,handleKeydown:e=>o.value?e.key===`Escape`?(e.preventDefault(),m(`escape`),!0):d.handleKeydown(e):!1,isOpen:o,navigate:d.navigate,open:h,scrollFocusedIntoView:u,set:d.set,[Symbol.dispose]:v,toggle:g,updatePosition:l.update}};exports.createListboxDropdown=a;
1
+ const e=require("../errors.cjs"),t=require("./overlay.cjs"),n=require("./nav.cjs"),r=require("./positioner.cjs");let i=require("@vielzeug/ripple"),a=require("@vielzeug/focus");var o=o=>{if(typeof o.getBoundary!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getBoundary is required`);if(typeof o.getPanel!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getPanel is required`);if(typeof o.getReference!=`function`)throw new e.RefineConfigError(`createListboxDropdown: getReference is required`);let s=(0,i.signal)(!1),c=(0,i.computed)(()=>String(s.value)),l=null,u=r.createDropdownPositioner({...o.positioning,getFloating:o.getPanel,getReference:o.getReference}),d=()=>{o.getFocusedOptionElement?.()?.scrollIntoView({block:`nearest`})},f=n.createListControl({disabled:(0,i.computed)(()=>!s.value),getItems:o.getItems,isItemDisabled:o.isItemDisabled,keys:o.keys,loop:o.loop??!0,onNavigate:e=>{d(),o.onNavigate?.(e)},orientation:o.orientation,signal:o.signal,typeahead:o.typeahead}),p=(0,i.computed)(()=>{let e=f.focusedIndex.value;return o.getOptionId&&s.value&&e>=0?o.getOptionId(e):null}),m=()=>typeof o.restoreFocus==`function`?o.restoreFocus():o.restoreFocus??!0,h=(e=`programmatic`,t=!0)=>{s.value&&(s.value=!1,f.reset(),l?.(),l=null,t&&m()&&o.getTrigger&&(0,a.restoreFocus)(o.getTrigger),o.onClose?.(e))},g=(e=`programmatic`)=>{o.isDisabled?.()||s.value||(s.value=!0,u.update(),l=u.startAutoUpdate?.()??null,o.onOpen?.(e))},_=(e=`click`,t=`trigger`)=>{s.value?h(t):g(e)};t.createOutsidePointerDismissal({getTargets:()=>[o.getBoundary(),o.getPanel()],isActive:()=>s.value,onDismiss:()=>h(`outsideClick`),signal:o.signal});let v=!1,y=()=>{v||(v=!0,s.value&&(s.value=!1,f.reset(),l?.(),l=null))};return o.signal.addEventListener(`abort`,y,{once:!0}),{ariaActiveDescendant:p,ariaExpanded:c,close:h,dispose:y,get disposed(){return v},focusedIndex:f.focusedIndex,getActiveItem:f.getActiveItem,handleKeydown:e=>s.value?e.key===`Escape`?(e.preventDefault(),h(`escape`),!0):f.handleKeydown(e):!1,isOpen:s,navigate:f.navigate,open:g,scrollFocusedIntoView:d,set:f.set,[Symbol.dispose]:y,toggle:_,updatePosition:u.update}};exports.createListboxDropdown=o;
2
2
  //# sourceMappingURL=option-list.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"option-list.cjs","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n type DropdownCloseReason,\n type OverlayOpenReason,\n restoreTriggerFocus,\n} from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (action, index, event) => {\n scrollFocusedIntoView();\n\n if (index >= 0) options.onNavigate?.(action, index, event);\n },\n orientation: options.orientation,\n signal: options.signal,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreTriggerFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":"mJAgEA,IAAa,EACX,GACuB,CACvB,GAAI,OAAO,EAAQ,aAAgB,WACjC,MAAM,IAAI,EAAA,kBAAkB,gDAAgD,EAG9E,GAAI,OAAO,EAAQ,UAAa,WAC9B,MAAM,IAAI,EAAA,kBAAkB,6CAA6C,EAG3E,GAAI,OAAO,EAAQ,cAAiB,WAClC,MAAM,IAAI,EAAA,kBAAkB,iDAAiD,EAG/E,IAAM,GAAA,EAAS,EAAA,OAAA,CAAO,EAAK,EACrB,GAAA,EAAe,EAAA,SAAA,KAAe,OAAO,EAAO,KAAK,CAAC,EACpD,EAAuC,KAErC,EAAa,EAAA,yBAAyB,CAC1C,GAAG,EAAQ,YACX,YAAa,EAAQ,SACrB,aAAc,EAAQ,YACxB,CAAC,EAEK,MAAoC,CACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,CAAE,MAAO,SAAU,CAAC,CAC1E,EAEM,EAAO,EAAA,kBAAqB,CAChC,UAAA,EAAU,EAAA,SAAA,KAAe,CAAC,EAAO,KAAK,EACtC,aAAc,EAAQ,aACtB,SAAU,EAAQ,SAClB,eAAgB,EAAQ,eACxB,KAAM,EAAQ,KACd,KAAM,EAAQ,MAAQ,GACtB,YAAa,EAAQ,EAAO,IAAU,CACpC,EAAsB,EAElB,GAAS,GAAG,EAAQ,aAAa,EAAQ,EAAO,CAAK,CAC3D,EACA,YAAa,EAAQ,YACrB,OAAQ,EAAQ,MAClB,CAAC,EAEK,GAAA,EAAuB,EAAA,SAAA,KAA8B,CACzD,IAAM,EAAQ,EAAK,aAAa,MAEhC,OAAO,EAAQ,aAAe,EAAO,OAAS,GAAS,EAAI,EAAQ,YAAY,CAAK,EAAI,IAC1F,CAAC,EAEK,MACG,OAAO,EAAQ,cAAiB,WAAa,EAAQ,aAAa,EAAK,EAAQ,cAAgB,GAGlG,GAAS,EAA8B,eAAgB,EAAgB,KAAe,CACrF,EAAO,QAEZ,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,KAEd,GAAiB,EAAmB,GAAK,EAAQ,YAAY,EAAA,oBAAoB,EAAQ,UAAU,EAEvG,EAAQ,UAAU,CAAM,EAC1B,EAEM,GAAQ,EAA4B,iBAAyB,CAC7D,EAAQ,aAAa,GAAK,EAAO,QAErC,EAAO,MAAQ,GACf,EAAW,OAAO,EAClB,EAAkB,EAAW,kBAAkB,GAAK,KACpD,EAAQ,SAAS,CAAM,EACzB,EAEM,GAAU,EAAgC,QAAS,EAAmC,YAAoB,CAC1G,EAAO,MAAO,EAAM,CAAW,EAC9B,EAAK,CAAU,CACtB,EAEA,EAAA,8BAA8B,CAC5B,eAAkB,CAAC,EAAQ,YAAY,EAAG,EAAQ,SAAS,CAAC,EAC5D,aAAgB,EAAO,MACvB,cAAiB,EAAM,cAAc,EACrC,OAAQ,EAAQ,MAClB,CAAC,EAED,IAAI,EAAW,GAET,MAAsB,CACtB,IAEJ,EAAW,GAEP,EAAO,QACT,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,MAEtB,EAiBA,OAfA,EAAQ,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAezD,CACL,uBACA,eACA,QACA,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAAc,EAAK,aACnB,cAAe,EAAK,cACpB,cAvBqB,GAChB,EAAO,MAER,EAAM,MAAQ,UAChB,EAAM,eAAe,EACrB,EAAM,QAAQ,EAEP,IAGF,EAAK,cAAc,CAAK,EATL,GAuB1B,SACA,SAAU,EAAK,SACf,OACA,wBACA,IAAK,EAAK,KACT,OAAO,SAAU,EAClB,SACA,eAAgB,EAAW,MAC7B,CACF"}
1
+ {"version":3,"file":"option-list.cjs","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { restoreFocus } from '@vielzeug/focus';\nimport { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport {\n createListControl,\n type ListNavigationAction,\n type ListNavigationChange,\n type ListNavigationTypeaheadOptions,\n} from './nav';\nimport { createOutsidePointerDismissal, type DropdownCloseReason, type OverlayOpenReason } from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItems: () => readonly T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, readonly string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (change: ListNavigationChange<T>) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n typeahead?: ListNavigationTypeaheadOptions<T>;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (change) => {\n scrollFocusedIntoView();\n options.onNavigate?.(change);\n },\n orientation: options.orientation,\n signal: options.signal,\n typeahead: options.typeahead,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":"gLAiEA,IAAa,EACX,GACuB,CACvB,GAAI,OAAO,EAAQ,aAAgB,WACjC,MAAM,IAAI,EAAA,kBAAkB,gDAAgD,EAG9E,GAAI,OAAO,EAAQ,UAAa,WAC9B,MAAM,IAAI,EAAA,kBAAkB,6CAA6C,EAG3E,GAAI,OAAO,EAAQ,cAAiB,WAClC,MAAM,IAAI,EAAA,kBAAkB,iDAAiD,EAG/E,IAAM,GAAA,EAAS,EAAA,OAAA,CAAO,EAAK,EACrB,GAAA,EAAe,EAAA,SAAA,KAAe,OAAO,EAAO,KAAK,CAAC,EACpD,EAAuC,KAErC,EAAa,EAAA,yBAAyB,CAC1C,GAAG,EAAQ,YACX,YAAa,EAAQ,SACrB,aAAc,EAAQ,YACxB,CAAC,EAEK,MAAoC,CACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,CAAE,MAAO,SAAU,CAAC,CAC1E,EAEM,EAAO,EAAA,kBAAqB,CAChC,UAAA,EAAU,EAAA,SAAA,KAAe,CAAC,EAAO,KAAK,EACtC,SAAU,EAAQ,SAClB,eAAgB,EAAQ,eACxB,KAAM,EAAQ,KACd,KAAM,EAAQ,MAAQ,GACtB,WAAa,GAAW,CACtB,EAAsB,EACtB,EAAQ,aAAa,CAAM,CAC7B,EACA,YAAa,EAAQ,YACrB,OAAQ,EAAQ,OAChB,UAAW,EAAQ,SACrB,CAAC,EAEK,GAAA,EAAuB,EAAA,SAAA,KAA8B,CACzD,IAAM,EAAQ,EAAK,aAAa,MAEhC,OAAO,EAAQ,aAAe,EAAO,OAAS,GAAS,EAAI,EAAQ,YAAY,CAAK,EAAI,IAC1F,CAAC,EAEK,MACG,OAAO,EAAQ,cAAiB,WAAa,EAAQ,aAAa,EAAK,EAAQ,cAAgB,GAGlG,GAAS,EAA8B,eAAgB,EAAgB,KAAe,CACrF,EAAO,QAEZ,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,KAEd,GAAiB,EAAmB,GAAK,EAAQ,aAAY,EAAA,EAAA,aAAA,CAAa,EAAQ,UAAU,EAEhG,EAAQ,UAAU,CAAM,EAC1B,EAEM,GAAQ,EAA4B,iBAAyB,CAC7D,EAAQ,aAAa,GAAK,EAAO,QAErC,EAAO,MAAQ,GACf,EAAW,OAAO,EAClB,EAAkB,EAAW,kBAAkB,GAAK,KACpD,EAAQ,SAAS,CAAM,EACzB,EAEM,GAAU,EAAgC,QAAS,EAAmC,YAAoB,CAC1G,EAAO,MAAO,EAAM,CAAW,EAC9B,EAAK,CAAU,CACtB,EAEA,EAAA,8BAA8B,CAC5B,eAAkB,CAAC,EAAQ,YAAY,EAAG,EAAQ,SAAS,CAAC,EAC5D,aAAgB,EAAO,MACvB,cAAiB,EAAM,cAAc,EACrC,OAAQ,EAAQ,MAClB,CAAC,EAED,IAAI,EAAW,GAET,MAAsB,CACtB,IAEJ,EAAW,GAEP,EAAO,QACT,EAAO,MAAQ,GACf,EAAK,MAAM,EACX,IAAkB,EAClB,EAAkB,MAEtB,EAiBA,OAfA,EAAQ,OAAO,iBAAiB,QAAS,EAAS,CAAE,KAAM,EAAK,CAAC,EAezD,CACL,uBACA,eACA,QACA,UACA,IAAI,UAAW,CACb,OAAO,CACT,EACA,aAAc,EAAK,aACnB,cAAe,EAAK,cACpB,cAvBqB,GAChB,EAAO,MAER,EAAM,MAAQ,UAChB,EAAM,eAAe,EACrB,EAAM,QAAQ,EAEP,IAGF,EAAK,cAAc,CAAK,EATL,GAuB1B,SACA,SAAU,EAAK,SACf,OACA,wBACA,IAAK,EAAK,KACT,OAAO,SAAU,EAClB,SACA,eAAgB,EAAW,MAC7B,CACF"}
@@ -1,5 +1,5 @@
1
1
  import { type Readable } from '@vielzeug/ripple';
2
- import { type ListKeyAction, type ListNavigationAction } from './nav';
2
+ import { type ListNavigationAction, type ListNavigationChange, type ListNavigationTypeaheadOptions } from './nav';
3
3
  import { type DropdownCloseReason, type OverlayOpenReason } from './overlay';
4
4
  import { type DropdownPositionerOptions } from './positioner';
5
5
  export type ListboxItem = object;
@@ -8,23 +8,23 @@ export type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'g
8
8
  export type ListboxDropdownOptions<T extends ListboxItem> = {
9
9
  getBoundary: () => HTMLElement | null;
10
10
  getFocusedOptionElement?: () => HTMLElement | null;
11
- getItemLabel?: (item: T, index: number) => string;
12
- getItems: () => T[];
11
+ getItems: () => readonly T[];
13
12
  getOptionId?: (index: number) => string;
14
13
  getPanel: () => HTMLElement | null;
15
14
  getReference: () => HTMLElement | null;
16
15
  getTrigger?: () => HTMLElement | null;
17
16
  isDisabled?: () => boolean;
18
17
  isItemDisabled?: (item: T, index: number) => boolean;
19
- keys?: Partial<Record<ListNavigationAction, string[]>>;
18
+ keys?: Partial<Record<ListNavigationAction, readonly string[]>>;
20
19
  loop?: boolean;
21
20
  onClose?: (reason: DropdownCloseReason) => void;
22
- onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;
21
+ onNavigate?: (change: ListNavigationChange<T>) => void;
23
22
  onOpen?: (reason: OverlayOpenReason) => void;
24
23
  orientation?: 'both' | 'horizontal' | 'vertical';
25
24
  positioning?: ListboxDropdownPlacementOptions;
26
25
  restoreFocus?: boolean | (() => boolean);
27
26
  signal: AbortSignal;
27
+ typeahead?: ListNavigationTypeaheadOptions<T>;
28
28
  };
29
29
  export type ListboxDropdown<T extends ListboxItem> = {
30
30
  [Symbol.dispose](): void;
@@ -1 +1 @@
1
- {"version":3,"file":"option-list.d.ts","sourceRoot":"","sources":["../../src/core/option-list.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"option-list.d.ts","sourceRoot":"","sources":["../../src/core/option-list.ts"],"names":[],"mappings":"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"}
@@ -1,36 +1,37 @@
1
1
  import { RefineConfigError as e } from "../errors.js";
2
- import { createOutsidePointerDismissal as t, restoreTriggerFocus as n } from "./overlay.js";
3
- import { createListControl as r } from "./nav.js";
4
- import { createDropdownPositioner as i } from "./positioner.js";
5
- import { computed as a, signal as o } from "@vielzeug/ripple";
2
+ import { createOutsidePointerDismissal as t } from "./overlay.js";
3
+ import { createListControl as n } from "./nav.js";
4
+ import { createDropdownPositioner as r } from "./positioner.js";
5
+ import { computed as i, signal as a } from "@vielzeug/ripple";
6
+ import { restoreFocus as o } from "@vielzeug/focus";
6
7
  //#region src/core/option-list.ts
7
8
  var s = (s) => {
8
9
  if (typeof s.getBoundary != "function") throw new e("createListboxDropdown: getBoundary is required");
9
10
  if (typeof s.getPanel != "function") throw new e("createListboxDropdown: getPanel is required");
10
11
  if (typeof s.getReference != "function") throw new e("createListboxDropdown: getReference is required");
11
- let c = o(!1), l = a(() => String(c.value)), u = null, d = i({
12
+ let c = a(!1), l = i(() => String(c.value)), u = null, d = r({
12
13
  ...s.positioning,
13
14
  getFloating: s.getPanel,
14
15
  getReference: s.getReference
15
16
  }), f = () => {
16
17
  s.getFocusedOptionElement?.()?.scrollIntoView({ block: "nearest" });
17
- }, p = r({
18
- disabled: a(() => !c.value),
19
- getItemLabel: s.getItemLabel,
18
+ }, p = n({
19
+ disabled: i(() => !c.value),
20
20
  getItems: s.getItems,
21
21
  isItemDisabled: s.isItemDisabled,
22
22
  keys: s.keys,
23
23
  loop: s.loop ?? !0,
24
- onNavigate: (e, t, n) => {
25
- f(), t >= 0 && s.onNavigate?.(e, t, n);
24
+ onNavigate: (e) => {
25
+ f(), s.onNavigate?.(e);
26
26
  },
27
27
  orientation: s.orientation,
28
- signal: s.signal
29
- }), m = a(() => {
28
+ signal: s.signal,
29
+ typeahead: s.typeahead
30
+ }), m = i(() => {
30
31
  let e = p.focusedIndex.value;
31
32
  return s.getOptionId && c.value && e >= 0 ? s.getOptionId(e) : null;
32
33
  }), h = () => typeof s.restoreFocus == "function" ? s.restoreFocus() : s.restoreFocus ?? !0, g = (e = "programmatic", t = !0) => {
33
- c.value && (c.value = !1, p.reset(), u?.(), u = null, t && h() && s.getTrigger && n(s.getTrigger), s.onClose?.(e));
34
+ c.value && (c.value = !1, p.reset(), u?.(), u = null, t && h() && s.getTrigger && o(s.getTrigger), s.onClose?.(e));
34
35
  }, _ = (e = "programmatic") => {
35
36
  s.isDisabled?.() || c.value || (c.value = !0, d.update(), u = d.startAutoUpdate?.() ?? null, s.onOpen?.(e));
36
37
  }, v = (e = "click", t = "trigger") => {
@@ -1 +1 @@
1
- {"version":3,"file":"option-list.js","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport { createListControl, type ListKeyAction, type ListNavigationAction } from './nav';\nimport {\n createOutsidePointerDismissal,\n type DropdownCloseReason,\n type OverlayOpenReason,\n restoreTriggerFocus,\n} from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItemLabel?: (item: T, index: number) => string;\n getItems: () => T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (action: ListKeyAction, index: number, event?: KeyboardEvent) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItemLabel: options.getItemLabel,\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (action, index, event) => {\n scrollFocusedIntoView();\n\n if (index >= 0) options.onNavigate?.(action, index, event);\n },\n orientation: options.orientation,\n signal: options.signal,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreTriggerFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":";;;;;;AAgEA,IAAa,KACX,MACuB;CACvB,IAAI,OAAO,EAAQ,eAAgB,YACjC,MAAM,IAAI,EAAkB,gDAAgD;CAG9E,IAAI,OAAO,EAAQ,YAAa,YAC9B,MAAM,IAAI,EAAkB,6CAA6C;CAG3E,IAAI,OAAO,EAAQ,gBAAiB,YAClC,MAAM,IAAI,EAAkB,iDAAiD;CAG/E,IAAM,IAAS,EAAO,EAAK,GACrB,IAAe,QAAe,OAAO,EAAO,KAAK,CAAC,GACpD,IAAuC,MAErC,IAAa,EAAyB;EAC1C,GAAG,EAAQ;EACX,aAAa,EAAQ;EACrB,cAAc,EAAQ;CACxB,CAAC,GAEK,UAAoC;EACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,EAAE,OAAO,UAAU,CAAC;CAC1E,GAEM,IAAO,EAAqB;EAChC,UAAU,QAAe,CAAC,EAAO,KAAK;EACtC,cAAc,EAAQ;EACtB,UAAU,EAAQ;EAClB,gBAAgB,EAAQ;EACxB,MAAM,EAAQ;EACd,MAAM,EAAQ,QAAQ;EACtB,aAAa,GAAQ,GAAO,MAAU;GAGpC,AAFA,EAAsB,GAElB,KAAS,KAAG,EAAQ,aAAa,GAAQ,GAAO,CAAK;EAC3D;EACA,aAAa,EAAQ;EACrB,QAAQ,EAAQ;CAClB,CAAC,GAEK,IAAuB,QAA8B;EACzD,IAAM,IAAQ,EAAK,aAAa;EAEhC,OAAO,EAAQ,eAAe,EAAO,SAAS,KAAS,IAAI,EAAQ,YAAY,CAAK,IAAI;CAC1F,CAAC,GAEK,UACG,OAAO,EAAQ,gBAAiB,aAAa,EAAQ,aAAa,IAAK,EAAQ,gBAAgB,IAGlG,KAAS,IAA8B,gBAAgB,IAAgB,OAAe;EACrF,EAAO,UAEZ,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB,MAEd,KAAiB,EAAmB,KAAK,EAAQ,cAAY,EAAoB,EAAQ,UAAU,GAEvG,EAAQ,UAAU,CAAM;CAC1B,GAEM,KAAQ,IAA4B,mBAAyB;EAC7D,EAAQ,aAAa,KAAK,EAAO,UAErC,EAAO,QAAQ,IACf,EAAW,OAAO,GAClB,IAAkB,EAAW,kBAAkB,KAAK,MACpD,EAAQ,SAAS,CAAM;CACzB,GAEM,KAAU,IAAgC,SAAS,IAAmC,cAAoB;EAC9G,AAAI,EAAO,QAAO,EAAM,CAAW,IAC9B,EAAK,CAAU;CACtB;CAEA,EAA8B;EAC5B,kBAAkB,CAAC,EAAQ,YAAY,GAAG,EAAQ,SAAS,CAAC;EAC5D,gBAAgB,EAAO;EACvB,iBAAiB,EAAM,cAAc;EACrC,QAAQ,EAAQ;CAClB,CAAC;CAED,IAAI,IAAW,IAET,UAAsB;EACtB,MAEJ,IAAW,IAEP,EAAO,UACT,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB;CAEtB;CAiBA,OAfA,EAAQ,OAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,GAezD;EACL;EACA;EACA;EACA;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,cAAc,EAAK;EACnB,eAAe,EAAK;EACpB,gBAvBqB,MAChB,EAAO,QAER,EAAM,QAAQ,YAChB,EAAM,eAAe,GACrB,EAAM,QAAQ,GAEP,MAGF,EAAK,cAAc,CAAK,IATL;EAuB1B;EACA,UAAU,EAAK;EACf;EACA;EACA,KAAK,EAAK;GACT,OAAO,UAAU;EAClB;EACA,gBAAgB,EAAW;CAC7B;AACF"}
1
+ {"version":3,"file":"option-list.js","names":[],"sources":["../../src/core/option-list.ts"],"sourcesContent":["import { restoreFocus } from '@vielzeug/focus';\nimport { computed, type Readable, signal } from '@vielzeug/ripple';\n\nimport { RefineConfigError } from '../errors';\nimport {\n createListControl,\n type ListNavigationAction,\n type ListNavigationChange,\n type ListNavigationTypeaheadOptions,\n} from './nav';\nimport { createOutsidePointerDismissal, type DropdownCloseReason, type OverlayOpenReason } from './overlay';\nimport { createDropdownPositioner, type DropdownPositionerOptions } from './positioner';\n\nexport type ListboxItem = object;\n\n/** Placement-only options for the listbox dropdown positioner. */\nexport type ListboxDropdownPlacementOptions = Omit<DropdownPositionerOptions, 'getFloating' | 'getReference'>;\n\nexport type ListboxDropdownOptions<T extends ListboxItem> = {\n getBoundary: () => HTMLElement | null;\n getFocusedOptionElement?: () => HTMLElement | null;\n getItems: () => readonly T[];\n getOptionId?: (index: number) => string;\n getPanel: () => HTMLElement | null;\n getReference: () => HTMLElement | null;\n getTrigger?: () => HTMLElement | null;\n isDisabled?: () => boolean;\n isItemDisabled?: (item: T, index: number) => boolean;\n keys?: Partial<Record<ListNavigationAction, readonly string[]>>;\n loop?: boolean;\n onClose?: (reason: DropdownCloseReason) => void;\n onNavigate?: (change: ListNavigationChange<T>) => void;\n onOpen?: (reason: OverlayOpenReason) => void;\n orientation?: 'both' | 'horizontal' | 'vertical';\n positioning?: ListboxDropdownPlacementOptions;\n restoreFocus?: boolean | (() => boolean);\n signal: AbortSignal;\n typeahead?: ListNavigationTypeaheadOptions<T>;\n};\n\nexport type ListboxDropdown<T extends ListboxItem> = {\n [Symbol.dispose](): void;\n readonly ariaActiveDescendant: Readable<string | null>;\n readonly ariaExpanded: Readable<string>;\n close(reason?: DropdownCloseReason): void;\n /** Closes the dropdown (without restoring focus) and disposes list navigation state. */\n dispose(): void;\n /** `true` after `dispose()` has been called. */\n readonly disposed: boolean;\n readonly focusedIndex: Readable<number>;\n getActiveItem(): T | undefined;\n handleKeydown(event: KeyboardEvent): boolean;\n readonly isOpen: Readable<boolean>;\n navigate(action: ListNavigationAction): number;\n open(reason?: OverlayOpenReason): void;\n scrollFocusedIntoView(): void;\n set(index: number): number;\n toggle(openReason?: OverlayOpenReason, closeReason?: DropdownCloseReason): void;\n updatePosition(): void;\n};\n\n/**\n * Internal listbox dropdown behavior for select and combobox. It owns only\n * listbox interactions; menu and other overlay families keep their own logic.\n */\nexport const createListboxDropdown = <T extends ListboxItem>(\n options: ListboxDropdownOptions<T>,\n): ListboxDropdown<T> => {\n if (typeof options.getBoundary !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getBoundary is required');\n }\n\n if (typeof options.getPanel !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getPanel is required');\n }\n\n if (typeof options.getReference !== 'function') {\n throw new RefineConfigError('createListboxDropdown: getReference is required');\n }\n\n const isOpen = signal(false);\n const ariaExpanded = computed(() => String(isOpen.value));\n let stopPositioning: (() => void) | null = null;\n\n const positioner = createDropdownPositioner({\n ...options.positioning,\n getFloating: options.getPanel,\n getReference: options.getReference,\n });\n\n const scrollFocusedIntoView = (): void => {\n options.getFocusedOptionElement?.()?.scrollIntoView({ block: 'nearest' });\n };\n\n const list = createListControl<T>({\n disabled: computed(() => !isOpen.value),\n getItems: options.getItems,\n isItemDisabled: options.isItemDisabled,\n keys: options.keys,\n loop: options.loop ?? true,\n onNavigate: (change) => {\n scrollFocusedIntoView();\n options.onNavigate?.(change);\n },\n orientation: options.orientation,\n signal: options.signal,\n typeahead: options.typeahead,\n });\n\n const ariaActiveDescendant = computed<string | null>(() => {\n const index = list.focusedIndex.value;\n\n return options.getOptionId && isOpen.value && index >= 0 ? options.getOptionId(index) : null;\n });\n\n const shouldRestoreFocus = (): boolean => {\n return typeof options.restoreFocus === 'function' ? options.restoreFocus() : (options.restoreFocus ?? true);\n };\n\n const close = (reason: DropdownCloseReason = 'programmatic', shouldRestore = true): void => {\n if (!isOpen.value) return;\n\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n\n if (shouldRestore && shouldRestoreFocus() && options.getTrigger) restoreFocus(options.getTrigger);\n\n options.onClose?.(reason);\n };\n\n const open = (reason: OverlayOpenReason = 'programmatic'): void => {\n if (options.isDisabled?.() || isOpen.value) return;\n\n isOpen.value = true;\n positioner.update();\n stopPositioning = positioner.startAutoUpdate?.() ?? null;\n options.onOpen?.(reason);\n };\n\n const toggle = (openReason: OverlayOpenReason = 'click', closeReason: DropdownCloseReason = 'trigger'): void => {\n if (isOpen.value) close(closeReason);\n else open(openReason);\n };\n\n createOutsidePointerDismissal({\n getTargets: () => [options.getBoundary(), options.getPanel()],\n isActive: () => isOpen.value,\n onDismiss: () => close('outsideClick'),\n signal: options.signal,\n });\n\n let disposed = false;\n\n const dispose = (): void => {\n if (disposed) return;\n\n disposed = true;\n\n if (isOpen.value) {\n isOpen.value = false;\n list.reset();\n stopPositioning?.();\n stopPositioning = null;\n }\n };\n\n options.signal.addEventListener('abort', dispose, { once: true });\n\n const handleKeydown = (event: KeyboardEvent): boolean => {\n if (!isOpen.value) return false;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n close('escape');\n\n return true;\n }\n\n return list.handleKeydown(event);\n };\n\n return {\n ariaActiveDescendant,\n ariaExpanded,\n close,\n dispose,\n get disposed() {\n return disposed;\n },\n focusedIndex: list.focusedIndex,\n getActiveItem: list.getActiveItem,\n handleKeydown,\n isOpen,\n navigate: list.navigate,\n open,\n scrollFocusedIntoView,\n set: list.set,\n [Symbol.dispose]: dispose,\n toggle,\n updatePosition: positioner.update,\n };\n};\n"],"mappings":";;;;;;;AAiEA,IAAa,KACX,MACuB;CACvB,IAAI,OAAO,EAAQ,eAAgB,YACjC,MAAM,IAAI,EAAkB,gDAAgD;CAG9E,IAAI,OAAO,EAAQ,YAAa,YAC9B,MAAM,IAAI,EAAkB,6CAA6C;CAG3E,IAAI,OAAO,EAAQ,gBAAiB,YAClC,MAAM,IAAI,EAAkB,iDAAiD;CAG/E,IAAM,IAAS,EAAO,EAAK,GACrB,IAAe,QAAe,OAAO,EAAO,KAAK,CAAC,GACpD,IAAuC,MAErC,IAAa,EAAyB;EAC1C,GAAG,EAAQ;EACX,aAAa,EAAQ;EACrB,cAAc,EAAQ;CACxB,CAAC,GAEK,UAAoC;EACxC,EAAQ,0BAA0B,CAAC,EAAE,eAAe,EAAE,OAAO,UAAU,CAAC;CAC1E,GAEM,IAAO,EAAqB;EAChC,UAAU,QAAe,CAAC,EAAO,KAAK;EACtC,UAAU,EAAQ;EAClB,gBAAgB,EAAQ;EACxB,MAAM,EAAQ;EACd,MAAM,EAAQ,QAAQ;EACtB,aAAa,MAAW;GAEtB,AADA,EAAsB,GACtB,EAAQ,aAAa,CAAM;EAC7B;EACA,aAAa,EAAQ;EACrB,QAAQ,EAAQ;EAChB,WAAW,EAAQ;CACrB,CAAC,GAEK,IAAuB,QAA8B;EACzD,IAAM,IAAQ,EAAK,aAAa;EAEhC,OAAO,EAAQ,eAAe,EAAO,SAAS,KAAS,IAAI,EAAQ,YAAY,CAAK,IAAI;CAC1F,CAAC,GAEK,UACG,OAAO,EAAQ,gBAAiB,aAAa,EAAQ,aAAa,IAAK,EAAQ,gBAAgB,IAGlG,KAAS,IAA8B,gBAAgB,IAAgB,OAAe;EACrF,EAAO,UAEZ,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB,MAEd,KAAiB,EAAmB,KAAK,EAAQ,cAAY,EAAa,EAAQ,UAAU,GAEhG,EAAQ,UAAU,CAAM;CAC1B,GAEM,KAAQ,IAA4B,mBAAyB;EAC7D,EAAQ,aAAa,KAAK,EAAO,UAErC,EAAO,QAAQ,IACf,EAAW,OAAO,GAClB,IAAkB,EAAW,kBAAkB,KAAK,MACpD,EAAQ,SAAS,CAAM;CACzB,GAEM,KAAU,IAAgC,SAAS,IAAmC,cAAoB;EAC9G,AAAI,EAAO,QAAO,EAAM,CAAW,IAC9B,EAAK,CAAU;CACtB;CAEA,EAA8B;EAC5B,kBAAkB,CAAC,EAAQ,YAAY,GAAG,EAAQ,SAAS,CAAC;EAC5D,gBAAgB,EAAO;EACvB,iBAAiB,EAAM,cAAc;EACrC,QAAQ,EAAQ;CAClB,CAAC;CAED,IAAI,IAAW,IAET,UAAsB;EACtB,MAEJ,IAAW,IAEP,EAAO,UACT,EAAO,QAAQ,IACf,EAAK,MAAM,GACX,IAAkB,GAClB,IAAkB;CAEtB;CAiBA,OAfA,EAAQ,OAAO,iBAAiB,SAAS,GAAS,EAAE,MAAM,GAAK,CAAC,GAezD;EACL;EACA;EACA;EACA;EACA,IAAI,WAAW;GACb,OAAO;EACT;EACA,cAAc,EAAK;EACnB,eAAe,EAAK;EACpB,gBAvBqB,MAChB,EAAO,QAER,EAAM,QAAQ,YAChB,EAAM,eAAe,GACrB,EAAM,QAAQ,GAEP,MAGF,EAAK,cAAc,CAAK,IATL;EAuB1B;EACA,UAAU,EAAK;EACf;EACA;EACA,KAAK,EAAK;GACT,OAAO,UAAU;EAClB;EACA,gBAAgB,EAAW;CAC7B;AACF"}
@@ -1,2 +1,2 @@
1
- var e=e=>{let t=t=>{if(!e.isActive())return;let n=t.composedPath(),r=n[0]instanceof Node?n[0]:t.target instanceof Node?t.target:null;e.getTargets().some(e=>e!=null&&(n.includes(e)||!!(r&&e.contains(r))))||e.onDismiss()},n=()=>{document.removeEventListener(`pointerdown`,t,{capture:!0})};return document.addEventListener(`pointerdown`,t,{capture:!0}),e.signal.addEventListener(`abort`,n,{once:!0}),n},t=e=>{e()?.focus()};exports.createOutsidePointerDismissal=e,exports.restoreTriggerFocus=t;
1
+ var e=e=>{let t=t=>{if(!e.isActive())return;let n=t.composedPath(),r=n[0]instanceof Node?n[0]:t.target instanceof Node?t.target:null;e.getTargets().some(e=>e!=null&&(n.includes(e)||!!(r&&e.contains(r))))||e.onDismiss()},n=()=>{document.removeEventListener(`pointerdown`,t,{capture:!0})};return document.addEventListener(`pointerdown`,t,{capture:!0}),e.signal.addEventListener(`abort`,n,{once:!0}),n};exports.createOutsidePointerDismissal=e;
2
2
  //# sourceMappingURL=overlay.cjs.map