@reactzero/combo 0.1.0

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 (124) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +188 -0
  4. package/dist/Combo-Cx3kSkop.cjs +2 -0
  5. package/dist/Combo-Cx3kSkop.cjs.map +1 -0
  6. package/dist/Combo-qs6_L512.js +439 -0
  7. package/dist/Combo-qs6_L512.js.map +1 -0
  8. package/dist/components/Combo.d.ts +71 -0
  9. package/dist/components/Combo.d.ts.map +1 -0
  10. package/dist/components/LiveRegion.d.ts +7 -0
  11. package/dist/components/LiveRegion.d.ts.map +1 -0
  12. package/dist/components/Portal.d.ts +8 -0
  13. package/dist/components/Portal.d.ts.map +1 -0
  14. package/dist/components/slots/CheckboxItem.d.ts +38 -0
  15. package/dist/components/slots/CheckboxItem.d.ts.map +1 -0
  16. package/dist/components/slots/CustomItem.d.ts +35 -0
  17. package/dist/components/slots/CustomItem.d.ts.map +1 -0
  18. package/dist/components/slots/FooterActions.d.ts +42 -0
  19. package/dist/components/slots/FooterActions.d.ts.map +1 -0
  20. package/dist/components/slots/GroupSeparator.d.ts +30 -0
  21. package/dist/components/slots/GroupSeparator.d.ts.map +1 -0
  22. package/dist/components/slots/index.d.ts +9 -0
  23. package/dist/components/slots/index.d.ts.map +1 -0
  24. package/dist/components/tabs/TabbedCombo.d.ts +45 -0
  25. package/dist/components/tabs/TabbedCombo.d.ts.map +1 -0
  26. package/dist/components/tabs/index.d.ts +3 -0
  27. package/dist/components/tabs/index.d.ts.map +1 -0
  28. package/dist/core/announce.d.ts +10 -0
  29. package/dist/core/announce.d.ts.map +1 -0
  30. package/dist/core/ids.d.ts +13 -0
  31. package/dist/core/ids.d.ts.map +1 -0
  32. package/dist/core/keyboard.d.ts +13 -0
  33. package/dist/core/keyboard.d.ts.map +1 -0
  34. package/dist/core/scroll.d.ts +5 -0
  35. package/dist/core/scroll.d.ts.map +1 -0
  36. package/dist/core/stateMachine.d.ts +32 -0
  37. package/dist/core/stateMachine.d.ts.map +1 -0
  38. package/dist/core/utils.d.ts +26 -0
  39. package/dist/core/utils.d.ts.map +1 -0
  40. package/dist/defaults-iFGq2Q-7.cjs +2 -0
  41. package/dist/defaults-iFGq2Q-7.cjs.map +1 -0
  42. package/dist/defaults-rhC5DFTg.js +53 -0
  43. package/dist/defaults-rhC5DFTg.js.map +1 -0
  44. package/dist/entries/hook-bare.d.ts +4 -0
  45. package/dist/entries/hook-bare.d.ts.map +1 -0
  46. package/dist/entries/hook.d.ts +4 -0
  47. package/dist/entries/hook.d.ts.map +1 -0
  48. package/dist/entries/icons.d.ts +4 -0
  49. package/dist/entries/icons.d.ts.map +1 -0
  50. package/dist/entries/index.d.ts +9 -0
  51. package/dist/entries/index.d.ts.map +1 -0
  52. package/dist/entries/position.d.ts +3 -0
  53. package/dist/entries/position.d.ts.map +1 -0
  54. package/dist/entries/slots.d.ts +9 -0
  55. package/dist/entries/slots.d.ts.map +1 -0
  56. package/dist/entries/tabs.d.ts +4 -0
  57. package/dist/entries/tabs.d.ts.map +1 -0
  58. package/dist/hook-bare.cjs +2 -0
  59. package/dist/hook-bare.cjs.map +1 -0
  60. package/dist/hook-bare.js +9 -0
  61. package/dist/hook-bare.js.map +1 -0
  62. package/dist/hook.cjs +2 -0
  63. package/dist/hook.cjs.map +1 -0
  64. package/dist/hook.js +11 -0
  65. package/dist/hook.js.map +1 -0
  66. package/dist/hooks/useCombo.d.ts +3 -0
  67. package/dist/hooks/useCombo.d.ts.map +1 -0
  68. package/dist/hooks/usePosition.d.ts +16 -0
  69. package/dist/hooks/usePosition.d.ts.map +1 -0
  70. package/dist/icons/defaults.d.ts +16 -0
  71. package/dist/icons/defaults.d.ts.map +1 -0
  72. package/dist/icons/icons.d.ts +30 -0
  73. package/dist/icons/icons.d.ts.map +1 -0
  74. package/dist/icons-Ch1Q5AhF.js +40 -0
  75. package/dist/icons-Ch1Q5AhF.js.map +1 -0
  76. package/dist/icons-vzkEacAb.cjs +2 -0
  77. package/dist/icons-vzkEacAb.cjs.map +1 -0
  78. package/dist/icons.cjs +2 -0
  79. package/dist/icons.cjs.map +1 -0
  80. package/dist/icons.js +20 -0
  81. package/dist/icons.js.map +1 -0
  82. package/dist/index.cjs +2 -0
  83. package/dist/index.cjs.map +1 -0
  84. package/dist/index.d.ts +2 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +12 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/position.cjs +2 -0
  89. package/dist/position.cjs.map +1 -0
  90. package/dist/position.js +5 -0
  91. package/dist/position.js.map +1 -0
  92. package/dist/slots.cjs +2 -0
  93. package/dist/slots.cjs.map +1 -0
  94. package/dist/slots.js +92 -0
  95. package/dist/slots.js.map +1 -0
  96. package/dist/style.css +1 -0
  97. package/dist/styles/base.css +205 -0
  98. package/dist/styles/checkbox.css +36 -0
  99. package/dist/styles/chips.css +71 -0
  100. package/dist/styles/custom-item.css +64 -0
  101. package/dist/styles/footer.css +73 -0
  102. package/dist/styles/groups.css +23 -0
  103. package/dist/styles/meta.css +30 -0
  104. package/dist/styles/radio.css +36 -0
  105. package/dist/styles/select.css +35 -0
  106. package/dist/styles/states.css +22 -0
  107. package/dist/tabs.cjs +2 -0
  108. package/dist/tabs.cjs.map +1 -0
  109. package/dist/tabs.js +132 -0
  110. package/dist/tabs.js.map +1 -0
  111. package/dist/themes/dark.css +96 -0
  112. package/dist/themes/default.css +126 -0
  113. package/dist/themes/high-contrast.css +98 -0
  114. package/dist/types.d.ts +168 -0
  115. package/dist/types.d.ts.map +1 -0
  116. package/dist/useCombo-D_vriwVz.cjs +2 -0
  117. package/dist/useCombo-D_vriwVz.cjs.map +1 -0
  118. package/dist/useCombo-gPeBdkRf.js +887 -0
  119. package/dist/useCombo-gPeBdkRf.js.map +1 -0
  120. package/dist/usePosition-6GfutqGX.cjs +2 -0
  121. package/dist/usePosition-6GfutqGX.cjs.map +1 -0
  122. package/dist/usePosition-DVw8IlwA.js +36 -0
  123. package/dist/usePosition-DVw8IlwA.js.map +1 -0
  124. package/package.json +219 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2025-03-25
