@telegraph/combobox 0.0.76 → 0.0.78

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @telegraph/combobox
2
2
 
3
+ ## 0.0.78
4
+
5
+ ### Patch Changes
6
+
7
+ - [#439](https://github.com/knocklabs/telegraph/pull/439) [`0dcbd65`](https://github.com/knocklabs/telegraph/commit/0dcbd65ba294edd97cdc4159533a8516433cd3c9) Thanks [@kylemcd](https://github.com/kylemcd)! - add combobox primitive trigger components
8
+
9
+ - Updated dependencies [[`0dcbd65`](https://github.com/knocklabs/telegraph/commit/0dcbd65ba294edd97cdc4159533a8516433cd3c9)]:
10
+ - @telegraph/button@0.0.77
11
+ - @telegraph/tag@0.0.82
12
+ - @telegraph/menu@0.0.62
13
+
14
+ ## 0.0.77
15
+
16
+ ### Patch Changes
17
+
18
+ - [#434](https://github.com/knocklabs/telegraph/pull/434) [`955c255`](https://github.com/knocklabs/telegraph/commit/955c25512468a67717de9e56a6b49f72ff53279e) Thanks [@kylemcd](https://github.com/kylemcd)! - adds support for custom triggers in the combobox
19
+
20
+ - Updated dependencies [[`955c255`](https://github.com/knocklabs/telegraph/commit/955c25512468a67717de9e56a6b49f72ff53279e)]:
21
+ - @telegraph/helpers@0.0.12
22
+ - @telegraph/button@0.0.76
23
+ - @telegraph/icon@0.0.50
24
+ - @telegraph/input@0.0.42
25
+ - @telegraph/layout@0.1.16
26
+ - @telegraph/menu@0.0.61
27
+ - @telegraph/tag@0.0.81
28
+ - @telegraph/tooltip@0.0.44
29
+ - @telegraph/typography@0.1.16
30
+
3
31
  ## 0.0.76
4
32
 
5
33
  ### Patch Changes
package/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@telegraph/button.svg)](https://www.npmjs.com/package/@telegraph/combobox)
4
4
 
5
5
  # @telegraph/combobox
6
+
6
7
  > A styled menu, triggered by a Select, that combines an Input and Single- or Multi-select.
7
8
 
8
9
  ## Installation Instructions
@@ -12,6 +13,479 @@ npm install @telegraph/combobox
12
13
  ```
13
14
 
14
15
  ### Add stylesheet
16
+
15
17
  ```
16
18
  @import "@telegraph/combobox"
17
19
  ```
20
+
21
+ ### Basic Usage
22
+
23
+ A combobox component that combines input and select functionality with a searchable dropdown menu.
24
+
25
+ #### `<Combobox/>`
26
+
27
+ ```tsx
28
+ import { Combobox } from "@telegraph/combobox";
29
+ import { useState } from "react";
30
+
31
+ // Single select example
32
+ const SingleSelectExample = () => {
33
+ const [value, setValue] = useState<string>("");
34
+
35
+ return (
36
+ <Combobox.Root value={value} onValueChange={setValue}>
37
+ <Combobox.Trigger placeholder="Select an option..." />
38
+ <Combobox.Content>
39
+ <Combobox.Search />
40
+ <Combobox.Options>
41
+ <Combobox.Option value="option1">Option 1</Combobox.Option>
42
+ <Combobox.Option value="option2">Option 2</Combobox.Option>
43
+ </Combobox.Options>
44
+ </Combobox.Content>
45
+ </Combobox.Root>
46
+ );
47
+ };
48
+
49
+ // Multi select example
50
+ const MultiSelectExample = () => {
51
+ const [values, setValues] = useState<string[]>([]);
52
+
53
+ return (
54
+ <Combobox.Root value={values} onValueChange={setValues}>
55
+ <Combobox.Trigger placeholder="Select options..." />
56
+ <Combobox.Content>
57
+ <Combobox.Search />
58
+ <Combobox.Options>
59
+ <Combobox.Option value="option1">Option 1</Combobox.Option>
60
+ <Combobox.Option value="option2">Option 2</Combobox.Option>
61
+ </Combobox.Options>
62
+ </Combobox.Content>
63
+ </Combobox.Root>
64
+ );
65
+ };
66
+ ```
67
+
68
+ ### Type Examples
69
+
70
+ #### Single Select Types
71
+
72
+ ```tsx
73
+ // String values (recommended)
74
+ const [value, setValue] = useState<string>("");
75
+ ```
76
+
77
+ #### Multi Select Types
78
+
79
+ ```tsx
80
+ // String array values (recommended)
81
+ const [values, setValues] = useState<string[]>([]);
82
+ ```
83
+
84
+ ### Accessibility
85
+
86
+ The combobox implements the [ARIA Combobox Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/), providing:
87
+
88
+ - Proper ARIA roles and attributes
89
+ - Keyboard navigation:
90
+ - `↓` / `↑`: Navigate options
91
+ - `Enter` / `Space`: Select option
92
+ - `Escape`: Close dropdown
93
+ - `Tab`: Move focus
94
+ - Screen reader announcements for selection changes
95
+ - Focus management
96
+
97
+ ### Common Patterns
98
+
99
+ #### Form Integration
100
+
101
+ ```tsx
102
+ import { useForm } from "react-hook-form";
103
+
104
+ const MyForm = () => {
105
+ const { register, setValue } = useForm();
106
+
107
+ return (
108
+ <form>
109
+ <Combobox.Root onValueChange={(value) => setValue("field", value)}>
110
+ {/* ... */}
111
+ </Combobox.Root>
112
+ </form>
113
+ );
114
+ };
115
+ ```
116
+
117
+ #### Custom Filtering
118
+
119
+ ```tsx
120
+ const MyCombobox = () => {
121
+ const [searchQuery, setSearchQuery] = useState("");
122
+ const options = useMemo(
123
+ () =>
124
+ allOptions.filter((opt) =>
125
+ opt.toLowerCase().includes(searchQuery.toLowerCase()),
126
+ ),
127
+ [searchQuery],
128
+ );
129
+
130
+ return (
131
+ <Combobox.Root>
132
+ <Combobox.Content>
133
+ <Combobox.Search value={searchQuery} onValueChange={setSearchQuery} />
134
+ <Combobox.Options>
135
+ {options.map((opt) => (
136
+ <Combobox.Option key={opt} value={opt}>
137
+ {opt}
138
+ </Combobox.Option>
139
+ ))}
140
+ </Combobox.Options>
141
+ </Combobox.Content>
142
+ </Combobox.Root>
143
+ );
144
+ };
145
+ ```
146
+
147
+ #### Async Loading
148
+
149
+ ```tsx
150
+ const AsyncCombobox = () => {
151
+ const [isLoading, setIsLoading] = useState(false);
152
+ const [options, setOptions] = useState([]);
153
+
154
+ const loadOptions = async (query) => {
155
+ setIsLoading(true);
156
+ const results = await fetchOptions(query);
157
+ setOptions(results);
158
+ setIsLoading(false);
159
+ };
160
+
161
+ return (
162
+ <Combobox.Root>
163
+ <Combobox.Content>
164
+ <Combobox.Search onValueChange={loadOptions} />
165
+ <Combobox.Options>
166
+ {isLoading ? (
167
+ <Box p="4" textAlign="center">
168
+ Loading...
169
+ </Box>
170
+ ) : (
171
+ options.map((opt) => (
172
+ <Combobox.Option key={opt} value={opt}>
173
+ {opt}
174
+ </Combobox.Option>
175
+ ))
176
+ )}
177
+ </Combobox.Options>
178
+ </Combobox.Content>
179
+ </Combobox.Root>
180
+ );
181
+ };
182
+ ```
183
+
184
+ #### Error States
185
+
186
+ ```tsx
187
+ const ErrorCombobox = () => {
188
+ const [error, setError] = useState("");
189
+
190
+ return (
191
+ <Stack gap="1">
192
+ <Combobox.Root errored={!!error}>{/* ... */}</Combobox.Root>
193
+ {error && (
194
+ <Text color="red" size="1">
195
+ {error}
196
+ </Text>
197
+ )}
198
+ </Stack>
199
+ );
200
+ };
201
+ ```
202
+
203
+ ### Component Parts
204
+
205
+ #### `<Combobox.Root/>`
206
+
207
+ The root component that manages the state and context for the combobox.
208
+
209
+ ##### Props
210
+
211
+ | Name | Type | Default | Description |
212
+ | -------------- | --------------------------------------------------------- | ---------- | ---------------------------------- |
213
+ | value | string \| string[] \| Option \| Option[] | undefined | The selected value(s) |
214
+ | onValueChange | (value: string \| string[] \| Option \| Option[]) => void | undefined | Callback when selection changes |
215
+ | layout | "truncate" \| "wrap" | "truncate" | How to display multiple selections |
216
+ | open | boolean | undefined | Controlled open state |
217
+ | defaultOpen | boolean | false | Initial open state |
218
+ | errored | boolean | false | Shows error styling |
219
+ | placeholder | string | undefined | Placeholder text |
220
+ | onOpenChange | (open: boolean) => void | undefined | Callback when open state changes |
221
+ | modal | boolean | true | Whether to render in a modal |
222
+ | closeOnSelect | boolean | true | Close menu after selection |
223
+ | clearable | boolean | false | Show clear button |
224
+ | disabled | boolean | false | Disable the combobox |
225
+ | legacyBehavior | boolean | false | Use legacy object format |
226
+
227
+ #### `<Combobox.Trigger/>`
228
+
229
+ The button that triggers the combobox dropdown.
230
+
231
+ For advanced customization of the trigger's internal components (indicator, clear button, text display, etc.), see the [Trigger Primitives](#trigger-primitives) section below.
232
+
233
+ ##### Props
234
+
235
+ | Name | Type | Default | Description |
236
+ | ----------- | ----------------- | --------- | ---------------------- |
237
+ | size | "1" \| "2" \| "3" | "2" | Size of the trigger |
238
+ | placeholder | string | undefined | Placeholder text |
239
+ | children | ReactNode | undefined | Custom trigger content |
240
+
241
+ #### `<Combobox.Content/>`
242
+
243
+ The dropdown menu content container.
244
+
245
+ ##### Props
246
+
247
+ Accepts all props from `TelegraphMenu.Content`
248
+
249
+ #### `<Combobox.Options/>`
250
+
251
+ Container for the option items.
252
+
253
+ ##### Props
254
+
255
+ Accepts all props from `Stack` component
256
+
257
+ #### `<Combobox.Option/>`
258
+
259
+ Individual selectable option item.
260
+
261
+ ##### Props
262
+
263
+ | Name | Type | Default | Description |
264
+ | -------- | ------- | --------- | -------------------- |
265
+ | value | string | required | Option value |
266
+ | label | string | undefined | Display label |
267
+ | selected | boolean | undefined | Force selected state |
268
+
269
+ #### `<Combobox.Search/>`
270
+
271
+ Search input field for filtering options.
272
+
273
+ ##### Props
274
+
275
+ | Name | Type | Default | Description |
276
+ | ----------- | ------ | -------- | ------------------- |
277
+ | label | string | "Search" | Accessibility label |
278
+ | placeholder | string | "Search" | Input placeholder |
279
+
280
+ #### `<Combobox.Empty/>`
281
+
282
+ Empty state component shown when no options match search.
283
+
284
+ ##### Props
285
+
286
+ | Name | Type | Default | Description |
287
+ | ------- | ----------------- | ------------------ | ------------------- |
288
+ | icon | IconProps \| null | SearchIcon | Empty state icon |
289
+ | message | string \| null | "No results found" | Empty state message |
290
+
291
+ #### `<Combobox.Create/>`
292
+
293
+ Option to create new values when none match search.
294
+
295
+ ##### Props
296
+
297
+ | Name | Type | Default | Description |
298
+ | ----------- | --------------------------------- | --------- | ------------------------ |
299
+ | leadingText | string | "Create" | Text before search value |
300
+ | values | string[] \| Option[] | undefined | Existing values |
301
+ | onCreate | (value: string \| Option) => void | undefined | Creation callback |
302
+
303
+ ### Primitives
304
+
305
+ The combobox includes several primitive components for advanced customization. These primitives allow you to build custom trigger layouts and behaviors while maintaining the combobox's core functionality.
306
+
307
+ #### Trigger Primitives
308
+
309
+ ##### `<Combobox.Primitives.TriggerIndicator/>`
310
+
311
+ The dropdown chevron icon that rotates based on the combobox's open state.
312
+
313
+ ###### Props
314
+
315
+ | Name | Type | Default | Description |
316
+ | ----------- | --------- | ----------- | ----------------------------------- |
317
+ | icon | IconProps | ChevronDown | The icon to display |
318
+ | aria-hidden | boolean | true | Whether to hide from screen readers |
319
+
320
+ ```tsx
321
+ <Combobox.Primitives.TriggerIndicator icon={CustomIcon} aria-hidden={false} />
322
+ ```
323
+
324
+ ##### `<Combobox.Primitives.TriggerClear/>`
325
+
326
+ A button to clear the current selection(s). Only shown when `clearable` is true and there are selections.
327
+
328
+ ###### Props
329
+
330
+ | Name | Type | Default | Description |
331
+ | ------------ | ---------------------------------- | --------- | --------------------- |
332
+ | tooltipProps | TgphComponentProps<typeof Tooltip> | undefined | Props for the tooltip |
333
+
334
+ Accepts all props from `Button`
335
+
336
+ ```tsx
337
+ <Combobox.Primitives.TriggerClear tooltipProps={{ delay: 300 }} />
338
+ ```
339
+
340
+ ##### `<Combobox.Primitives.TriggerText/>`
341
+
342
+ Displays the selected value's text or label. Used in single-select mode.
343
+
344
+ ###### Props
345
+
346
+ Accepts all props from `Button.Text`
347
+
348
+ ```tsx
349
+ <Combobox.Primitives.TriggerText color="blue" weight="medium" />
350
+ ```
351
+
352
+ ##### `<Combobox.Primitives.TriggerPlaceholder/>`
353
+
354
+ Shows placeholder text when no value is selected.
355
+
356
+ ###### Props
357
+
358
+ Accepts all props from `Button.Text`
359
+
360
+ ```tsx
361
+ <Combobox.Primitives.TriggerPlaceholder color="gray-8" />
362
+ ```
363
+
364
+ ##### `<Combobox.Primitives.TriggerTagsContainer/>`
365
+
366
+ Container for selected value tags in multi-select mode. Handles tag layout and truncation.
367
+
368
+ ###### Props
369
+
370
+ Accepts all props from `Stack`
371
+
372
+ ```tsx
373
+ <Combobox.Primitives.TriggerTagsContainer gap="2" wrap="wrap" />
374
+ ```
375
+
376
+ ##### `<Combobox.Primitives.TriggerTag/>`
377
+
378
+ A collection of components for building custom tags in multi-select mode:
379
+
380
+ ###### `<Combobox.Primitives.TriggerTag.Root/>`
381
+
382
+ The base container for a tag.
383
+
384
+ Props:
385
+ | Name | Type | Default | Description |
386
+ | ---- | ---- | ------- | ----------- |
387
+ | value | string | required | The value this tag represents |
388
+
389
+ ###### `<Combobox.Primitives.TriggerTag.Text/>`
390
+
391
+ The text content of a tag.
392
+
393
+ Props: Accepts all props from `Text`
394
+
395
+ ###### `<Combobox.Primitives.TriggerTag.Button/>`
396
+
397
+ The remove button for a tag.
398
+
399
+ Props: Accepts all props from `Button`
400
+
401
+ ###### `<Combobox.Primitives.TriggerTag.Default/>`
402
+
403
+ A pre-composed tag with text and remove button.
404
+
405
+ Props:
406
+ | Name | Type | Default | Description |
407
+ | ---- | ---- | ------- | ----------- |
408
+ | value | string | required | The value this tag represents |
409
+
410
+ Example of a custom tag layout:
411
+
412
+ ```tsx
413
+ <Combobox.Primitives.TriggerTag.Root value="example">
414
+ <Icon icon={CustomIcon} />
415
+ <Combobox.Primitives.TriggerTag.Text>
416
+ Custom Tag
417
+ </Combobox.Primitives.TriggerTag.Text>
418
+ <Combobox.Primitives.TriggerTag.Button
419
+ icon={{ icon: XIcon, alt: "Remove" }}
420
+ />
421
+ </Combobox.Primitives.TriggerTag.Root>
422
+ ```
423
+
424
+ Example of using the default tag:
425
+
426
+ ```tsx
427
+ <Combobox.Primitives.TriggerTag.Default value="example" />
428
+ ```
429
+
430
+ Complete example using primitives for a custom trigger layout:
431
+
432
+ ```tsx
433
+ <Combobox.Root>
434
+ <Combobox.Trigger>
435
+ <Stack direction="row" justify="space-between" align="center" w="full">
436
+ {/* Left side: Text or Tags */}
437
+ <Box flex="1" overflow="hidden">
438
+ <Combobox.Primitives.TriggerTagsContainer>
439
+ <Combobox.Primitives.TriggerTag.Default value="tag1" />
440
+ <Combobox.Primitives.TriggerTag.Default value="tag2" />
441
+ </Combobox.Primitives.TriggerTagsContainer>
442
+ </Box>
443
+
444
+ {/* Right side: Clear and Indicator */}
445
+ <Stack direction="row" gap="1" align="center">
446
+ <Combobox.Primitives.TriggerClear />
447
+ <Box borderLeft="1" h="4" />
448
+ <Combobox.Primitives.TriggerIndicator />
449
+ </Stack>
450
+ </Stack>
451
+ </Combobox.Trigger>
452
+ <Combobox.Content>{/* ... */}</Combobox.Content>
453
+ </Combobox.Root>
454
+ ```
455
+
456
+ ### Legacy Behavior (⚠️ Deprecated)
457
+
458
+ > **Warning**: Legacy behavior is deprecated and will be removed in a future version. New implementations should use string values instead of objects.
459
+
460
+ The `legacyBehavior` prop changes how values are handled:
461
+
462
+ - When `false` (default, recommended): Values are simple strings
463
+ - When `true` (deprecated): Values are objects with `{ value: string; label?: string }`
464
+
465
+ #### Legacy Single Select Types
466
+
467
+ ```tsx
468
+ // ⚠️ Deprecated - Don't use in new code
469
+ const [value, setValue] = useState<{ value: string; label?: string }>()
470
+
471
+ <Combobox.Root
472
+ value={value}
473
+ onValueChange={setValue}
474
+ legacyBehavior={true}
475
+ >
476
+ ```
477
+
478
+ #### Legacy Multi Select Types
479
+
480
+ ```tsx
481
+ // ⚠️ Deprecated - Don't use in new code
482
+ const [values, setValues] = useState<Array<{ value: string; label?: string }>>([])
483
+
484
+ <Combobox.Root
485
+ value={values}
486
+ onValueChange={setValues}
487
+ legacyBehavior={true}
488
+ >
489
+ ```
490
+
491
+ This object-based value pattern is only maintained for backwards compatibility and should not be used in new code. It will be removed in a future major version.
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),G=require("@radix-ui/react-dismissable-layer"),Y=require("@radix-ui/react-portal"),U=require("@radix-ui/react-use-controllable-state"),X=require("@radix-ui/react-visually-hidden"),k=require("@telegraph/button"),q=require("@telegraph/compose-refs"),W=require("@telegraph/helpers"),C=require("@telegraph/icon"),J=require("@telegraph/input"),j=require("@telegraph/layout"),I=require("@telegraph/menu"),w=require("@telegraph/motion"),P=require("@telegraph/tag"),Z=require("@telegraph/tooltip"),Q=require("@telegraph/typography"),i=require("react");function M(t){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const e in t)if(e!=="default"){const l=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(r,e,l.get?l:{enumerable:!0,get:()=>t[e]})}}return r.default=t,Object.freeze(r)}const ee=M(Y),te=M(X),ne={0:"5",1:"6",2:"8",3:"10"},E=t=>Array.isArray(t),T=t=>typeof t=="object"&&!Array.isArray(t)||typeof t=="string"||!t,oe=t=>{const r=(a,c=[])=>(i.Children.toArray(a).forEach(o=>{i.isValidElement(o)&&(o.props.value?c.push(o):o.props.children&&r(o.props.children,c))}),c);return r(t).map(a=>{var n;const c=a;return{value:c.props.value,label:((n=c.props)==null?void 0:n.label)||c.props.children||c.props.value}})},S=(t,r)=>{if(t)return r===!0?t==null?void 0:t.value:t},D=(t,r,e)=>{if(!t||!r||r.length===0)return;const l=r.find(a=>a.value===S(t,e));if(l)return l},re=({children:t,value:r,searchQuery:e})=>{const l=F(t);return(r==null?void 0:r.toLowerCase().includes(e.toLowerCase()))||l.some(a=>a.toLowerCase().includes(e.toLowerCase()))},F=t=>{const r=i.Children.toArray(t),e=[];return r.forEach(l=>{typeof l=="string"&&e.push(l),i.isValidElement(l)&&l.props.children&&e.push(...F(l.props.children))}),e},ae=["ArrowDown","PageUp","Home"],se=["ArrowUp","PageDown","End"],H=["Enter"," "],v=i.createContext({value:void 0,onValueChange:()=>{},contentId:"",triggerId:"",open:!1,setOpen:()=>{},onOpenToggle:()=>{},clearable:!1,disabled:!1,options:[],legacyBehavior:!1}),ie=({modal:t=!0,closeOnSelect:r=!0,clearable:e=!1,disabled:l=!1,legacyBehavior:a=!1,open:c,onOpenChange:n,defaultOpen:o,value:u,onValueChange:g,errored:b,placeholder:x,layout:h,children:p,...d})=>{const y=i.useId(),m=i.useId(),f=i.useRef(null),R=i.useRef(null),A=i.useRef(null),L=i.useMemo(()=>oe(p),[p]),[N,V]=i.useState(""),[O=!1,B]=U.useControllableState({prop:c,defaultProp:o,onChange:n}),z=i.useCallback(()=>{B($=>!$)},[B]);return i.useEffect(()=>{O||V("")},[O]),s.jsx(v.Provider,{value:{contentId:y,triggerId:m,value:u,onValueChange:g,placeholder:x,open:O,setOpen:B,onOpenToggle:z,closeOnSelect:r,clearable:e,disabled:l,searchQuery:N,setSearchQuery:V,triggerRef:f,searchRef:R,contentRef:A,errored:b,layout:h,options:L,legacyBehavior:a},children:s.jsx(I.Menu.Root,{open:O,onOpenChange:B,modal:t,...d,children:p})})},ce=({value:t,...r})=>{const e=i.useContext(v),l=i.useMemo(()=>{const a=e.options.find(o=>o.value===t);if(a)return a.label||a.value;if(!e.value)return;const n=e.value.find(o=>S(o,e.legacyBehavior)===t);if(n)return n},[e.options,e.value,t,e.legacyBehavior]);return s.jsxs(P.Tag.Root,{as:w.motion.span,initializeWithAnimation:!1,initial:{opacity:0,scale:.5},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.5},transition:{duration:100,type:"spring"},"tgph-motion-key":t,size:"1",layout:"position",...r,children:[s.jsx(P.Tag.Text,{children:l}),s.jsx(P.Tag.Button,{icon:{icon:C.Lucide.X,alt:`Remove ${t}`},onClick:a=>{if(!e.onValueChange)return;const c=e.onValueChange,o=e.value.filter(u=>S(u,e.legacyBehavior)!==t);c==null||c(o),a.stopPropagation(),a.preventDefault()}})]})},le=()=>{var r;const t=i.useContext(v);if(t.value&&E(t.value)){const e=t.layout||"truncate",l=t.value.length-2,a=l.toString().split("");return t.value.length===0?s.jsx(k.Button.Text,{color:"gray",children:t.placeholder}):s.jsxs(j.Stack,{gap:"1",w:"full",wrap:e==="wrap"?"wrap":"nowrap",align:"center",style:{position:"relative",flexGrow:1},children:[s.jsx(w.AnimatePresence,{presenceMap:t.value.map(c=>({"tgph-motion-key":S(c,t.legacyBehavior)||"",value:!0})),children:t.value.map((c,n)=>{const o=S(c,t.legacyBehavior);if(o&&(e==="truncate"&&n<=1||e==="wrap"))return s.jsx(W.RefToTgphRef,{children:s.jsx(ce,{value:o})},o)})}),s.jsx(w.AnimatePresence,{presenceMap:[{"tgph-motion-key":"combobox-more",value:!0}],children:e==="truncate"&&t.value.length>2&&s.jsx(j.Stack,{as:w.motion.div,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:100,type:"spring"},h:"full",pr:"1",pl:"8",align:"center","aria-label":`${l} more selected`,position:"absolute",right:"0",style:{backgroundImage:"linear-gradient(to left, var(--tgph-surface-1) 0 60%, transparent 90% 100%)"},children:s.jsxs(Q.Text,{as:"span",size:"1",style:{whiteSpace:"nowrap"},children:["+",s.jsxs(w.AnimatePresence,{presenceMap:a.map(c=>({"tgph-motion-key":c,value:!0})),children:[a.map(c=>s.jsx(j.Box,{as:w.motion.span,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:100,type:"spring"},w:"2",display:"inline-block","tgph-motion-key":c,children:c},c))," "]}),"more"]})})})]})}if(t&&T(t.value)){const e=D(t.value,t.options,t.legacyBehavior),l=(e==null?void 0:e.label)||(e==null?void 0:e.value)||t.placeholder,a=t.legacyBehavior&&((r=t==null?void 0:t.value)==null?void 0:r.label);return s.jsx(k.Button.Text,{color:t.value?"default":"gray",textOverflow:"ellipsis",overflow:"hidden",children:a||l})}},ue=({size:t="2",...r})=>{const e=i.useContext(v),l=i.useCallback(()=>{var n;if(!e.value)return e.placeholder;if(T(e.value)){const o=D(e.value,e.options,e.legacyBehavior);return(o==null?void 0:o.label)||e.placeholder}if(E(e.value))return((n=e.value)==null?void 0:n.map(o=>{const u=D(o,e.options,e.legacyBehavior);return u==null?void 0:u.label}).join(", "))||e.placeholder},[e.value,e.placeholder,e.options,e.legacyBehavior]),a=i.useMemo(()=>{var n;if(T(e.value))return e.clearable&&e.value;if(E(e.value))return e.clearable&&((n=e.value)==null?void 0:n.length)>0},[e.clearable,e.value]),c=()=>{var n,o;if(E(e.value)){const u=e.onValueChange;u==null||u([])}if(T(e.value)){const u=e.onValueChange;u==null||u(void 0)}(o=(n=e.triggerRef)==null?void 0:n.current)==null||o.focus()};return s.jsx(I.Menu.Trigger,{...r,asChild:!0,onClick:n=>{var o,u;n.preventDefault(),e.onOpenToggle(),(u=(o=e.triggerRef)==null?void 0:o.current)==null||u.focus()},onKeyDown:n=>{if(n.key==="Tab"){n.stopPropagation();return}if(H.includes(n.key)){n.preventDefault();return}if(n.key==="ArrowDown"){n.stopPropagation(),n.preventDefault(),e.onOpenToggle();return}},tgphRef:e.triggerRef,children:s.jsxs(k.Button.Root,{id:e.triggerId,type:"button",bg:"surface-1",variant:"outline",align:"center",minH:ne[t],h:"full",w:"full",py:"1",size:t,color:e.errored?"red":"gray",justify:"space-between",role:"combobox","aria-label":l(),"aria-controls":e.contentId,"aria-expanded":e.open,"aria-haspopup":"listbox","data-tgph-combobox-trigger":!0,"data-tgph-combobox-trigger-open":e.open,disabled:e.disabled,children:[s.jsx(le,{}),s.jsxs(j.Stack,{align:"center",gap:"1",children:[a&&s.jsx(Z.Tooltip,{label:"Clear field",children:s.jsx(k.Button,{type:"button",icon:{icon:C.Lucide.X,alt:"Clear field"},size:"1",variant:"ghost",onClick:n=>{e.value&&(n.stopPropagation(),c())},onKeyDown:n=>{(n.key==="Enter"||n.key===" ")&&(n.stopPropagation(),c())},"data-tgph-combobox-clear":!0,style:{marginTop:"calc(-1 * var(--tgph-spacing-1)",marginBottom:"calc(-1 * var(--tgph-spacing-1)"}})}),s.jsx(k.Button.Icon,{as:w.motion.span,animate:{rotate:e.open?180:0},transition:{duration:150,type:"spring"},icon:C.Lucide.ChevronDown,"aria-hidden":!0})]})]})})},pe=({style:t,children:r,tgphRef:e,...l})=>{const a=i.useContext(v),c=i.useRef(!1),n=q.useComposedRefs(e,a.contentRef),o=i.useRef(null),[u,g]=i.useState(0),[b,x]=i.useState(!1),h=i.useCallback(p=>{const d=p==null?void 0:p.getBoundingClientRect();d&&g(d.height),b||x(!0)},[b]);return i.useEffect(()=>{const p=new ResizeObserver(d=>{for(const y of d){const m=y.target;h(m)}});return o.current&&b&&p.observe(o.current),()=>p.disconnect()},[b,h]),i.useEffect(()=>{b===!0&&a.open===!1&&x(!1)},[a.open,b]),i.useEffect(()=>{let p;return a.open&&(p=setTimeout(()=>{h(o.current)},10)),()=>p&&clearTimeout(p)},[a.open,h]),s.jsx(ee.Root,{asChild:!0,children:s.jsx(G.DismissableLayer,{onEscapeKeyDown:p=>{a.open&&(p.stopPropagation(),p.preventDefault(),a.setOpen(!1))},children:s.jsx(I.Menu.Content,{className:"tgph",mt:"1",onCloseAutoFocus:p=>{var d,y;c.current||(y=(d=a.triggerRef)==null?void 0:d.current)==null||y.focus(),c.current=!1,p.preventDefault()},bg:"surface-1",style:{width:"var(--tgph-combobox-trigger-width)",transition:"min-height 200ms ease-in-out",minHeight:u?`${u}px`:"0",...t,"--tgph-combobox-content-transform-origin":"var(--radix-popper-transform-origin)","--tgph-combobox-content-available-width":"var(--radix-popper-available-width)","--tgph-combobox-content-available-height":"calc(var(--radix-popper-available-height) - var(--tgph-spacing-8))","--tgph-combobox-trigger-width":"var(--radix-popper-anchor-width)","--tgph-combobox-trigger-height":"var(--radix-popper-anchor-height)"},...l,tgphRef:n,"data-tgph-combobox-content":!0,"data-tgph-combobox-content-open":a.open,role:void 0,"aria-orientation":void 0,onKeyDown:p=>{var y,m,f,R;p.stopPropagation();const d=(m=(y=a.contentRef)==null?void 0:y.current)==null?void 0:m.querySelectorAll("[data-tgph-combobox-option]");document.activeElement===(d==null?void 0:d[0])&&se.includes(p.key)&&((R=(f=a.searchRef)==null?void 0:f.current)==null||R.focus())},children:s.jsx(j.Stack,{direction:"column",gap:"1",tgphRef:o,children:r})})})})},ge=({...t})=>{const r=i.useContext(v);return s.jsx(j.Stack,{id:r.contentId,direction:"column",gap:"1",style:{overflowY:"auto","--max-height":t.maxHeight?void 0:"calc(var(--tgph-combobox-content-available-height) - var(--tgph-spacing-12))"},role:"listbox",...t})},_=({value:t,label:r,selected:e,onSelect:l,children:a,...c})=>{const n=i.useContext(v),[o,u]=i.useState(!1),g=n.value,b=!n.searchQuery||re({children:r||a,value:t,searchQuery:n.searchQuery}),x=E(g)?g.some(p=>S(p,n.legacyBehavior)===t):S(g,n.legacyBehavior)===t,h=p=>{var y,m;p.stopPropagation();const d=p;if(!(d.key&&!H.includes(d.key))){if(p.preventDefault(),n.closeOnSelect===!0&&n.setOpen(!1),l)return l(p);if(T(g)){const f=n.onValueChange;n.legacyBehavior===!0?f==null||f({value:t,label:r}):f==null||f(t)}else if(E(g)){const f=n.onValueChange,R=n.value,A=x?R.filter(L=>S(L,n.legacyBehavior)!==t):[...R,n.legacyBehavior===!0?{value:t,label:r}:t];f==null||f(A)}(m=(y=n.triggerRef)==null?void 0:y.current)==null||m.focus()}};if(b)return s.jsx(I.Menu.Button,{type:"button",onSelect:h,onKeyDown:h,selected:e===null?null:e??x,onFocus:()=>u(!0),onBlur:()=>u(!1),role:"option","aria-selected":x?"true":"false","data-tgph-combobox-option":!0,"data-tgph-combobox-option-focused":o,"data-tgph-combobox-option-value":t,"data-tgph-combobox-option-label":r,...c,children:r||a||t})},de=({label:t="Search",placeholder:r="Search",tgphRef:e,value:l,onValueChange:a,...c})=>{var x;const n=i.useId(),o=i.useContext(v),u=q.useComposedRefs(e,o.searchRef),g=l??o.searchQuery,b=a??o.setSearchQuery;return i.useEffect(()=>{var d;const h=y=>{var m,f;ae.includes(y.key)&&((f=(m=o.contentRef)==null?void 0:m.current)==null||f.focus({preventScroll:!0})),y.key==="Escape"&&o.setOpen(!1),y.stopPropagation()},p=(d=o.searchRef)==null?void 0:d.current;if(p)return p.addEventListener("keydown",h),()=>{p.removeEventListener("keydown",h)}},[o]),s.jsxs(j.Box,{borderBottom:"px",px:"1",pb:"1",children:[s.jsx(te.Root,{children:s.jsx(Q.Text,{as:"label",htmlFor:n,children:t})}),s.jsx(J.Input,{id:n,variant:"ghost",placeholder:r,value:g,onChange:h=>{b(h.target.value)},LeadingComponent:s.jsx(C.Icon,{icon:C.Lucide.Search,alt:"Search Icon"}),TrailingComponent:o!=null&&o.searchQuery&&((x=o==null?void 0:o.searchQuery)==null?void 0:x.length)>0?s.jsx(k.Button,{variant:"ghost",color:"gray",icon:{icon:C.Lucide.X,alt:"Clear Search Query"},onClick:()=>{var h;return(h=o.setSearchQuery)==null?void 0:h.call(o,"")}}):null,autoFocus:!0,"data-tgph-combobox-search":!0,"aria-controls":o.contentId,...c,tgphRef:u})]})},fe=({icon:t={icon:C.Lucide.Search,alt:"Search Icon"},message:r="No results found",children:e,...l})=>{const a=i.useContext(v),[c,n]=i.useState(!1);if(i.useEffect(()=>{var u,g;const o=(g=(u=a.contentRef)==null?void 0:u.current)==null?void 0:g.querySelectorAll("[data-tgph-combobox-option]");(o==null?void 0:o.length)===0?n(!0):n(!1)},[a.searchQuery,a.contentRef,e]),c)return s.jsxs(j.Stack,{gap:"1",align:"center",justify:"center",w:"full",my:"8","data-tgph-combobox-empty":!0,...l,children:[t===null?s.jsx(s.Fragment,{}):s.jsx(C.Icon,{...t}),r===null?s.jsx(s.Fragment,{}):s.jsx(Q.Text,{as:"span",children:r})]})},he=({leadingText:t="Create",values:r,onCreate:e,selected:l=null,legacyBehavior:a=!1,...c})=>{const n=i.useContext(v),o=i.useCallback(u=>!r||(r==null?void 0:r.length)===0?!1:r.some(g=>S(g,a)===u),[r,a]);if(n.searchQuery&&!o(n.searchQuery))return s.jsx(_,{leadingIcon:{icon:C.Lucide.Plus,"aria-hidden":!0},mx:"1",value:n.searchQuery,label:`${t} "${n.searchQuery}"`,selected:l,onSelect:()=>{var u;if(e&&n.value&&n.searchQuery){const g=a===!0?{value:n.searchQuery}:n.searchQuery;e(g),(u=n.setSearchQuery)==null||u.call(n,"")}},...c})},K={};Object.assign(K,{Root:ie,Trigger:ue,Content:pe,Options:ge,Option:_,Search:de,Empty:fe,Create:he});exports.Combobox=K;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),X=require("@radix-ui/react-dismissable-layer"),W=require("@radix-ui/react-portal"),J=require("@radix-ui/react-use-controllable-state"),Z=require("@radix-ui/react-visually-hidden"),B=require("@telegraph/button"),H=require("@telegraph/compose-refs"),ee=require("@telegraph/helpers"),C=require("@telegraph/icon"),te=require("@telegraph/input"),S=require("@telegraph/layout"),A=require("@telegraph/menu"),q=require("@telegraph/typography"),l=require("react"),k=require("@telegraph/motion"),M=require("@telegraph/tag"),ne=require("@telegraph/tooltip");function _(t){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const e in t)if(e!=="default"){const o=Object.getOwnPropertyDescriptor(t,e);Object.defineProperty(n,e,o.get?o:{enumerable:!0,get:()=>t[e]})}}return n.default=t,Object.freeze(n)}const oe=_(W),re=_(Z),ae={0:"5",1:"6",2:"8",3:"10"},R=t=>Array.isArray(t),E=t=>typeof t=="object"&&!Array.isArray(t)||typeof t=="string"||!t,se=t=>{const n=(a,i=[])=>(l.Children.toArray(a).forEach(s=>{l.isValidElement(s)&&(s.props.value?i.push(s):s.props.children&&n(s.props.children,i))}),i);return n(t).map(a=>{var r;const i=a;return{value:i.props.value,label:((r=i.props)==null?void 0:r.label)||i.props.children||i.props.value}})},T=(t,n)=>{if(t)return n===!0?t==null?void 0:t.value:t},Q=(t,n,e)=>{if(!t||!n||n.length===0)return;const o=n.find(a=>a.value===T(t,e));if(o)return o},ie=({children:t,value:n,searchQuery:e})=>{const o=K(t);return(n==null?void 0:n.toLowerCase().includes(e.toLowerCase()))||o.some(a=>a.toLowerCase().includes(e.toLowerCase()))},K=t=>{const n=l.Children.toArray(t),e=[];return n.forEach(o=>{typeof o=="string"&&e.push(o),l.isValidElement(o)&&o.props.children&&e.push(...K(o.props.children))}),e},ce=({icon:t=C.Lucide.ChevronDown,"aria-hidden":n=!0,...e})=>{const o=l.useContext(y);return c.jsx(B.Button.Icon,{as:k.motion.span,animate:{rotate:o.open?180:0},transition:{duration:150,type:"spring"},icon:t,"aria-hidden":n,...e})},le=({tooltipProps:t,...n})=>{const e=l.useContext(y),o=()=>{var i,r;if(R(e.value)){const s=e.onValueChange;s==null||s([])}if(E(e.value)){const s=e.onValueChange;s==null||s(void 0)}(r=(i=e.triggerRef)==null?void 0:i.current)==null||r.focus()};return l.useMemo(()=>{var i;if(E(e.value))return e.clearable&&e.value;if(R(e.value))return e.clearable&&((i=e.value)==null?void 0:i.length)>0},[e.clearable,e.value])?c.jsx(ne.Tooltip,{label:"Clear field",...t,children:c.jsx(B.Button,{type:"button",icon:{icon:C.Lucide.X,alt:"Clear field"},size:"1",variant:"ghost",onClick:i=>{e.value&&(i.stopPropagation(),o())},onKeyDown:i=>{(i.key==="Enter"||i.key===" ")&&(i.stopPropagation(),o())},"data-tgph-combobox-clear":!0,style:{marginTop:"calc(-1 * var(--tgph-spacing-1)",marginBottom:"calc(-1 * var(--tgph-spacing-1)"},...n})}):null},ue=({children:t,...n})=>{const e=l.useContext(y),o=l.useMemo(()=>{var s;if(!E(e.value))return;const a=Q(e.value,e.options,e.legacyBehavior),i=(a==null?void 0:a.label)||(a==null?void 0:a.value)||e.placeholder,r=e.legacyBehavior&&((s=e==null?void 0:e.value)==null?void 0:s.label);return r||i},[e.value,e.options,e.legacyBehavior,e.placeholder]);return c.jsx(B.Button.Text,{color:e.value?"default":"gray",textOverflow:"ellipsis",overflow:"hidden",...n,children:t||o})},pe=({children:t,...n})=>{const e=l.useContext(y);return c.jsx(B.Button.Text,{color:"gray",...n,children:t||e.placeholder})},ge=({children:t})=>{const n=l.useContext(y);if(!R(n.value))return null;const e=n.layout||"truncate",a=(n.value.length-2).toString().split("");return c.jsxs(S.Stack,{gap:"1",w:"full",wrap:e==="wrap"?"wrap":"nowrap",align:"center",style:{position:"relative",flexGrow:1},children:[c.jsx(k.AnimatePresence,{presenceMap:n.value.map(i=>({"tgph-motion-key":T(i,n.legacyBehavior)||"",value:!0})),children:t}),c.jsx(k.AnimatePresence,{presenceMap:[{"tgph-motion-key":"combobox-more",value:!0}],children:e==="truncate"&&n.value.length>2&&c.jsx(S.Stack,{as:k.motion.div,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:100,type:"spring"},h:"full",pr:"1",pl:"8",align:"center","aria-label":`${n.value.length-2} more selected`,position:"absolute",right:"0",style:{backgroundImage:"linear-gradient(to left, var(--tgph-surface-1) 0 60%, transparent 90% 100%)"},children:c.jsxs(q.Text,{as:"span",size:"1",style:{whiteSpace:"nowrap"},children:["+",c.jsxs(k.AnimatePresence,{presenceMap:a.map(i=>({"tgph-motion-key":i,value:!0})),children:[a.map(i=>c.jsx(S.Box,{as:k.motion.span,initial:{opacity:0},animate:{opacity:1},exit:{opacity:0},transition:{duration:100,type:"spring"},w:"2",display:"inline-block","tgph-motion-key":i,children:i},i))," "]}),"more"]})})})]})},V=l.createContext({value:""}),de=({value:t,children:n,...e})=>c.jsx(V.Provider,{value:{value:t},children:c.jsx(M.Tag.Root,{as:k.motion.span,initializeWithAnimation:!1,initial:{opacity:0,scale:.5},animate:{opacity:1,scale:1},exit:{opacity:0,scale:.5},transition:{duration:100,type:"spring"},"tgph-motion-key":t,size:"1",layout:"position",...e,children:n})}),fe=({children:t,...n})=>{const e=l.useContext(y),o=l.useContext(V),a=l.useMemo(()=>{const i=e.options.find(p=>p.value===o.value);if(i)return i.label||i.value;if(!e.value)return;const s=e.value.find(p=>T(p,e.legacyBehavior)===o.value);if(s)return s},[e.options,e.value,o.value,e.legacyBehavior]);return c.jsx(M.Tag.Text,{...n,children:t||a})},he=({children:t,...n})=>{const e=l.useContext(y),o=l.useContext(V);return c.jsx(M.Tag.Button,{icon:{icon:C.Lucide.X,alt:`Remove ${o.value}`},onClick:a=>{if(!e.onValueChange)return;const i=e.onValueChange,s=e.value.filter(p=>T(p,e.legacyBehavior)!==o.value);i==null||i(s),a.stopPropagation(),a.preventDefault()},...n,children:t})},xe=({value:t,children:n,...e})=>c.jsxs(P.Root,{value:t,...e,children:[c.jsx(P.Text,{children:n}),c.jsx(P.Button,{})]}),P={Root:de,Text:fe,Button:he,Default:xe},j={TriggerIndicator:ce,TriggerClear:le,TriggerText:ue,TriggerPlaceholder:pe,TriggerTagsContainer:ge,TriggerTag:P},ye=["ArrowDown","PageUp","Home"],me=["ArrowUp","PageDown","End"],N=["Enter"," "],y=l.createContext({value:void 0,onValueChange:()=>{},contentId:"",triggerId:"",open:!1,setOpen:()=>{},onOpenToggle:()=>{},clearable:!1,disabled:!1,options:[],legacyBehavior:!1}),be=({modal:t=!0,closeOnSelect:n=!0,clearable:e=!1,disabled:o=!1,legacyBehavior:a=!1,open:i,onOpenChange:r,defaultOpen:s,value:p,onValueChange:g,errored:m,placeholder:v,layout:h,children:u,...d})=>{const x=l.useId(),b=l.useId(),f=l.useRef(null),w=l.useRef(null),D=l.useRef(null),L=l.useMemo(()=>se(u),[u]),[G,F]=l.useState(""),[O=!1,I]=J.useControllableState({prop:i,defaultProp:s,onChange:r}),Y=l.useCallback(()=>{I(U=>!U)},[I]);return l.useEffect(()=>{O||F("")},[O]),c.jsx(y.Provider,{value:{contentId:x,triggerId:b,value:p,onValueChange:g,placeholder:v,open:O,setOpen:I,onOpenToggle:Y,closeOnSelect:n,clearable:e,disabled:o,searchQuery:G,setSearchQuery:F,triggerRef:f,searchRef:w,contentRef:D,errored:m,layout:h,options:L,legacyBehavior:a},children:c.jsx(A.Menu.Root,{open:O,onOpenChange:I,modal:t,...d,children:u})})},ve=()=>{const t=l.useContext(y);if(t.value&&R(t.value)){const n=t.layout||"truncate";return t.value.length===0?c.jsx(j.TriggerPlaceholder,{}):c.jsx(j.TriggerTagsContainer,{children:t.value.map((e,o)=>{const a=T(e,t.legacyBehavior);if(a&&(n==="truncate"&&o<=1||n==="wrap"))return c.jsx(ee.RefToTgphRef,{children:c.jsx(j.TriggerTag.Default,{value:a})},a)})})}if(t&&E(t.value))return t.value?c.jsx(j.TriggerText,{}):c.jsx(j.TriggerPlaceholder,{})},Ce=({size:t="2",children:n,...e})=>{const o=l.useContext(y),a=l.useMemo(()=>{if(o.value){if(E(o.value))return Q(o.value,o.options,o.legacyBehavior);if(R(o.value))return o.value.map(r=>Q(r,o.options,o.legacyBehavior))}},[o.value,o.options,o.legacyBehavior]),i=l.useCallback(()=>a?E(a)?(a==null?void 0:a.label)||(a==null?void 0:a.value)||o.placeholder:R(a)&&a.map(r=>(r==null?void 0:r.label)||(r==null?void 0:r.value)).join(", ")||o.placeholder:o.placeholder,[a,o.placeholder]);return c.jsx(A.Menu.Trigger,{...e,asChild:!0,onClick:r=>{var s,p;r.preventDefault(),o.onOpenToggle(),(p=(s=o.triggerRef)==null?void 0:s.current)==null||p.focus()},onKeyDown:r=>{if(r.key==="Tab"){r.stopPropagation();return}if(N.includes(r.key)){r.preventDefault();return}if(r.key==="ArrowDown"){r.stopPropagation(),r.preventDefault(),o.onOpenToggle();return}},tgphRef:o.triggerRef,children:c.jsxs(B.Button.Root,{id:o.triggerId,type:"button",bg:"surface-1",variant:"outline",align:"center",minH:ae[t],h:"full",w:"full",py:"1",size:t,color:o.errored?"red":"gray",justify:"space-between",role:"combobox","aria-label":i(),"aria-controls":o.contentId,"aria-expanded":o.open,"aria-haspopup":"listbox","data-tgph-combobox-trigger":!0,"data-tgph-combobox-trigger-open":o.open,disabled:o.disabled,...e,children:[n?typeof n=="function"?n({value:a}):n:c.jsx(ve,{}),c.jsxs(S.Stack,{align:"center",gap:"1",children:[c.jsx(j.TriggerClear,{}),c.jsx(j.TriggerIndicator,{})]})]})})},Te=({style:t,children:n,tgphRef:e,...o})=>{const a=l.useContext(y),i=l.useRef(!1),r=H.useComposedRefs(e,a.contentRef),s=l.useRef(null),[p,g]=l.useState(0),[m,v]=l.useState(!1),h=l.useCallback(u=>{const d=u==null?void 0:u.getBoundingClientRect();d&&g(d.height),m||v(!0)},[m]);return l.useEffect(()=>{const u=new ResizeObserver(d=>{for(const x of d){const b=x.target;h(b)}});return s.current&&m&&u.observe(s.current),()=>u.disconnect()},[m,h]),l.useEffect(()=>{m===!0&&a.open===!1&&v(!1)},[a.open,m]),l.useEffect(()=>{let u;return a.open&&(u=setTimeout(()=>{h(s.current)},10)),()=>u&&clearTimeout(u)},[a.open,h]),c.jsx(oe.Root,{asChild:!0,children:c.jsx(X.DismissableLayer,{onEscapeKeyDown:u=>{a.open&&(u.stopPropagation(),u.preventDefault(),a.setOpen(!1))},children:c.jsx(A.Menu.Content,{className:"tgph",mt:"1",onCloseAutoFocus:u=>{var d,x;i.current||(x=(d=a.triggerRef)==null?void 0:d.current)==null||x.focus(),i.current=!1,u.preventDefault()},bg:"surface-1",style:{width:"var(--tgph-combobox-trigger-width)",transition:"min-height 200ms ease-in-out",minHeight:p?`${p}px`:"0",...t,"--tgph-combobox-content-transform-origin":"var(--radix-popper-transform-origin)","--tgph-combobox-content-available-width":"var(--radix-popper-available-width)","--tgph-combobox-content-available-height":"calc(var(--radix-popper-available-height) - var(--tgph-spacing-8))","--tgph-combobox-trigger-width":"var(--radix-popper-anchor-width)","--tgph-combobox-trigger-height":"var(--radix-popper-anchor-height)"},...o,tgphRef:r,"data-tgph-combobox-content":!0,"data-tgph-combobox-content-open":a.open,role:void 0,"aria-orientation":void 0,onKeyDown:u=>{var x,b,f,w;u.stopPropagation();const d=(b=(x=a.contentRef)==null?void 0:x.current)==null?void 0:b.querySelectorAll("[data-tgph-combobox-option]");document.activeElement===(d==null?void 0:d[0])&&me.includes(u.key)&&((w=(f=a.searchRef)==null?void 0:f.current)==null||w.focus())},children:c.jsx(S.Stack,{direction:"column",gap:"1",tgphRef:s,children:n})})})})},je=({...t})=>{const n=l.useContext(y);return c.jsx(S.Stack,{id:n.contentId,direction:"column",gap:"1",style:{overflowY:"auto","--max-height":t.maxHeight?void 0:"calc(var(--tgph-combobox-content-available-height) - var(--tgph-spacing-12))"},role:"listbox",...t})},z=({value:t,label:n,selected:e,onSelect:o,children:a,...i})=>{const r=l.useContext(y),[s,p]=l.useState(!1),g=r.value,m=!r.searchQuery||ie({children:n||a,value:t,searchQuery:r.searchQuery}),v=R(g)?g.some(u=>T(u,r.legacyBehavior)===t):T(g,r.legacyBehavior)===t,h=u=>{var x,b;u.stopPropagation();const d=u;if(!(d.key&&!N.includes(d.key))){if(u.preventDefault(),r.closeOnSelect===!0&&r.setOpen(!1),o)return o(u);if(E(g)){const f=r.onValueChange;r.legacyBehavior===!0?f==null||f({value:t,label:n}):f==null||f(t)}else if(R(g)){const f=r.onValueChange,w=r.value,D=v?w.filter(L=>T(L,r.legacyBehavior)!==t):[...w,r.legacyBehavior===!0?{value:t,label:n}:t];f==null||f(D)}(b=(x=r.triggerRef)==null?void 0:x.current)==null||b.focus()}};if(m)return c.jsx(A.Menu.Button,{type:"button",onSelect:h,onKeyDown:h,selected:e===null?null:e??v,onFocus:()=>p(!0),onBlur:()=>p(!1),role:"option","aria-selected":v?"true":"false","data-tgph-combobox-option":!0,"data-tgph-combobox-option-focused":s,"data-tgph-combobox-option-value":t,"data-tgph-combobox-option-label":n,...i,children:n||a||t})},Se=({label:t="Search",placeholder:n="Search",tgphRef:e,value:o,onValueChange:a,...i})=>{var v;const r=l.useId(),s=l.useContext(y),p=H.useComposedRefs(e,s.searchRef),g=o??s.searchQuery,m=a??s.setSearchQuery;return l.useEffect(()=>{var d;const h=x=>{var b,f;ye.includes(x.key)&&((f=(b=s.contentRef)==null?void 0:b.current)==null||f.focus({preventScroll:!0})),x.key==="Escape"&&s.setOpen(!1),x.stopPropagation()},u=(d=s.searchRef)==null?void 0:d.current;if(u)return u.addEventListener("keydown",h),()=>{u.removeEventListener("keydown",h)}},[s]),c.jsxs(S.Box,{borderBottom:"px",px:"1",pb:"1",children:[c.jsx(re.Root,{children:c.jsx(q.Text,{as:"label",htmlFor:r,children:t})}),c.jsx(te.Input,{id:r,variant:"ghost",placeholder:n,value:g,onChange:h=>{m(h.target.value)},LeadingComponent:c.jsx(C.Icon,{icon:C.Lucide.Search,alt:"Search Icon"}),TrailingComponent:s!=null&&s.searchQuery&&((v=s==null?void 0:s.searchQuery)==null?void 0:v.length)>0?c.jsx(B.Button,{variant:"ghost",color:"gray",icon:{icon:C.Lucide.X,alt:"Clear Search Query"},onClick:()=>{var h;return(h=s.setSearchQuery)==null?void 0:h.call(s,"")}}):null,autoFocus:!0,"data-tgph-combobox-search":!0,"aria-controls":s.contentId,...i,tgphRef:p})]})},Re=({icon:t={icon:C.Lucide.Search,alt:"Search Icon"},message:n="No results found",children:e,...o})=>{const a=l.useContext(y),[i,r]=l.useState(!1);if(l.useEffect(()=>{var p,g;const s=(g=(p=a.contentRef)==null?void 0:p.current)==null?void 0:g.querySelectorAll("[data-tgph-combobox-option]");(s==null?void 0:s.length)===0?r(!0):r(!1)},[a.searchQuery,a.contentRef,e]),i)return c.jsxs(S.Stack,{gap:"1",align:"center",justify:"center",w:"full",my:"8","data-tgph-combobox-empty":!0,...o,children:[t===null?c.jsx(c.Fragment,{}):c.jsx(C.Icon,{...t}),n===null?c.jsx(c.Fragment,{}):c.jsx(q.Text,{as:"span",children:n})]})},we=({leadingText:t="Create",values:n,onCreate:e,selected:o=null,legacyBehavior:a=!1,...i})=>{const r=l.useContext(y),s=l.useCallback(p=>!n||(n==null?void 0:n.length)===0?!1:n.some(g=>T(g,a)===p),[n,a]);if(r.searchQuery&&!s(r.searchQuery))return c.jsx(z,{leadingIcon:{icon:C.Lucide.Plus,"aria-hidden":!0},mx:"1",value:r.searchQuery,label:`${t} "${r.searchQuery}"`,selected:o,onSelect:()=>{var p;if(e&&r.value&&r.searchQuery){const g=a===!0?{value:r.searchQuery}:r.searchQuery;e(g),(p=r.setSearchQuery)==null||p.call(r,"")}},...i})},$={};Object.assign($,{Root:be,Trigger:Ce,Content:Te,Options:je,Option:z,Search:Se,Empty:Re,Create:we,Primitives:j});exports.Combobox=$;
2
2
  //# sourceMappingURL=index.js.map