@yamada-ui/autocomplete 1.5.1 → 1.5.2-dev-20240917033401

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 (105) hide show
  1. package/dist/autocomplete-context.d.mts +210 -0
  2. package/dist/autocomplete-context.d.ts +210 -0
  3. package/dist/autocomplete-context.js +53 -0
  4. package/dist/autocomplete-context.js.map +1 -0
  5. package/dist/autocomplete-context.mjs +18 -0
  6. package/dist/autocomplete-context.mjs.map +1 -0
  7. package/dist/autocomplete-create.d.mts +4 -3
  8. package/dist/autocomplete-create.d.ts +4 -3
  9. package/dist/autocomplete-create.js +56 -61
  10. package/dist/autocomplete-create.js.map +1 -1
  11. package/dist/autocomplete-create.mjs +4 -1
  12. package/dist/autocomplete-empty.d.mts +4 -3
  13. package/dist/autocomplete-empty.d.ts +4 -3
  14. package/dist/autocomplete-empty.js +54 -59
  15. package/dist/autocomplete-empty.js.map +1 -1
  16. package/dist/autocomplete-empty.mjs +4 -1
  17. package/dist/autocomplete-icon.d.mts +6 -4
  18. package/dist/autocomplete-icon.d.ts +6 -4
  19. package/dist/autocomplete-icon.js +15 -22
  20. package/dist/autocomplete-icon.js.map +1 -1
  21. package/dist/autocomplete-icon.mjs +2 -1
  22. package/dist/autocomplete-list.d.mts +2 -2
  23. package/dist/autocomplete-list.d.ts +2 -2
  24. package/dist/autocomplete-list.js +20 -23
  25. package/dist/autocomplete-list.js.map +1 -1
  26. package/dist/autocomplete-list.mjs +3 -1
  27. package/dist/autocomplete-option-group.d.mts +5 -9
  28. package/dist/autocomplete-option-group.d.ts +5 -9
  29. package/dist/autocomplete-option-group.js +14 -16
  30. package/dist/autocomplete-option-group.js.map +1 -1
  31. package/dist/autocomplete-option-group.mjs +3 -1
  32. package/dist/autocomplete-option.d.mts +15 -8
  33. package/dist/autocomplete-option.d.ts +15 -8
  34. package/dist/autocomplete-option.js +97 -102
  35. package/dist/autocomplete-option.js.map +1 -1
  36. package/dist/autocomplete-option.mjs +4 -1
  37. package/dist/autocomplete.d.mts +13 -7
  38. package/dist/autocomplete.d.ts +13 -7
  39. package/dist/autocomplete.js +673 -661
  40. package/dist/autocomplete.js.map +1 -1
  41. package/dist/autocomplete.mjs +12 -1
  42. package/dist/chunk-7GCVSXCV.mjs +190 -0
  43. package/dist/chunk-7GCVSXCV.mjs.map +1 -0
  44. package/dist/chunk-BD7VZQOL.mjs +267 -0
  45. package/dist/chunk-BD7VZQOL.mjs.map +1 -0
  46. package/dist/chunk-FZM3BH3D.mjs +57 -0
  47. package/dist/chunk-FZM3BH3D.mjs.map +1 -0
  48. package/dist/chunk-GM7RV2YY.mjs +959 -0
  49. package/dist/chunk-GM7RV2YY.mjs.map +1 -0
  50. package/dist/chunk-GOMUH7TZ.mjs +60 -0
  51. package/dist/chunk-GOMUH7TZ.mjs.map +1 -0
  52. package/dist/chunk-HL2KEBRX.mjs +87 -0
  53. package/dist/chunk-HL2KEBRX.mjs.map +1 -0
  54. package/dist/chunk-JMX72TSD.mjs +78 -0
  55. package/dist/chunk-JMX72TSD.mjs.map +1 -0
  56. package/dist/chunk-JPUKYLBW.mjs +25 -0
  57. package/dist/chunk-JPUKYLBW.mjs.map +1 -0
  58. package/dist/chunk-JXFXCGZK.mjs +102 -0
  59. package/dist/chunk-JXFXCGZK.mjs.map +1 -0
  60. package/dist/chunk-KCALQJLK.mjs +59 -0
  61. package/dist/chunk-KCALQJLK.mjs.map +1 -0
  62. package/dist/chunk-PRDD3JJO.mjs +202 -0
  63. package/dist/chunk-PRDD3JJO.mjs.map +1 -0
  64. package/dist/chunk-QGOCVO2C.mjs +68 -0
  65. package/dist/chunk-QGOCVO2C.mjs.map +1 -0
  66. package/dist/chunk-QQFSHTTC.mjs +59 -0
  67. package/dist/chunk-QQFSHTTC.mjs.map +1 -0
  68. package/dist/index.d.mts +4 -1
  69. package/dist/index.d.ts +4 -1
  70. package/dist/index.js +1550 -1536
  71. package/dist/index.js.map +1 -1
  72. package/dist/index.mjs +23 -6
  73. package/dist/multi-autocomplete.d.mts +13 -7
  74. package/dist/multi-autocomplete.d.ts +13 -7
  75. package/dist/multi-autocomplete.js +1516 -1504
  76. package/dist/multi-autocomplete.js.map +1 -1
  77. package/dist/multi-autocomplete.mjs +12 -1
  78. package/dist/use-autocomplete-list.d.mts +8 -0
  79. package/dist/use-autocomplete-list.d.ts +8 -0
  80. package/dist/use-autocomplete-list.js +103 -0
  81. package/dist/use-autocomplete-list.js.map +1 -0
  82. package/dist/use-autocomplete-list.mjs +9 -0
  83. package/dist/use-autocomplete-list.mjs.map +1 -0
  84. package/dist/use-autocomplete-option-group.d.mts +16 -0
  85. package/dist/use-autocomplete-option-group.d.ts +16 -0
  86. package/dist/use-autocomplete-option-group.js +113 -0
  87. package/dist/use-autocomplete-option-group.js.map +1 -0
  88. package/dist/use-autocomplete-option-group.mjs +9 -0
  89. package/dist/use-autocomplete-option-group.mjs.map +1 -0
  90. package/dist/use-autocomplete-option.d.mts +49 -0
  91. package/dist/use-autocomplete-option.d.ts +49 -0
  92. package/dist/use-autocomplete-option.js +231 -0
  93. package/dist/use-autocomplete-option.js.map +1 -0
  94. package/dist/use-autocomplete-option.mjs +13 -0
  95. package/dist/use-autocomplete-option.mjs.map +1 -0
  96. package/dist/use-autocomplete.d.mts +188 -8
  97. package/dist/use-autocomplete.d.ts +188 -8
  98. package/dist/use-autocomplete.js +359 -481
  99. package/dist/use-autocomplete.js.map +1 -1
  100. package/dist/use-autocomplete.mjs +9 -25
  101. package/package.json +13 -13
  102. package/dist/chunk-ZD25NCFE.mjs +0 -2038
  103. package/dist/chunk-ZD25NCFE.mjs.map +0 -1
  104. package/dist/use-autocomplete-BJNWa6hL.d.mts +0 -389
  105. package/dist/use-autocomplete-BJNWa6hL.d.ts +0 -389