9
+
10
+ ### Added
11
+
12
+ - **`useCombo` hook** — Headless hook with 9 prop getters, 8 imperative actions, full state exposure
13
+ - `getInputProps`, `getToggleButtonProps`, `getLabelProps`, `getClearButtonProps`, `getMenuProps`, `getItemProps`, `getGroupProps`, `getChevronProps`, `getTriggerProps`
14
+ - Actions: `openMenu`, `closeMenu`, `toggleMenu`, `selectItem`, `removeItem`, `clearSelection`, `setInputValue`, `reset`
15
+ - **`<Combo>` component** — Pre-built component with render props
16
+ - `renderItem`, `renderEmpty`, `renderLoading`, `renderError`, `renderFooter`, `renderTrigger`, `renderGroupHeader`
17
+ - `classNames` slots for all sub-elements
18
+ - `label` prop with automatic `<label>` association
19
+ - `variant="select"` for non-editable dropdown
20
+ - `groups` prop for grouped item rendering
21
+ - `theme` prop for built-in theme switching
22
+ - **Portal component** — Renders listbox in a portal to escape overflow containers
23
+ - **LiveRegion component** — ARIA live region for screen reader announcements
24
+ - **Pure state machine** — 7 status states, 16+ actions, pure reducer
25
+ - **Keyboard navigation** — ArrowUp/Down, Enter, Escape, Home, End, Tab
26
+ - **CSS custom properties** — 40+ design tokens for full visual customization
27
+ - **Built-in themes** — Default, dark, and high-contrast
28
+ - **Icon system** — 5 swappable icon slots + 6 chevron styles (caret, arrow, angle, plusminus, dots, none)
29
+ - **Dual entry points** — `@reactzero/combo/hook` (4.2 kB) and `@reactzero/combo` (5.5 kB)
30
+ - **332 tests** — Full coverage with jest-axe accessibility validation
31
+ - **TypeScript** — Full generic type inference
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 motiondesignlv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # @reactzero/combo
2
+
3
+ Headless, accessible React combo & select. **Zero dependencies.** ARIA 1.2 compliant, < 7 kB gzipped.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@reactzero/combo)](https://www.npmjs.com/package/@reactzero/combo)
6
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/@reactzero/combo)](https://bundlephobia.com/package/@reactzero/combo)
7
+ [![license](https://img.shields.io/npm/l/@reactzero/combo)](./LICENSE)
8
+
9
+ ## Features
10
+
11
+ - **Zero dependencies** — Only peer depends on React 18+. No runtime surprises.
12
+ - **Headless architecture** — Full control over markup and styling via the `useCombo` hook
13
+ - **Pre-built component** — Drop-in `<Combo>` with render props for quick setup
14
+ - **ARIA 1.2 compliant** — Keyboard navigation, screen reader support, live region announcements
15
+ - **Tiny bundle** — Hook: 4.8 kB, Full: 6.7 kB, CSS: 2.5 kB (all brotli)
16
+ - **CSS custom properties** — 40+ design tokens, built-in dark and high-contrast themes
17
+ - **TypeScript first** — Full generic type inference on all APIs
18
+ - **Multiple variants** — Combobox, select dropdown, grouped items, custom triggers
19
+
20
+ ## AI Reference
21
+
22
+ Download the [AI reference file](./ai-reference.md) and feed it to your AI coding assistant for complete API docs, examples, and patterns.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ npm install @reactzero/combo
28
+ ```
29
+
30
+ ## Quick Start — Headless Hook
31
+
32
+ ```tsx
33
+ import { useCombo } from '@reactzero/combo/hook';
34
+
35
+ function MyCombo() {
36
+ const items = ['Apple', 'Banana', 'Cherry', 'Date'];
37
+
38
+ const {
39
+ isOpen,
40
+ filteredItems,
41
+ highlightedIndex,
42
+ selectedItem,
43
+ getLabelProps,
44
+ getInputProps,
45
+ getToggleButtonProps,
46
+ getClearButtonProps,
47
+ getMenuProps,
48
+ getItemProps,
49
+ getChevronProps,
50
+ hasSelection,
51
+ icons,
52
+ chevronIcon,
53
+ } = useCombo({ items });
54
+
55
+ return (
56
+ <div>
57
+ <label {...getLabelProps()}>Fruit</label>
58
+ <div>
59
+ <input {...getInputProps({ placeholder: 'Search...' })} />
60
+ {hasSelection && <button {...getClearButtonProps()}>{icons.clear}</button>}
61
+ <button {...getToggleButtonProps()}>
62
+ <span {...getChevronProps()}>{chevronIcon}</span>
63
+ </button>
64
+ </div>
65
+ <ul {...getMenuProps()} style={{ display: isOpen ? 'block' : 'none' }}>
66
+ {isOpen &&
67
+ filteredItems.map((item, index) => (
68
+ <li
69
+ key={index}
70
+ {...getItemProps({ item, index })}
71
+ style={{
72
+ background: highlightedIndex === index ? '#dbeafe' : 'transparent',
73
+ fontWeight: selectedItem === item ? 600 : 400,
74
+ }}
75
+ >
76
+ {String(item)}
77
+ </li>
78
+ ))}
79
+ </ul>
80
+ </div>
81
+ );
82
+ }
83
+ ```
84
+
85
+ ## Quick Start — Pre-built Component
86
+
87
+ ```tsx
88
+ import { Combo } from '@reactzero/combo';
89
+ import '@reactzero/combo/styles';
90
+
91
+ function App() {
92
+ return (
93
+ <Combo
94
+ items={['Apple', 'Banana', 'Cherry', 'Date']}
95
+ label="Favorite Fruit"
96
+ placeholder="Search fruits..."
97
+ onSelectedItemChange={(item) => console.log('Selected:', item)}
98
+ renderItem={({ item, isHighlighted, isSelected }) => (
99
+ <div style={{ fontWeight: isSelected ? 600 : 400 }}>
100
+ {String(item)}
101
+ </div>
102
+ )}
103
+ />
104
+ );
105
+ }
106
+ ```
107
+
108
+ ## Import Paths
109
+
110
+ | Path | Size | Description |
111
+ |------|------|-------------|
112
+ | `@reactzero/combo/hook` | 4.8 kB | Hook + types only |
113
+ | `@reactzero/combo` | 6.7 kB | Hook + Combo + Portal + LiveRegion |
114
+ | `@reactzero/combo/styles` | 2.5 kB | Base structural CSS |
115
+ | `@reactzero/combo/themes/dark.css` | — | Dark theme tokens |
116
+ | `@reactzero/combo/themes/high-contrast.css` | — | High-contrast theme tokens |
117
+
118
+ ## Variants
119
+
120
+ ### Select Dropdown
121
+
122
+ ```tsx
123
+ <Combo
124
+ items={['United States', 'Canada', 'Mexico']}
125
+ variant="select"
126
+ placeholder="Choose a country..."
127
+ />
128
+ ```
129
+
130
+ ### Grouped Items
131
+
132
+ ```tsx
133
+ <Combo
134
+ groups={[
135
+ { label: 'Fruits', items: ['Apple', 'Banana'] },
136
+ { label: 'Vegetables', items: ['Carrot', 'Broccoli'] },
137
+ ]}
138
+ items={[]}
139
+ placeholder="Search..."
140
+ />
141
+ ```
142
+
143
+ ### Custom Trigger
144
+
145
+ ```tsx
146
+ <Combo
147
+ items={items}
148
+ renderTrigger={({ getInputProps, getToggleButtonProps, isOpen, chevronIcon }) => (
149
+ <div className="my-trigger">
150
+ <input {...getInputProps()} />
151
+ <button {...getToggleButtonProps()}>{chevronIcon}</button>
152
+ </div>
153
+ )}
154
+ />
155
+ ```
156
+
157
+ ## Theming
158
+
159
+ Override CSS custom properties to customize the appearance:
160
+
161
+ ```css
162
+ .my-combobox {
163
+ --rzero-combo-input-border: 2px solid #6366f1;
164
+ --rzero-combo-input-focus-ring: 0 0 0 3px rgba(99, 102, 241, 0.3);
165
+ --rzero-combo-item-highlighted-bg: #e0e7ff;
166
+ --rzero-combo-item-selected-color: #4f46e5;
167
+ }
168
+ ```
169
+
170
+ Or use built-in themes:
171
+
172
+ ```tsx
173
+ <Combo items={items} theme="dark" />
174
+ ```
175
+
176
+ ## Documentation
177
+
178
+ - [Getting Started](https://reactzero-combo.dev/guide/getting-started)
179
+ - [Headless Usage](https://reactzero-combo.dev/guide/headless-usage)
180
+ - [Pre-built Component](https://reactzero-combo.dev/guide/pre-built)
181
+ - [Theming](https://reactzero-combo.dev/guide/theming)
182
+ - [Accessibility](https://reactzero-combo.dev/guide/accessibility)
183
+ - [API Reference — useCombo](https://reactzero-combo.dev/api/use-combo)
184
+ - [API Reference — Combo](https://reactzero-combo.dev/api/combo)
185
+
186
+ ## License
187
+
188
+ [MIT](./LICENSE)
@@ -0,0 +1,2 @@
1
+ "use strict";const e=require("react/jsx-runtime"),f=require("react"),Te=require("./useCombo-D_vriwVz.cjs"),Ie=require("./usePosition-6GfutqGX.cjs"),Pe=require("react-dom");function re({children:c,target:g,disabled:h}){if(h)return e.jsx(e.Fragment,{children:c});const d=g??(typeof document<"u"?document.body:null);return d?Pe.createPortal(c,d):null}const we={position:"absolute",width:"1px",height:"1px",padding:0,margin:"-1px",overflow:"hidden",clip:"rect(0,0,0,0)",whiteSpace:"nowrap",borderWidth:0};function oe({message:c,id:g,clearAfterMs:h=3e3}){const d=f.useRef(null);return f.useEffect(()=>{if(!d.current||!c)return;const p=d.current;p.textContent="";const I=requestAnimationFrame(()=>{p.textContent=c}),P=setTimeout(()=>{p.textContent=""},h);return()=>{cancelAnimationFrame(I),clearTimeout(P)}},[c,h]),e.jsx("div",{ref:d,id:g,role:"status","aria-live":"polite","aria-atomic":"true",style:we})}function l(...c){return c.filter(Boolean).join(" ")}function De(c){const{placeholder:g,label:h,theme:d,itemVariant:p,renderItem:I,renderEmpty:P,renderLoading:V,renderError:K,renderFooter:U,renderTrigger:A,renderGroupHeader:G,renderListHeader:W,hintText:O,errorText:w,minSelected:b,onInputKeyDown:J,classNames:n={},...r}=c,ne=f.useMemo(()=>r.groups&&!r.items?.length?r.groups.flatMap(t=>t.items):r.items,[r.groups,r.items]),se=Te.useCombo({...r,items:ne}),{isOpen:a,selectedItem:D,highlightedIndex:ae,filteredItems:j,hasSelection:v,triggerLabel:M,isLoading:x,isError:z,error:le,getLabelProps:ie,getInputProps:B,getToggleButtonProps:H,getClearButtonProps:k,getMenuProps:ce,getItemProps:Q,getGroupProps:de,getChevronProps:C,getTriggerProps:X,icons:R,chevronIcon:L,inputRef:Y,listboxRef:ue,triggerRef:me,inputValue:ge,openMenu:he,closeMenu:pe,clearSelection:be,removeItem:xe,selectedItems:m}=se,q=r.itemToString??(t=>t!=null?String(t):""),u=r.itemToValue??(t=>typeof t=="object"&&t!=null&&"value"in t?t.value:String(t)),fe=r.isItemDisabled??(()=>!1),Z=r.variant==="select",S=r.mode==="multi",E=z||!!w,_=f.useRef(null),je=Z?me:S?_:Y,y=Ie.usePosition({triggerRef:je,listboxRef:ue,isOpen:a}),ve=f.useMemo(()=>{if(!a)return"";if(x)return"Loading options...";const t=j.length;return t===0?"No options available":`${t} option${t!==1?"s":""} available`},[a,x,j.length]),Ne=d?{"data-rzero-theme":d}:{},N=r.disabled===!0,ee=f.useMemo(()=>{const t=new Map;return j.forEach((o,s)=>{t.set(u(o),s)}),t},[j,u]),$=f.useMemo(()=>r.groups?r.groups.map((t,o)=>{const s=t.items.map(i=>({item:i,globalIndex:ee.get(u(i))})).filter(i=>i.globalIndex!==void 0);return{group:t,groupIdx:o,items:s}}).filter(t=>t.items.length>0):null,[r.groups,ee,u]);function te(t,o){const s=ae===o,i=S?m.some(ye=>u(ye)===u(t)):D!=null&&u(D)===u(t),T=fe(t),F=p&&p!=="default"?p:void 0;return I?e.jsx("li",{...Q({item:t,index:o,variant:F}),className:l("rzero-combo-item",n.item,s&&n.itemHighlighted,i&&n.itemSelected,T&&n.itemDisabled),children:I({item:t,index:o,isHighlighted:s,isSelected:i,isDisabled:T})},o):e.jsxs("li",{...Q({item:t,index:o,variant:F}),className:l("rzero-combo-item",n.item,s&&n.itemHighlighted,i&&n.itemSelected,T&&n.itemDisabled),children:[e.jsx("span",{children:q(t)}),i&&!F&&e.jsx("span",{className:"rzero-combo-check","aria-hidden":"true",children:R.check})]},o)}function ze(){if(S)return e.jsxs("div",{ref:_,className:l("rzero-combo-trigger","rzero-combo-trigger--multi",n.trigger),"data-rzero-trigger":"","data-disabled":N||void 0,"data-readonly":r.readOnly||void 0,"data-loading":r.disabled==="loading"||void 0,"data-error":E||void 0,onClick:o=>{if(N||r.readOnly)return;const s=o.target;s.tagName==="INPUT"||s.tagName==="BUTTON"||s.closest("button")||(Y.current?.focus(),a||he())},onMouseDown:o=>{o.target.tagName!=="INPUT"&&o.preventDefault()},children:[e.jsxs("div",{className:"rzero-combo-trigger-content",children:[m.map(o=>e.jsxs("span",{className:"rzero-combo-chip",children:[e.jsx("span",{className:"rzero-combo-chip-label",children:q(o)}),!N&&!r.readOnly&&e.jsx("button",{type:"button",className:"rzero-combo-chip-remove","aria-label":`Remove ${q(o)}`,onMouseDown:s=>s.preventDefault(),onClick:s=>{s.stopPropagation(),xe(o)},children:e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",children:e.jsx("path",{d:"M18 6 6 18M6 6l12 12"})})})]},String(u(o)))),e.jsx("input",{...B({placeholder:m.length===0?g:"",className:n.input,onKeyDown:J})})]}),e.jsxs("div",{className:"rzero-combo-trigger-actions",children:[v&&!N&&!r.readOnly&&e.jsx("button",{...k({className:n.clearButton}),children:R.clear}),e.jsx("button",{...H({className:n.toggleButton}),children:e.jsx("span",{...C(),children:L})})]})]});const t=v&&a&&ge!==M;return e.jsxs("div",{className:l("rzero-combo-trigger",n.trigger),"data-rzero-trigger":"","data-disabled":N||void 0,"data-readonly":r.readOnly||void 0,"data-loading":r.disabled==="loading"||void 0,"data-error":E||void 0,"data-has-hidden-selection":t||void 0,children:[e.jsx("input",{...B({placeholder:v?M:g,className:n.input,onKeyDown:J})}),v&&!N&&!r.readOnly&&e.jsx("button",{...k({className:n.clearButton}),children:R.clear}),e.jsx("button",{...H({className:n.toggleButton}),children:e.jsx("span",{...C(),children:L})})]})}function Se(){return e.jsxs("button",{...X({className:l("rzero-combo-select-trigger",n.trigger),"data-error":E||void 0}),children:[e.jsx("span",{className:"rzero-combo-select-value",children:v?M:g||"Select..."}),e.jsx("span",{...C(),children:L})]})}return e.jsxs("div",{className:l("rzero-combo",n.root),...Ne,"data-rzero-root":"",children:[h&&e.jsx("label",{...ie({className:l("rzero-combo-label",n.label)}),children:h}),A?A({getInputProps:B,getToggleButtonProps:H,getTriggerProps:X,getClearButtonProps:k,getChevronProps:C,selectedItem:D,hasSelection:v,triggerLabel:M,isOpen:a,icons:R,chevronIcon:L}):Z?Se():ze(),(w||O||S&&(b!=null||r.maxSelected!=null))&&e.jsxs("div",{className:"rzero-combo-meta",children:[w?e.jsx("span",{className:"rzero-combo-error-text",children:w}):O?e.jsx("span",{className:"rzero-combo-hint",children:O}):e.jsx("span",{}),S&&(b!=null||r.maxSelected!=null)&&e.jsxs("span",{className:"rzero-combo-selection-count","data-warning":b!=null&&m.length<b||r.maxSelected!=null&&m.length>=r.maxSelected?"":void 0,children:[m.length,r.maxSelected!=null?` / ${r.maxSelected}`:"",b!=null&&m.length<b?` · min ${b}`:""]})]}),e.jsx(re,{disabled:r.disablePortal,target:r.portalTarget,children:e.jsxs("ul",{...ce({className:l("rzero-combo-list",n.list),style:a?{position:"absolute",top:y.top,left:y.left,width:y.width,maxHeight:y.maxHeight,overflow:"auto",zIndex:"var(--rzero-combo-z-index, 9999)",margin:0}:{display:"none"}}),"data-state":a?"open":"closed","data-placement":y.placement,hidden:!a,children:[a&&W&&e.jsx("li",{role:"presentation",children:W()}),a&&x&&e.jsx("li",{role:"presentation",className:l("rzero-combo-loading",n.loadingState),children:V?V():"Loading..."}),a&&!x&&z&&K&&e.jsx("li",{role:"presentation",className:l("rzero-combo-error",n.errorState),children:K({error:le})}),a&&!x&&!z&&j.length===0&&e.jsx("li",{role:"presentation",className:l("rzero-combo-empty",n.emptyState),children:P?P():"No results found"}),a&&!x&&!z&&$&&$.map(({group:t,groupIdx:o,items:s})=>e.jsxs("li",{role:"presentation",children:[e.jsx("div",{...de({group:t,index:o}),className:l("rzero-combo-group-header",n.groupHeader),children:G?G({group:t,index:o}):t.label}),e.jsx("ul",{role:"group","aria-label":t.label,style:{listStyle:"none",margin:0,padding:0},children:s.map(({item:i,globalIndex:T})=>te(i,T))})]},`group-${o}`)),a&&!x&&!z&&!$&&j.map((t,o)=>te(t,o)),a&&U&&e.jsx("li",{role:"presentation",className:l("rzero-combo-footer",n.footer),children:U({selectedItem:D,selectedItems:m,closeMenu:pe,clearSelection:be})})]})}),e.jsx(oe,{message:ve})]})}exports.Combo=De;exports.LiveRegion=oe;exports.Portal=re;
2
+ //# sourceMappingURL=Combo-Cx3kSkop.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Combo-Cx3kSkop.cjs","sources":["../src/components/Portal.tsx","../src/components/LiveRegion.tsx","../src/components/Combo.tsx"],"sourcesContent":["import { createPortal } from 'react-dom';\nimport type { ReactNode } from 'react';\n\nexport interface PortalProps {\n children: ReactNode;\n target?: Element | null;\n disabled?: boolean;\n}\n\nexport function Portal({ children, target, disabled }: PortalProps) {\n if (disabled) return <>{children}</>;\n\n const mountNode =\n target ?? (typeof document !== 'undefined' ? document.body : null);\n if (!mountNode) return null;\n\n return createPortal(children, mountNode);\n}\n","import { useEffect, useRef } from 'react';\n\nexport interface LiveRegionProps {\n message: string;\n id?: string;\n clearAfterMs?: number;\n}\n\nconst srOnlyStyle: React.CSSProperties = {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: 0,\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0,0,0,0)',\n whiteSpace: 'nowrap',\n borderWidth: 0,\n};\n\nexport function LiveRegion({\n message,\n id,\n clearAfterMs = 3000,\n}: LiveRegionProps) {\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!ref.current || !message) return;\n const el = ref.current;\n // Clear then set — forces screen readers to re-announce\n el.textContent = '';\n const raf = requestAnimationFrame(() => {\n el.textContent = message;\n });\n const timer = setTimeout(() => {\n el.textContent = '';\n }, clearAfterMs);\n return () => {\n cancelAnimationFrame(raf);\n clearTimeout(timer);\n };\n }, [message, clearAfterMs]);\n\n return (\n <div\n ref={ref}\n id={id}\n role=\"status\"\n aria-live=\"polite\"\n aria-atomic=\"true\"\n style={srOnlyStyle}\n />\n );\n}\n","import React, { useMemo, useRef } from 'react';\nimport { useCombo } from '../hooks/useCombo';\nimport { usePosition } from '../hooks/usePosition';\nimport { Portal } from './Portal';\nimport { LiveRegion } from './LiveRegion';\nimport type {\n UseComboOptions,\n UseComboReturn,\n ComboGroup,\n IconSlots,\n} from '../types';\n\nexport interface ComboClassNames {\n root?: string;\n label?: string;\n input?: string;\n trigger?: string;\n popover?: string;\n list?: string;\n item?: string;\n itemSelected?: string;\n itemHighlighted?: string;\n itemDisabled?: string;\n clearButton?: string;\n toggleButton?: string;\n groupHeader?: string;\n loadingState?: string;\n emptyState?: string;\n errorState?: string;\n footer?: string;\n}\n\nexport type ItemVariant = 'default' | 'checkbox' | 'radio';\n\nexport interface ComboProps<T> extends UseComboOptions<T> {\n placeholder?: string;\n label?: string;\n theme?: 'default' | 'dark' | 'high-contrast' | 'system';\n itemVariant?: ItemVariant;\n renderItem?: (props: {\n item: T;\n index: number;\n isHighlighted: boolean;\n isSelected: boolean;\n isDisabled: boolean;\n }) => React.ReactNode;\n renderEmpty?: () => React.ReactNode;\n renderLoading?: () => React.ReactNode;\n renderError?: (props: { error: Error | null }) => React.ReactNode;\n renderFooter?: (props: {\n selectedItem: T | null;\n selectedItems: T[];\n closeMenu: () => void;\n clearSelection: () => void;\n }) => React.ReactNode;\n renderTrigger?: (props: {\n getInputProps: UseComboReturn<T>['getInputProps'];\n getToggleButtonProps: UseComboReturn<T>['getToggleButtonProps'];\n getTriggerProps: UseComboReturn<T>['getTriggerProps'];\n getClearButtonProps: UseComboReturn<T>['getClearButtonProps'];\n getChevronProps: UseComboReturn<T>['getChevronProps'];\n selectedItem: T | null;\n hasSelection: boolean;\n triggerLabel: string;\n isOpen: boolean;\n icons: IconSlots;\n chevronIcon: React.ReactNode;\n }) => React.ReactNode;\n renderGroupHeader?: (props: {\n group: ComboGroup<T>;\n index: number;\n }) => React.ReactNode;\n renderListHeader?: () => React.ReactNode;\n hintText?: string;\n errorText?: string;\n minSelected?: number;\n onInputKeyDown?: (e: React.KeyboardEvent) => void;\n classNames?: ComboClassNames;\n}\n\nfunction cx(...args: (string | false | null | undefined)[]): string {\n return args.filter(Boolean).join(' ');\n}\n\nexport function Combo<T>(props: ComboProps<T>) {\n const {\n placeholder,\n label,\n theme,\n itemVariant,\n renderItem,\n renderEmpty,\n renderLoading,\n renderError,\n renderFooter,\n renderTrigger,\n renderGroupHeader,\n renderListHeader,\n hintText,\n errorText,\n minSelected,\n onInputKeyDown,\n classNames = {},\n ...hookOptions\n } = props;\n\n // When groups are provided, flatten into items for the hook\n const flatItems = useMemo(() => {\n if (hookOptions.groups && !hookOptions.items?.length) {\n return hookOptions.groups.flatMap((g) => g.items);\n }\n return hookOptions.items;\n }, [hookOptions.groups, hookOptions.items]);\n\n const combo = useCombo({ ...hookOptions, items: flatItems });\n const {\n isOpen,\n selectedItem,\n highlightedIndex,\n filteredItems,\n hasSelection,\n triggerLabel,\n isLoading,\n isError,\n error,\n getLabelProps,\n getInputProps,\n getToggleButtonProps,\n getClearButtonProps,\n getMenuProps,\n getItemProps,\n getGroupProps,\n getChevronProps,\n getTriggerProps,\n icons,\n chevronIcon,\n inputRef,\n listboxRef,\n triggerRef,\n inputValue,\n openMenu,\n closeMenu,\n clearSelection,\n removeItem,\n selectedItems,\n } = combo;\n\n const itemToString =\n hookOptions.itemToString ??\n ((item: T | null) => (item != null ? String(item) : ''));\n const itemToValue =\n hookOptions.itemToValue ??\n ((item: T) => {\n if (\n typeof item === 'object' &&\n item != null &&\n 'value' in (item as object)\n )\n return (item as Record<string, unknown>).value as string | number;\n return String(item);\n });\n const isItemDisabled = hookOptions.isItemDisabled ?? (() => false);\n const isSelectVariant = hookOptions.variant === 'select';\n const isMultiMode = hookOptions.mode === 'multi';\n const hasError = isError || !!errorText;\n\n // Stable ref for the multi-select trigger container so the popover\n // anchors to the outer div rather than the input (which shifts as chips wrap).\n const multiTriggerRef = useRef<HTMLDivElement>(null);\n\n const positionTriggerRef = isSelectVariant\n ? triggerRef\n : isMultiMode\n ? multiTriggerRef\n : inputRef;\n\n const position = usePosition({\n triggerRef: positionTriggerRef,\n listboxRef,\n isOpen,\n });\n\n const liveMessage = useMemo(() => {\n if (!isOpen) return '';\n if (isLoading) return 'Loading options...';\n const count = filteredItems.length;\n return count === 0\n ? 'No options available'\n : `${count} option${count !== 1 ? 's' : ''} available`;\n }, [isOpen, isLoading, filteredItems.length]);\n\n const themeAttr = theme ? { 'data-rzero-theme': theme } : {};\n const isDisabled = hookOptions.disabled === true;\n\n // Build a value → filteredItems index map for grouped rendering\n const valueToIndex = useMemo(() => {\n const map = new Map<string | number, number>();\n filteredItems.forEach((item, index) => {\n map.set(itemToValue(item), index);\n });\n return map;\n }, [filteredItems, itemToValue]);\n\n // Compute grouped items with global indices\n const groupedItems = useMemo(() => {\n if (!hookOptions.groups) return null;\n return hookOptions.groups\n .map((group, groupIdx) => {\n const items = group.items\n .map((item) => ({\n item,\n globalIndex: valueToIndex.get(itemToValue(item)),\n }))\n .filter(\n (entry): entry is { item: T; globalIndex: number } =>\n entry.globalIndex !== undefined,\n );\n return { group, groupIdx, items };\n })\n .filter((g) => g.items.length > 0);\n }, [hookOptions.groups, valueToIndex, itemToValue]);\n\n // Shared item renderer\n\n function renderItemLi(item: T, index: number) {\n const isHighlighted = highlightedIndex === index;\n const isSelected = isMultiMode\n ? selectedItems.some((si: T) => itemToValue(si) === itemToValue(item))\n : selectedItem != null &&\n itemToValue(selectedItem) === itemToValue(item);\n const itemDisabled = isItemDisabled(item);\n\n const variantForItem =\n itemVariant && itemVariant !== 'default' ? itemVariant : undefined;\n\n if (renderItem) {\n return (\n <li\n key={index}\n {...getItemProps({ item, index, variant: variantForItem })}\n className={cx(\n 'rzero-combo-item',\n classNames.item,\n isHighlighted && classNames.itemHighlighted,\n isSelected && classNames.itemSelected,\n itemDisabled && classNames.itemDisabled,\n )}\n >\n {renderItem({\n item,\n index,\n isHighlighted,\n isSelected,\n isDisabled: itemDisabled,\n })}\n </li>\n );\n }\n\n return (\n <li\n key={index}\n {...getItemProps({ item, index, variant: variantForItem })}\n className={cx(\n 'rzero-combo-item',\n classNames.item,\n isHighlighted && classNames.itemHighlighted,\n isSelected && classNames.itemSelected,\n itemDisabled && classNames.itemDisabled,\n )}\n >\n <span>{itemToString(item)}</span>\n {isSelected && !variantForItem && (\n <span className=\"rzero-combo-check\" aria-hidden=\"true\">\n {icons.check}\n </span>\n )}\n </li>\n );\n }\n\n // Default trigger (input variant)\n function renderDefaultTrigger() {\n if (isMultiMode) {\n return (\n <div\n ref={multiTriggerRef}\n className={cx('rzero-combo-trigger', 'rzero-combo-trigger--multi', classNames.trigger)}\n data-rzero-trigger=\"\"\n data-disabled={isDisabled || undefined}\n data-readonly={hookOptions.readOnly || undefined}\n data-loading={hookOptions.disabled === 'loading' || undefined}\n data-error={hasError || undefined}\n onClick={(e) => {\n if (isDisabled || hookOptions.readOnly) return;\n // Only handle clicks on the container itself, not on input/buttons\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'BUTTON' || target.closest('button')) return;\n inputRef.current?.focus();\n if (!isOpen) openMenu();\n }}\n onMouseDown={(e) => {\n // Prevent blur when clicking the container (not input)\n const target = e.target as HTMLElement;\n if (target.tagName !== 'INPUT') {\n e.preventDefault();\n }\n }}\n >\n <div className=\"rzero-combo-trigger-content\">\n {selectedItems.map((item: T) => (\n <span className=\"rzero-combo-chip\" key={String(itemToValue(item))}>\n <span className=\"rzero-combo-chip-label\">{itemToString(item)}</span>\n {!isDisabled && !hookOptions.readOnly && (\n <button\n type=\"button\"\n className=\"rzero-combo-chip-remove\"\n aria-label={`Remove ${itemToString(item)}`}\n onMouseDown={(e) => e.preventDefault()}\n onClick={(e) => {\n e.stopPropagation();\n removeItem(item);\n }}\n >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\">\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n </button>\n )}\n </span>\n ))}\n <input\n {...getInputProps({\n placeholder: selectedItems.length === 0 ? placeholder : '',\n className: classNames.input,\n onKeyDown: onInputKeyDown,\n } as Record<string, unknown>)}\n />\n </div>\n\n <div className=\"rzero-combo-trigger-actions\">\n {hasSelection && !isDisabled && !hookOptions.readOnly && (\n <button\n {...getClearButtonProps({\n className: classNames.clearButton,\n } as Record<string, unknown>)}\n >\n {icons.clear}\n </button>\n )}\n\n <button\n {...getToggleButtonProps({\n className: classNames.toggleButton,\n } as Record<string, unknown>)}\n >\n <span {...getChevronProps()}>{chevronIcon}</span>\n </button>\n </div>\n </div>\n );\n }\n\n const hasHiddenSelection = hasSelection && isOpen && inputValue !== triggerLabel;\n\n return (\n <div\n className={cx('rzero-combo-trigger', classNames.trigger)}\n data-rzero-trigger=\"\"\n data-disabled={isDisabled || undefined}\n data-readonly={hookOptions.readOnly || undefined}\n data-loading={hookOptions.disabled === 'loading' || undefined}\n data-error={hasError || undefined}\n data-has-hidden-selection={hasHiddenSelection || undefined}\n >\n <input\n {...getInputProps({\n placeholder: hasSelection ? triggerLabel : placeholder,\n className: classNames.input,\n onKeyDown: onInputKeyDown,\n } as Record<string, unknown>)}\n />\n\n {hasSelection && !isDisabled && !hookOptions.readOnly && (\n <button\n {...getClearButtonProps({\n className: classNames.clearButton,\n } as Record<string, unknown>)}\n >\n {icons.clear}\n </button>\n )}\n\n <button\n {...getToggleButtonProps({\n className: classNames.toggleButton,\n } as Record<string, unknown>)}\n >\n <span {...getChevronProps()}>{chevronIcon}</span>\n </button>\n </div>\n );\n }\n\n // Select variant trigger\n function renderSelectTrigger() {\n return (\n <button\n {...getTriggerProps({\n className: cx('rzero-combo-select-trigger', classNames.trigger),\n 'data-error': hasError || undefined,\n } as Record<string, unknown>)}\n >\n <span className=\"rzero-combo-select-value\">\n {hasSelection ? triggerLabel : placeholder || 'Select...'}\n </span>\n <span {...getChevronProps()}>{chevronIcon}</span>\n </button>\n );\n }\n\n return (\n <div\n className={cx('rzero-combo', classNames.root)}\n {...themeAttr}\n data-rzero-root=\"\"\n >\n {/* Label */}\n {label && (\n <label\n {...getLabelProps({\n className: cx('rzero-combo-label', classNames.label),\n } as Record<string, unknown>)}\n >\n {label}\n </label>\n )}\n\n {/* Trigger */}\n {renderTrigger\n ? renderTrigger({\n getInputProps,\n getToggleButtonProps,\n getTriggerProps,\n getClearButtonProps,\n getChevronProps,\n selectedItem,\n hasSelection,\n triggerLabel,\n isOpen,\n icons,\n chevronIcon,\n })\n : isSelectVariant\n ? renderSelectTrigger()\n : renderDefaultTrigger()}\n\n {/* Meta row: hint/error text + selection count */}\n {(errorText || hintText || (isMultiMode && (minSelected != null || hookOptions.maxSelected != null))) && (\n <div className=\"rzero-combo-meta\">\n {errorText ? (\n <span className=\"rzero-combo-error-text\">{errorText}</span>\n ) : hintText ? (\n <span className=\"rzero-combo-hint\">{hintText}</span>\n ) : (\n <span />\n )}\n {isMultiMode && (minSelected != null || hookOptions.maxSelected != null) && (\n <span\n className=\"rzero-combo-selection-count\"\n data-warning={\n (minSelected != null && selectedItems.length < minSelected) ||\n (hookOptions.maxSelected != null && selectedItems.length >= hookOptions.maxSelected)\n ? ''\n : undefined\n }\n >\n {selectedItems.length}\n {hookOptions.maxSelected != null ? ` / ${hookOptions.maxSelected}` : ''}\n {minSelected != null && selectedItems.length < minSelected\n ? ` \\u00B7 min ${minSelected}`\n : ''}\n </span>\n )}\n </div>\n )}\n\n {/* Popover */}\n <Portal\n disabled={hookOptions.disablePortal}\n target={hookOptions.portalTarget}\n >\n <ul\n {...getMenuProps({\n className: cx('rzero-combo-list', classNames.list),\n style: isOpen\n ? ({\n position: 'absolute',\n top: position.top,\n left: position.left,\n width: position.width,\n maxHeight: position.maxHeight,\n overflow: 'auto',\n zIndex: 'var(--rzero-combo-z-index, 9999)',\n margin: 0,\n } as React.CSSProperties)\n : ({ display: 'none' } as React.CSSProperties),\n } as Record<string, unknown>)}\n data-state={isOpen ? 'open' : 'closed'}\n data-placement={position.placement}\n hidden={!isOpen}\n >\n {/* List header (e.g. tab strip) */}\n {isOpen && renderListHeader && (\n <li role=\"presentation\">\n {renderListHeader()}\n </li>\n )}\n\n {/* Loading */}\n {isOpen && isLoading && (\n <li\n role=\"presentation\"\n className={cx('rzero-combo-loading', classNames.loadingState)}\n >\n {renderLoading ? renderLoading() : 'Loading...'}\n </li>\n )}\n\n {/* Error */}\n {isOpen && !isLoading && isError && renderError && (\n <li\n role=\"presentation\"\n className={cx('rzero-combo-error', classNames.errorState)}\n >\n {renderError({ error })}\n </li>\n )}\n\n {/* Empty */}\n {isOpen &&\n !isLoading &&\n !isError &&\n filteredItems.length === 0 && (\n <li\n role=\"presentation\"\n className={cx('rzero-combo-empty', classNames.emptyState)}\n >\n {renderEmpty ? renderEmpty() : 'No results found'}\n </li>\n )}\n\n {/* Items — grouped rendering */}\n {isOpen &&\n !isLoading &&\n !isError &&\n groupedItems &&\n groupedItems.map(({ group, groupIdx, items }) => (\n <li key={`group-${groupIdx}`} role=\"presentation\">\n <div\n {...getGroupProps({ group, index: groupIdx })}\n className={cx(\n 'rzero-combo-group-header',\n classNames.groupHeader,\n )}\n >\n {renderGroupHeader\n ? renderGroupHeader({ group, index: groupIdx })\n : group.label}\n </div>\n <ul role=\"group\" aria-label={group.label} style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {items.map(({ item, globalIndex }) =>\n renderItemLi(item, globalIndex),\n )}\n </ul>\n </li>\n ))}\n\n {/* Items — flat rendering (no groups) */}\n {isOpen &&\n !isLoading &&\n !isError &&\n !groupedItems &&\n filteredItems.map((item, index) => renderItemLi(item, index))}\n\n {/* Footer */}\n {isOpen && renderFooter && (\n <li\n role=\"presentation\"\n className={cx('rzero-combo-footer', classNames.footer)}\n >\n {renderFooter({\n selectedItem,\n selectedItems,\n closeMenu,\n clearSelection,\n })}\n </li>\n )}\n </ul>\n </Portal>\n\n {/* Live region */}\n <LiveRegion message={liveMessage} />\n </div>\n );\n}\n"],"names":["Portal","children","target","disabled","jsx","Fragment","mountNode","createPortal","srOnlyStyle","LiveRegion","message","id","clearAfterMs","ref","useRef","useEffect","el","raf","timer","cx","args","Combo","props","placeholder","label","theme","itemVariant","renderItem","renderEmpty","renderLoading","renderError","renderFooter","renderTrigger","renderGroupHeader","renderListHeader","hintText","errorText","minSelected","onInputKeyDown","classNames","hookOptions","flatItems","useMemo","g","combo","useCombo","isOpen","selectedItem","highlightedIndex","filteredItems","hasSelection","triggerLabel","isLoading","isError","error","getLabelProps","getInputProps","getToggleButtonProps","getClearButtonProps","getMenuProps","getItemProps","getGroupProps","getChevronProps","getTriggerProps","icons","chevronIcon","inputRef","listboxRef","triggerRef","inputValue","openMenu","closeMenu","clearSelection","removeItem","selectedItems","itemToString","item","itemToValue","isItemDisabled","isSelectVariant","isMultiMode","hasError","multiTriggerRef","positionTriggerRef","position","usePosition","liveMessage","count","themeAttr","isDisabled","valueToIndex","map","index","groupedItems","group","groupIdx","items","entry","renderItemLi","isHighlighted","isSelected","si","itemDisabled","variantForItem","jsxs","renderDefaultTrigger","e","hasHiddenSelection","renderSelectTrigger","globalIndex"],"mappings":"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"}