@@ -0,0 +1,959 @@
1
+ "use client"
2
+ import {
3
+ AutocompleteOptionGroup
4
+ } from "./chunk-FZM3BH3D.mjs";
5
+ import {
6
+ AutocompleteOption
7
+ } from "./chunk-QQFSHTTC.mjs";
8
+ import {
9
+ useAutocompleteContext,
10
+ useAutocompleteDescendants,
11
+ useAutocompleteDescendantsContext
12
+ } from "./chunk-JPUKYLBW.mjs";
13
+
14
+ // src/use-autocomplete.tsx
15
+ import { layoutStyleProperties } from "@yamada-ui/core";
16
+ import {
17
+ formControlProperties,
18
+ useFormControlProps
19
+ } from "@yamada-ui/form-control";
20
+ import { useControllableState } from "@yamada-ui/use-controllable-state";
21
+ import { useDisclosure } from "@yamada-ui/use-disclosure";
22
+ import { useOutsideClick } from "@yamada-ui/use-outside-click";
23
+ import {
24
+ dataAttr,
25
+ funcAll,
26
+ getEventRelatedTarget,
27
+ handlerAll,
28
+ isArray,
29
+ isContains,
30
+ mergeRefs,
31
+ pickObject,
32
+ splitObject,
33
+ useUnmountEffect,
34
+ useUpdateEffect,
35
+ getValidChildren,
36
+ isUndefined
37
+ } from "@yamada-ui/utils";
38
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
39
+ import { jsx } from "react/jsx-runtime";
40
+ var kanaMap = {
41
+ \uFF76\uFF9E: "\u30AC",
42
+ \uFF77\uFF9E: "\u30AE",
43
+ \uFF78\uFF9E: "\u30B0",
44
+ \uFF79\uFF9E: "\u30B2",
45
+ \uFF7A\uFF9E: "\u30B4",
46
+ \uFF7B\uFF9E: "\u30B6",
47
+ \uFF7C\uFF9E: "\u30B8",
48
+ \uFF7D\uFF9E: "\u30BA",
49
+ \uFF7E\uFF9E: "\u30BC",
50
+ \uFF7F\uFF9E: "\u30BE",
51
+ \uFF80\uFF9E: "\u30C0",
52
+ \uFF81\uFF9E: "\u30C2",
53
+ \uFF82\uFF9E: "\u30C5",
54
+ \uFF83\uFF9E: "\u30C7",
55
+ \uFF84\uFF9E: "\u30C9",
56
+ \uFF8A\uFF9E: "\u30D0",
57
+ \uFF8B\uFF9E: "\u30D3",
58
+ \uFF8C\uFF9E: "\u30D6",
59
+ \uFF8D\uFF9E: "\u30D9",
60
+ \uFF8E\uFF9E: "\u30DC",
61
+ \uFF8A\uFF9F: "\u30D1",
62
+ \uFF8B\uFF9F: "\u30D4",
63
+ \uFF8C\uFF9F: "\u30D7",
64
+ \uFF8D\uFF9F: "\u30DA",
65
+ \uFF8E\uFF9F: "\u30DD",
66
+ \uFF73\uFF9E: "\u30F4",
67
+ \uFF9C\uFF9E: "\u30F7",
68
+ \uFF66\uFF9E: "\u30FA",
69
+ \uFF71: "\u30A2",
70
+ \uFF72: "\u30A4",
71
+ \uFF73: "\u30A6",
72
+ \uFF74: "\u30A8",
73
+ \uFF75: "\u30AA",
74
+ \uFF76: "\u30AB",
75
+ \uFF77: "\u30AD",
76
+ \uFF78: "\u30AF",
77
+ \uFF79: "\u30B1",
78
+ \uFF7A: "\u30B3",
79
+ \uFF7B: "\u30B5",
80
+ \uFF7C: "\u30B7",
81
+ \uFF7D: "\u30B9",
82
+ \uFF7E: "\u30BB",
83
+ \uFF7F: "\u30BD",
84
+ \uFF80: "\u30BF",
85
+ \uFF81: "\u30C1",
86
+ \uFF82: "\u30C4",
87
+ \uFF83: "\u30C6",
88
+ \uFF84: "\u30C8",
89
+ \uFF85: "\u30CA",
90
+ \uFF86: "\u30CB",
91
+ \uFF87: "\u30CC",
92
+ \uFF88: "\u30CD",
93
+ \uFF89: "\u30CE",
94
+ \uFF8A: "\u30CF",
95
+ \uFF8B: "\u30D2",
96
+ \uFF8C: "\u30D5",
97
+ \uFF8D: "\u30D8",
98
+ \uFF8E: "\u30DB",
99
+ \uFF8F: "\u30DE",
100
+ \uFF90: "\u30DF",
101
+ \uFF91: "\u30E0",
102
+ \uFF92: "\u30E1",
103
+ \uFF93: "\u30E2",
104
+ \uFF94: "\u30E4",
105
+ \uFF95: "\u30E6",
106
+ \uFF96: "\u30E8",
107
+ \uFF97: "\u30E9",
108
+ \uFF98: "\u30EA",
109
+ \uFF99: "\u30EB",
110
+ \uFF9A: "\u30EC",
111
+ \uFF9B: "\u30ED",
112
+ \uFF9C: "\u30EF",
113
+ \uFF66: "\u30F2",
114
+ \uFF9D: "\u30F3",
115
+ \uFF67: "\u30A1",
116
+ \uFF68: "\u30A3",
117
+ \uFF69: "\u30A5",
118
+ \uFF6A: "\u30A7",
119
+ \uFF6B: "\u30A9",
120
+ \uFF6F: "\u30C3",
121
+ \uFF6C: "\u30E3",
122
+ \uFF6D: "\u30E5",
123
+ \uFF6E: "\u30E7",
124
+ "\uFF61": "\u3002",
125
+ "\uFF64": "\u3001",
126
+ \uFF70: "\u30FC",
127
+ "\uFF62": "\u300C",
128
+ "\uFF63": "\u300D",
129
+ "\uFF65": "\u30FB"
130
+ };
131
+ var defaultFormat = (value) => {
132
+ value = value.replace(
133
+ /[!-~]/g,
134
+ (v) => String.fromCharCode(v.charCodeAt(0) - 65248)
135
+ );
136
+ const reg = new RegExp("(" + Object.keys(kanaMap).join("|") + ")", "g");
137
+ value = value.replace(reg, (v) => kanaMap[v]).replace(/゙/g, "\u309B").replace(/゚/g, "\u309C");
138
+ value = value.toUpperCase();
139
+ return value;
140
+ };
141
+ var flattenItems = (items) => {
142
+ const filterItems = (items2) => items2.map((item) => {
143
+ var _a;
144
+ const { isDisabled, isFocusable } = item;
145
+ const trulyDisabled = !!isDisabled && !isFocusable;
146
+ if (trulyDisabled) return;
147
+ if ("items" in item) {
148
+ return filterItems((_a = item.items) != null ? _a : []);
149
+ } else {
150
+ return item;
151
+ }
152
+ }).filter(Boolean);
153
+ return filterItems(items).flat(Infinity);
154
+ };
155
+ var useAutocomplete = (props) => {
156
+ const {
157
+ value: valueProp,
158
+ defaultValue,
159
+ onChange: onChangeProp,
160
+ onCreate: onCreateProp,
161
+ onSearch: onSearchProp,
162
+ closeOnSelect = true,
163
+ omitSelectedValues = false,
164
+ maxSelectValues,
165
+ allowCreate = false,
166
+ allowFree = false,
167
+ insertPositionItem = "first",
168
+ emptyMessage = "No results found",
169
+ format = defaultFormat,
170
+ optionProps,
171
+ placeholder,
172
+ onKeyDown: onKeyDownProp,
173
+ isOpen: isOpenProp,
174
+ defaultIsOpen,
175
+ onOpen: onOpenProp,
176
+ onClose: onCloseProp,
177
+ closeOnBlur = true,
178
+ closeOnEsc = true,
179
+ openDelay,
180
+ closeDelay,
181
+ isLazy,
182
+ lazyBehavior,
183
+ animation,
184
+ duration = 0.2,
185
+ offset,
186
+ gutter,
187
+ preventOverflow,
188
+ flip,
189
+ matchWidth = true,
190
+ boundary,
191
+ eventListeners,
192
+ strategy,
193
+ placement = "bottom-start",
194
+ modifiers,
195
+ items,
196
+ children,
197
+ ...rest
198
+ } = useFormControlProps(props);
199
+ const {
200
+ "aria-readonly": _ariaReadonly,
201
+ onFocus: onFocusProp,
202
+ ...formControlProps
203
+ } = pickObject(rest, formControlProperties);
204
+ const [containerProps, inputProps] = splitObject(rest, layoutStyleProperties);
205
+ const { id } = rest;
206
+ const descendants = useAutocompleteDescendants();
207
+ const containerRef = useRef(null);
208
+ const listRef = useRef(null);
209
+ const inputRef = useRef(null);
210
+ const timeoutIds = useRef(/* @__PURE__ */ new Set([]));
211
+ const isComposition = useRef(false);
212
+ const prevValue = useRef(void 0);
213
+ const [resolvedItems, setResolvedItems] = useState(items ? JSON.parse(JSON.stringify(items)) : void 0);
214
+ const [value, setValue] = useControllableState({
215
+ value: valueProp,
216
+ defaultValue,
217
+ onChange: onChangeProp
218
+ });
219
+ const [label, setLabel] = useState(void 0);
220
+ const [inputValue, setInputValue] = useState("");
221
+ const [focusedIndex, setFocusedIndex] = useState(-1);
222
+ const [isAllSelected, setIsAllSelected] = useState(false);
223
+ const [isHit, setIsHit] = useState(true);
224
+ const {
225
+ isOpen,
226
+ onOpen: onInternalOpen,
227
+ onClose
228
+ } = useDisclosure({
229
+ isOpen: isOpenProp,
230
+ defaultIsOpen,
231
+ onOpen: onOpenProp,
232
+ onClose: onCloseProp
233
+ });
234
+ const isFocused = focusedIndex > -1;
235
+ const isCreate = focusedIndex === -2 && allowCreate;
236
+ const isMulti = isArray(value);
237
+ const isEmptyValue = !isMulti ? !value : !value.length;
238
+ const [firstInsertPositionItem, secondInsertPositionItem] = useMemo(() => {
239
+ if (isArray(insertPositionItem)) {
240
+ return insertPositionItem;
241
+ } else {
242
+ return [insertPositionItem, "first"];
243
+ }
244
+ }, [insertPositionItem]);
245
+ if (allowCreate && !isUndefined(children)) {
246
+ console.warn(
247
+ `${!isMulti ? "Autocomplete" : "MultiAutocomplete"}: ${!isMulti ? "Autocomplete" : "MultiAutocomplete"} internally prefers 'children'. If 'allowCreate' is true, it will not be reflected correctly. If want to reflect, please set 'items' in props.`
248
+ );
249
+ }
250
+ const selectedValues = descendants.enabledValues(
251
+ ({ node }) => {
252
+ var _a;
253
+ return isMulti && value.includes((_a = node.dataset.value) != null ? _a : "");
254
+ }
255
+ );
256
+ const selectedIndexes = selectedValues.map(({ index }) => index);
257
+ const enabledValues = descendants.enabledValues(
258
+ ({ node, index }) => "target" in node.dataset && !selectedIndexes.includes(index)
259
+ );
260
+ const validChildren = getValidChildren(children);
261
+ const computedChildren = useMemo(
262
+ () => resolvedItems == null ? void 0 : resolvedItems.map((item, i) => {
263
+ if ("value" in item) {
264
+ const { label: label2, value: value2, ...props2 } = item;
265
+ return /* @__PURE__ */ jsx(AutocompleteOption, { value: value2, ...props2, children: label2 }, i);
266
+ } else if ("items" in item) {
267
+ const { label: label2, items: items2 = [], ...props2 } = item;
268
+ return /* @__PURE__ */ jsx(AutocompleteOptionGroup, { label: label2, ...props2, children: items2.map(({ label: label3, value: value2, ...props3 }, i2) => /* @__PURE__ */ jsx(AutocompleteOption, { value: value2, ...props3, children: label3 }, i2)) }, i);
269
+ }
270
+ }),
271
+ [resolvedItems]
272
+ );
273
+ const isEmpty = !validChildren.length && !(computedChildren == null ? void 0 : computedChildren.length);
274
+ const onOpen = useCallback(() => {
275
+ if (formControlProps.disabled || formControlProps.readOnly) return;
276
+ if (!allowCreate && (isEmpty || isAllSelected)) return;
277
+ onInternalOpen();
278
+ if (inputRef.current) inputRef.current.focus();
279
+ }, [allowCreate, formControlProps, isAllSelected, isEmpty, onInternalOpen]);
280
+ const onFocusFirst = useCallback(() => {
281
+ const id2 = setTimeout(() => {
282
+ if (isEmpty || isAllSelected) return;
283
+ const first = descendants.enabledFirstValue(
284
+ ({ node }) => "target" in node.dataset
285
+ );
286
+ if (!first) return;
287
+ if (!isMulti || !omitSelectedValues) {
288
+ setFocusedIndex(first.index);
289
+ } else {
290
+ if (selectedIndexes.includes(first.index)) {
291
+ const enabledFirst = enabledValues[0];
292
+ setFocusedIndex(enabledFirst.index);
293
+ } else {
294
+ setFocusedIndex(first.index);
295
+ }
296
+ }
297
+ });
298
+ timeoutIds.current.add(id2);
299
+ }, [
300
+ descendants,
301
+ enabledValues,
302
+ isAllSelected,
303
+ isEmpty,
304
+ isMulti,
305
+ omitSelectedValues,
306
+ selectedIndexes
307
+ ]);
308
+ const onFocusLast = useCallback(() => {
309
+ const id2 = setTimeout(() => {
310
+ if (isEmpty || isAllSelected) return;
311
+ const last = descendants.enabledLastValue(
312
+ ({ node }) => "target" in node.dataset
313
+ );
314
+ if (!last) return;
315
+ if (!isMulti || !omitSelectedValues) {
316
+ setFocusedIndex(last.index);
317
+ } else {
318
+ if (selectedIndexes.includes(last.index)) {
319
+ const enabledLast = enabledValues.reverse()[0];
320
+ setFocusedIndex(enabledLast.index);
321
+ } else {
322
+ setFocusedIndex(last.index);
323
+ }
324
+ }
325
+ });
326
+ timeoutIds.current.add(id2);
327
+ }, [
328
+ descendants,
329
+ enabledValues,
330
+ isAllSelected,
331
+ isEmpty,
332
+ isMulti,
333
+ omitSelectedValues,
334
+ selectedIndexes
335
+ ]);
336
+ const onFocusSelected = useCallback(() => {
337
+ const id2 = setTimeout(() => {
338
+ const values = descendants.enabledValues();
339
+ const selected = values.find(
340
+ ({ node }) => {
341
+ var _a;
342
+ return !isMulti ? node.dataset.value === value : value.includes((_a = node.dataset.value) != null ? _a : "");
343
+ }
344
+ );
345
+ if (selected) setFocusedIndex(selected.index);
346
+ });
347
+ timeoutIds.current.add(id2);
348
+ }, [descendants, isMulti, value]);
349
+ const onFocusNext = useCallback(
350
+ (index = focusedIndex) => {
351
+ const id2 = setTimeout(() => {
352
+ var _a;
353
+ const next = descendants.enabledNextValue(
354
+ index,
355
+ ({ node }) => "target" in node.dataset
356
+ );
357
+ if (!next) return;
358
+ if (!isMulti || !omitSelectedValues) {
359
+ setFocusedIndex(next.index);
360
+ } else {
361
+ if (selectedIndexes.includes(next.index)) {
362
+ const enabledNext = (_a = enabledValues.find(({ index: index2 }) => next.index < index2)) != null ? _a : enabledValues[0];
363
+ setFocusedIndex(enabledNext.index);
364
+ } else {
365
+ setFocusedIndex(next.index);
366
+ }
367
+ }
368
+ });
369
+ timeoutIds.current.add(id2);
370
+ },
371
+ [
372
+ descendants,
373
+ enabledValues,
374
+ focusedIndex,
375
+ isMulti,
376
+ omitSelectedValues,
377
+ selectedIndexes
378
+ ]
379
+ );
380
+ const onFocusPrev = useCallback(
381
+ (index = focusedIndex) => {
382
+ const id2 = setTimeout(() => {
383
+ var _a;
384
+ const prev = descendants.enabledPrevValue(
385
+ index,
386
+ ({ node }) => "target" in node.dataset
387
+ );
388
+ if (!prev) return;
389
+ if (!isMulti || !omitSelectedValues) {
390
+ setFocusedIndex(prev.index);
391
+ } else {
392
+ if (selectedIndexes.includes(prev.index)) {
393
+ const enabledPrev = (_a = enabledValues.reverse().find(({ index: index2 }) => index2 < prev.index)) != null ? _a : enabledValues[0];
394
+ setFocusedIndex(enabledPrev.index);
395
+ } else {
396
+ setFocusedIndex(prev.index);
397
+ }
398
+ }
399
+ });
400
+ timeoutIds.current.add(id2);
401
+ },
402
+ [
403
+ descendants,
404
+ enabledValues,
405
+ focusedIndex,
406
+ isMulti,
407
+ omitSelectedValues,
408
+ selectedIndexes
409
+ ]
410
+ );
411
+ const onFocusFirstOrSelected = isEmptyValue || omitSelectedValues ? onFocusFirst : onFocusSelected;
412
+ const onFocusLastOrSelected = isEmptyValue || omitSelectedValues ? onFocusLast : onFocusSelected;
413
+ const pickOptions = useCallback(
414
+ (value2) => {
415
+ const values = descendants.values();
416
+ let isHit2 = false;
417
+ let isFocused2 = false;
418
+ values.forEach(({ node, index }) => {
419
+ var _a;
420
+ if (format((_a = node.textContent) != null ? _a : "").includes(value2)) {
421
+ isHit2 = true;
422
+ const isDisabled = "disabled" in node.dataset;
423
+ node.dataset.target = "";
424
+ if (!isFocused2 && !isDisabled) {
425
+ isFocused2 = true;
426
+ setFocusedIndex(index);
427
+ }
428
+ } else {
429
+ delete node.dataset.target;
430
+ }
431
+ });
432
+ setIsHit(isHit2);
433
+ },
434
+ [descendants, format]
435
+ );
436
+ const rebirthOptions = useCallback(
437
+ (runFocus = true) => {
438
+ const values = descendants.values();
439
+ values.forEach(({ node }) => {
440
+ node.dataset.target = "";
441
+ });
442
+ if (runFocus) onFocusFirst();
443
+ setIsHit(true);
444
+ },
445
+ [descendants, onFocusFirst]
446
+ );
447
+ const getSelectedValues = useCallback(
448
+ (newValues) => {
449
+ const enabledValues2 = descendants.enabledValues();
450
+ const resolvedValues = isArray(newValues) ? newValues : [newValues];
451
+ const selectedValues2 = resolvedValues.map((value2) => {
452
+ var _a, _b;
453
+ const { node } = (_a = enabledValues2.find(({ node: node2 }) => node2.dataset.value === value2)) != null ? _a : {};
454
+ if (node) {
455
+ const el = Array.from(node.children).find(
456
+ (child) => child.getAttribute("data-label") !== null
457
+ );
458
+ return (_b = el == null ? void 0 : el.textContent) != null ? _b : void 0;
459
+ } else {
460
+ return allowFree ? value2 : void 0;
461
+ }
462
+ }).filter(Boolean);
463
+ return selectedValues2;
464
+ },
465
+ [allowFree, descendants]
466
+ );
467
+ const onChangeLabel = useCallback(
468
+ (newValue, { forceUpdate, runOmit = true } = {}) => {
469
+ const selectedValues2 = getSelectedValues(newValue);
470
+ if (!forceUpdate && !selectedValues2.length) return;
471
+ setLabel((prev) => {
472
+ if (!isMulti) {
473
+ return selectedValues2[0];
474
+ } else {
475
+ selectedValues2.forEach((selectedValue) => {
476
+ const isSelected = isArray(prev) && prev.includes(selectedValue != null ? selectedValue : "");
477
+ if (!isSelected) {
478
+ prev = [...isArray(prev) ? prev : [], selectedValue];
479
+ } else if (runOmit) {
480
+ prev = isArray(prev) ? prev.filter((value2) => value2 !== selectedValue) : void 0;
481
+ }
482
+ });
483
+ return prev;
484
+ }
485
+ });
486
+ },
487
+ [getSelectedValues, isMulti]
488
+ );
489
+ const onChange = useCallback(
490
+ (newValue, { forceUpdate, runRebirth = true } = {}) => {
491
+ setValue((prev) => {
492
+ let next;
493
+ if (!isArray(prev)) {
494
+ next = newValue;
495
+ } else {
496
+ const isSelected = prev.includes(newValue);
497
+ if (!isSelected) {
498
+ next = [...prev, newValue];
499
+ } else {
500
+ next = prev.filter((value2) => value2 !== newValue);
501
+ }
502
+ }
503
+ prevValue.current = next;
504
+ return next;
505
+ });
506
+ const isHit2 = descendants.values().filter(
507
+ ({ node }) => {
508
+ var _a;
509
+ return format((_a = node.textContent) != null ? _a : "").includes(newValue);
510
+ }
511
+ ).length > 0;
512
+ onChangeLabel(newValue, { forceUpdate });
513
+ if (allowFree || isHit2) setInputValue("");
514
+ if (isMulti && runRebirth) rebirthOptions(false);
515
+ },
516
+ [
517
+ allowFree,
518
+ isMulti,
519
+ onChangeLabel,
520
+ rebirthOptions,
521
+ setValue,
522
+ descendants,
523
+ format
524
+ ]
525
+ );
526
+ const onSelect = useCallback(() => {
527
+ var _a, _b;
528
+ let enabledValue = descendants.value(focusedIndex);
529
+ if ("disabled" in ((_a = enabledValue == null ? void 0 : enabledValue.node.dataset) != null ? _a : {}))
530
+ enabledValue = void 0;
531
+ if (!enabledValue) return;
532
+ const value2 = (_b = enabledValue.node.dataset.value) != null ? _b : "";
533
+ onChange(value2);
534
+ if (closeOnSelect) onClose();
535
+ if (omitSelectedValues) onFocusNext();
536
+ }, [
537
+ closeOnSelect,
538
+ descendants,
539
+ focusedIndex,
540
+ omitSelectedValues,
541
+ onChange,
542
+ onClose,
543
+ onFocusNext
544
+ ]);
545
+ const onSearch = useCallback(
546
+ (ev) => {
547
+ if (!isOpen) onOpen();
548
+ onSearchProp == null ? void 0 : onSearchProp(ev);
549
+ const value2 = ev.target.value;
550
+ const computedValue = format(value2);
551
+ if (computedValue) {
552
+ pickOptions(computedValue);
553
+ } else {
554
+ rebirthOptions();
555
+ }
556
+ setInputValue(value2);
557
+ },
558
+ [isOpen, onOpen, format, onSearchProp, pickOptions, rebirthOptions]
559
+ );
560
+ const onCompositionStart = useCallback(() => {
561
+ isComposition.current = true;
562
+ }, []);
563
+ const onCompositionEnd = useCallback(() => {
564
+ isComposition.current = false;
565
+ }, []);
566
+ const onCreate = useCallback(() => {
567
+ var _a, _b;
568
+ if (!listRef.current) return;
569
+ const newItem = { label: inputValue, value: inputValue };
570
+ let newItems = [];
571
+ if (resolvedItems) newItems = [...resolvedItems];
572
+ if (firstInsertPositionItem === "first") {
573
+ newItems = [newItem, ...newItems];
574
+ } else if (firstInsertPositionItem === "last") {
575
+ newItems = [...newItems, newItem];
576
+ } else {
577
+ const i = newItems.findIndex(
578
+ ({ label: label2 }) => label2 === firstInsertPositionItem
579
+ );
580
+ const targetItem = newItems[i];
581
+ if (i !== -1 && "items" in targetItem) {
582
+ if (secondInsertPositionItem === "first") {
583
+ targetItem.items = [newItem, ...(_a = targetItem.items) != null ? _a : []];
584
+ } else {
585
+ targetItem.items = [...(_b = targetItem.items) != null ? _b : [], newItem];
586
+ }
587
+ newItems[i] = targetItem;
588
+ } else {
589
+ console.warn(
590
+ `${!isMulti ? "Autocomplete" : "MultiAutocomplete"}: '${firstInsertPositionItem}' specified in insertPositionItem does not exist in the option group.`
591
+ );
592
+ }
593
+ }
594
+ setResolvedItems(newItems);
595
+ onChange(inputValue);
596
+ rebirthOptions(false);
597
+ const index = flattenItems(newItems).findIndex(
598
+ ({ value: value2 }) => value2 === inputValue
599
+ );
600
+ setFocusedIndex(index);
601
+ onCreateProp == null ? void 0 : onCreateProp(newItem, newItems);
602
+ }, [
603
+ inputValue,
604
+ resolvedItems,
605
+ firstInsertPositionItem,
606
+ onChange,
607
+ rebirthOptions,
608
+ onCreateProp,
609
+ secondInsertPositionItem,
610
+ isMulti
611
+ ]);
612
+ const onClick = useCallback(() => {
613
+ if (isOpen) {
614
+ if (inputRef.current) inputRef.current.focus();
615
+ } else {
616
+ onOpen();
617
+ onFocusFirstOrSelected();
618
+ }
619
+ }, [isOpen, onFocusFirstOrSelected, onOpen]);
620
+ const onFocus = useCallback(() => {
621
+ if (isOpen) return;
622
+ onOpen();
623
+ onFocusFirstOrSelected();
624
+ }, [isOpen, onFocusFirstOrSelected, onOpen]);
625
+ const onBlur = useCallback(
626
+ (ev) => {
627
+ const relatedTarget = getEventRelatedTarget(ev);
628
+ if (isContains(containerRef.current, relatedTarget)) return;
629
+ if (!closeOnBlur && isHit) return;
630
+ if (allowFree && !!inputValue) onChange(inputValue, { runRebirth: false });
631
+ setInputValue("");
632
+ if (isOpen) onClose();
633
+ },
634
+ [closeOnBlur, isHit, isOpen, inputValue, allowFree, onClose, onChange]
635
+ );
636
+ const onDelete = useCallback(() => {
637
+ if (!isMulti) {
638
+ onChange("", { forceUpdate: true });
639
+ } else {
640
+ onChange(value[value.length - 1]);
641
+ }
642
+ if (!isOpen) onFocus();
643
+ }, [isMulti, isOpen, onChange, onFocus, value]);
644
+ const onClear = useCallback(
645
+ (ev) => {
646
+ ev.stopPropagation();
647
+ prevValue.current = [];
648
+ setValue([]);
649
+ setLabel(void 0);
650
+ setInputValue("");
651
+ rebirthOptions();
652
+ if (isOpen && inputRef.current) inputRef.current.focus();
653
+ },
654
+ [isOpen, setLabel, setInputValue, setValue, rebirthOptions]
655
+ );
656
+ const onKeyDown = useCallback(
657
+ (ev) => {
658
+ if (ev.key === " ") ev.key = ev.code;
659
+ if (formControlProps.disabled || formControlProps.readOnly) return;
660
+ if (isComposition.current) return;
661
+ const enabledDelete = label === inputValue || !inputValue.length;
662
+ const actions = {
663
+ ArrowDown: isFocused ? () => onFocusNext() : !isOpen ? funcAll(onOpen, onFocusFirstOrSelected) : void 0,
664
+ ArrowUp: isFocused ? () => onFocusPrev() : !isOpen ? funcAll(onOpen, onFocusLastOrSelected) : void 0,
665
+ Space: isCreate ? onCreate : isFocused ? onSelect : !isOpen ? funcAll(onOpen, onFocusFirstOrSelected) : void 0,
666
+ Enter: isCreate ? onCreate : isFocused ? onSelect : !isOpen ? funcAll(onOpen, onFocusFirstOrSelected) : allowFree && isMulti ? () => {
667
+ if (inputValue) onChange(inputValue);
668
+ setFocusedIndex(0);
669
+ } : void 0,
670
+ Home: isOpen ? onFocusFirst : void 0,
671
+ End: isOpen ? onFocusLast : void 0,
672
+ Escape: closeOnEsc ? onClose : void 0,
673
+ Backspace: !isEmptyValue && enabledDelete ? onDelete : void 0
674
+ };
675
+ const action = actions[ev.key];
676
+ if (!action) return;
677
+ ev.preventDefault();
678
+ ev.stopPropagation();
679
+ action(ev);
680
+ },
681
+ [
682
+ allowFree,
683
+ formControlProps,
684
+ label,
685
+ inputValue,
686
+ onOpen,
687
+ isFocused,
688
+ isMulti,
689
+ onFocusFirstOrSelected,
690
+ onFocusNext,
691
+ onFocusLastOrSelected,
692
+ onFocusPrev,
693
+ isCreate,
694
+ onCreate,
695
+ onSelect,
696
+ isOpen,
697
+ onFocusFirst,
698
+ onFocusLast,
699
+ closeOnEsc,
700
+ onClose,
701
+ isEmptyValue,
702
+ onDelete,
703
+ onChange
704
+ ]
705
+ );
706
+ useEffect(() => {
707
+ if (!isMulti) return;
708
+ if (!omitSelectedValues && isUndefined(maxSelectValues)) return;
709
+ const isAll = value.length > 0 && value.length === descendants.count();
710
+ const isMax = value.length === maxSelectValues;
711
+ if (isAll || isMax) {
712
+ onClose();
713
+ setIsAllSelected(true);
714
+ } else {
715
+ setIsAllSelected(false);
716
+ }
717
+ }, [
718
+ omitSelectedValues,
719
+ value,
720
+ descendants,
721
+ isMulti,
722
+ onClose,
723
+ maxSelectValues
724
+ ]);
725
+ useEffect(() => {
726
+ var _a;
727
+ if (isMulti) {
728
+ if (JSON.stringify((_a = prevValue.current) != null ? _a : []) === JSON.stringify(value != null ? value : []))
729
+ return;
730
+ const label2 = getSelectedValues(value);
731
+ setLabel(label2);
732
+ } else {
733
+ if (prevValue.current === value) return;
734
+ onChangeLabel(value, { runOmit: false });
735
+ }
736
+ }, [isMulti, value, onChangeLabel, getSelectedValues]);
737
+ useUpdateEffect(() => {
738
+ if (isOpen || allowFree) return;
739
+ setFocusedIndex(-1);
740
+ setInputValue("");
741
+ }, [isOpen]);
742
+ useUpdateEffect(() => {
743
+ if (!isHit) setFocusedIndex(-2);
744
+ }, [isHit]);
745
+ useUpdateEffect(() => {
746
+ setResolvedItems(items ? JSON.parse(JSON.stringify(items)) : void 0);
747
+ }, [items]);
748
+ useUnmountEffect(() => {
749
+ timeoutIds.current.forEach((id2) => clearTimeout(id2));
750
+ timeoutIds.current.clear();
751
+ });
752
+ useOutsideClick({
753
+ ref: containerRef,
754
+ handler: onClose,
755
+ enabled: isOpen && (closeOnBlur || !isHit)
756
+ });
757
+ const getPopoverProps = useCallback(
758
+ (props2) => ({
759
+ closeOnBlur,
760
+ openDelay,
761
+ closeDelay,
762
+ isLazy,
763
+ lazyBehavior,
764
+ animation,
765
+ duration,
766
+ offset,
767
+ gutter,
768
+ preventOverflow,
769
+ flip,
770
+ matchWidth,
771
+ boundary,
772
+ eventListeners,
773
+ strategy,
774
+ placement,
775
+ modifiers,
776
+ ...props2,
777
+ trigger: "never",
778
+ closeOnButton: false,
779
+ isOpen,
780
+ onOpen,
781
+ onClose
782
+ }),
783
+ [
784
+ closeOnBlur,
785
+ openDelay,
786
+ closeDelay,
787
+ isLazy,
788
+ lazyBehavior,
789
+ animation,
790
+ duration,
791
+ offset,
792
+ gutter,
793
+ preventOverflow,
794
+ flip,
795
+ matchWidth,
796
+ boundary,
797
+ eventListeners,
798
+ strategy,
799
+ placement,
800
+ modifiers,
801
+ isOpen,
802
+ onOpen,
803
+ onClose
804
+ ]
805
+ );
806
+ const getContainerProps = useCallback(
807
+ (props2 = {}, ref = null) => ({
808
+ ref: mergeRefs(containerRef, ref),
809
+ ...containerProps,
810
+ ...props2,
811
+ ...formControlProps,
812
+ onClick: handlerAll(props2.onClick, rest.onClick, onClick),
813
+ onBlur: handlerAll(props2.onBlur, rest.onBlur, onBlur)
814
+ }),
815
+ [containerProps, formControlProps, onBlur, onClick, rest]
816
+ );
817
+ const getFieldProps = useCallback(
818
+ (props2 = {}, ref = null) => ({
819
+ ref,
820
+ tabIndex: -1,
821
+ ...props2,
822
+ ...formControlProps,
823
+ placeholder,
824
+ "data-active": dataAttr(isOpen),
825
+ "aria-expanded": dataAttr(isOpen),
826
+ onFocus: handlerAll(props2.onFocus, onFocusProp, onFocus),
827
+ onKeyDown: handlerAll(props2.onKeyDown, onKeyDownProp, onKeyDown)
828
+ }),
829
+ [
830
+ formControlProps,
831
+ placeholder,
832
+ isOpen,
833
+ onFocusProp,
834
+ onFocus,
835
+ onKeyDownProp,
836
+ onKeyDown
837
+ ]
838
+ );
839
+ return {
840
+ id,
841
+ descendants,
842
+ value,
843
+ label,
844
+ inputValue,
845
+ isHit,
846
+ isEmpty,
847
+ computedChildren,
848
+ focusedIndex,
849
+ omitSelectedValues,
850
+ closeOnSelect,
851
+ allowCreate,
852
+ allowFree,
853
+ emptyMessage,
854
+ isOpen,
855
+ isAllSelected,
856
+ listRef,
857
+ inputRef,
858
+ optionProps,
859
+ formControlProps,
860
+ setFocusedIndex,
861
+ onChangeLabel,
862
+ onChange,
863
+ onSearch,
864
+ onCreate,
865
+ onClear,
866
+ onCompositionStart,
867
+ onCompositionEnd,
868
+ pickOptions,
869
+ rebirthOptions,
870
+ onOpen,
871
+ onClose,
872
+ onFocusFirst,
873
+ onFocusLast,
874
+ onFocusSelected,
875
+ onFocusNext,
876
+ onFocusPrev,
877
+ getPopoverProps,
878
+ getContainerProps,
879
+ getFieldProps,
880
+ inputProps
881
+ };
882
+ };
883
+ var useAutocompleteInput = () => {
884
+ const {
885
+ id,
886
+ inputRef,
887
+ onSearch,
888
+ onCompositionStart,
889
+ onCompositionEnd,
890
+ isAllSelected,
891
+ formControlProps,
892
+ inputProps,
893
+ isOpen,
894
+ focusedIndex,
895
+ listRef
896
+ } = useAutocompleteContext();
897
+ const { value } = useAutocompleteDescendantsContext();
898
+ useUpdateEffect(() => {
899
+ if (isAllSelected && inputRef.current) inputRef.current.blur();
900
+ }, [isAllSelected]);
901
+ const getInputProps = useCallback(
902
+ (props = {}, ref = null) => {
903
+ var _a, _b;
904
+ return {
905
+ ref: mergeRefs(inputRef, ref),
906
+ ...formControlProps,
907
+ role: "combobox",
908
+ "aria-haspopup": "listbox",
909
+ "aria-autocomplete": "list",
910
+ "aria-expanded": isOpen,
911
+ "aria-activedescendant": (_a = value(focusedIndex)) == null ? void 0 : _a.node.id,
912
+ "aria-controls": (_b = listRef.current) == null ? void 0 : _b.id,
913
+ autoCapitalize: "none",
914
+ autoComplete: "off",
915
+ spellCheck: "false",
916
+ ...inputProps,
917
+ ...props,
918
+ id,
919
+ cursor: formControlProps.readOnly ? "default" : "text",
920
+ pointerEvents: formControlProps.disabled || isAllSelected ? "none" : "auto",
921
+ tabIndex: isAllSelected ? -1 : 0,
922
+ onChange: handlerAll(props.onChange, onSearch),
923
+ onCompositionStart: handlerAll(
924
+ props.onCompositionStart,
925
+ inputProps.onCompositionStart,
926
+ onCompositionStart
927
+ ),
928
+ onCompositionEnd: handlerAll(
929
+ props.onCompositionEnd,
930
+ inputProps.onCompositionEnd,
931
+ onCompositionEnd
932
+ )
933
+ };
934
+ },
935
+ [
936
+ listRef,
937
+ focusedIndex,
938
+ isOpen,
939
+ inputProps,
940
+ inputRef,
941
+ formControlProps,
942
+ id,
943
+ isAllSelected,
944
+ value,
945
+ onSearch,
946
+ onCompositionStart,
947
+ onCompositionEnd
948
+ ]
949
+ );
950
+ return {
951
+ getInputProps
952
+ };
953
+ };
954
+
955
+ export {
956
+ useAutocomplete,
957
+ useAutocompleteInput
958
+ };
959
+ //# sourceMappingURL=chunk-GM7RV2YY.mjs.map