@react-fabric/form 1.0.0-beta.8 → 1.0.1

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 (215) hide show
  1. package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
  2. package/css/_colorPicker.css +95 -0
  3. package/{src/internal/Field.module.css → css/_field.css} +94 -33
  4. package/{src/input/File.module.css → css/_file.css} +21 -6
  5. package/css/styles.css +27 -0
  6. package/dist/cjs/builder/FileField.js +107 -78
  7. package/dist/cjs/builder/FormField.js +60 -39
  8. package/dist/cjs/builder/SchemaEditor.js +72 -0
  9. package/dist/cjs/builder/components/AddSchemaFields.js +64 -0
  10. package/dist/cjs/builder/components/SchemaArrayForm.js +146 -0
  11. package/dist/cjs/builder/components/SchemaField.js +423 -0
  12. package/dist/cjs/form/Controller.js +66 -19
  13. package/dist/cjs/form/Form.js +97 -39
  14. package/dist/cjs/form/useForm.js +32 -0
  15. package/dist/cjs/hooks/useFileUploader.js +74 -45
  16. package/dist/cjs/hooks/useFormBuilder.js +85 -31
  17. package/dist/cjs/i18n/{ar.json.js → ar/form.json.js} +5 -4
  18. package/dist/cjs/i18n/{en.json.js → en/form.json.js} +5 -5
  19. package/dist/cjs/i18n/index.js +4 -4
  20. package/dist/cjs/index.js +41 -2
  21. package/dist/cjs/input/ArrayInput.js +259 -135
  22. package/dist/cjs/input/AvatarInput.js +99 -63
  23. package/dist/cjs/input/Checkbox.js +24 -25
  24. package/dist/cjs/input/ColorInput.js +138 -81
  25. package/dist/cjs/input/ColorPicker.js +78 -95
  26. package/dist/cjs/input/DateInput.js +192 -0
  27. package/dist/cjs/input/Field.js +21 -20
  28. package/dist/cjs/input/File.js +85 -80
  29. package/dist/cjs/input/Hidden.js +27 -13
  30. package/dist/cjs/input/Input.js +49 -48
  31. package/dist/cjs/input/Number.js +46 -44
  32. package/dist/cjs/input/Password.js +51 -49
  33. package/dist/cjs/input/Radio.js +26 -16
  34. package/dist/cjs/input/RadioGroup.js +26 -11
  35. package/dist/cjs/input/{Range.js → RangeSlider.js} +61 -66
  36. package/dist/cjs/input/Search.js +58 -64
  37. package/dist/cjs/input/Slider.js +57 -66
  38. package/dist/cjs/input/Switch.js +29 -27
  39. package/dist/cjs/input/Textarea.js +65 -53
  40. package/dist/cjs/internal/ErrorIcon.js +9 -9
  41. package/dist/cjs/internal/FieldWrapper.js +23 -13
  42. package/dist/cjs/internal/InputWrapper.js +85 -87
  43. package/dist/cjs/ranger/index.js +7 -7
  44. package/dist/cjs/ranger/utils.js +9 -4
  45. package/dist/cjs/select/AutoComplete.js +93 -76
  46. package/dist/cjs/select/DualList.js +235 -154
  47. package/dist/cjs/select/List.js +122 -89
  48. package/dist/cjs/select/Options.js +58 -54
  49. package/dist/cjs/select/Select.js +119 -89
  50. package/dist/cjs/select/helpers.js +5 -5
  51. package/dist/cjs/select/useSelect.js +83 -58
  52. package/dist/cjs/types/schema.js +43 -0
  53. package/dist/cjs/utils/eventHandlers.js +16 -6
  54. package/dist/cjs/utils/getColor.js +6 -6
  55. package/dist/cjs/utils/getProps.js +49 -0
  56. package/dist/esm/builder/FileField.js +109 -80
  57. package/dist/esm/builder/FormField.js +60 -39
  58. package/dist/esm/builder/SchemaEditor.js +72 -0
  59. package/dist/esm/builder/components/AddSchemaFields.js +64 -0
  60. package/dist/esm/builder/components/SchemaArrayForm.js +146 -0
  61. package/dist/esm/builder/components/SchemaField.js +423 -0
  62. package/dist/esm/form/Controller.js +66 -19
  63. package/dist/esm/form/Form.js +97 -39
  64. package/dist/esm/form/useForm.js +32 -0
  65. package/dist/esm/hooks/useFileUploader.js +75 -46
  66. package/dist/esm/hooks/useFormBuilder.js +84 -30
  67. package/dist/esm/i18n/{ar.json.js → ar/form.json.js} +5 -4
  68. package/dist/esm/i18n/{en.json.js → en/form.json.js} +5 -5
  69. package/dist/esm/i18n/index.js +2 -2
  70. package/dist/esm/index.js +36 -1
  71. package/dist/esm/input/ArrayInput.js +260 -136
  72. package/dist/esm/input/AvatarInput.js +99 -63
  73. package/dist/esm/input/Checkbox.js +26 -27
  74. package/dist/esm/input/ColorInput.js +141 -84
  75. package/dist/esm/input/ColorPicker.js +80 -97
  76. package/dist/esm/input/DateInput.js +192 -0
  77. package/dist/esm/input/Field.js +21 -20
  78. package/dist/esm/input/File.js +89 -84
  79. package/dist/esm/input/Hidden.js +28 -14
  80. package/dist/esm/input/Input.js +51 -50
  81. package/dist/esm/input/Number.js +48 -46
  82. package/dist/esm/input/Password.js +54 -52
  83. package/dist/esm/input/Radio.js +27 -17
  84. package/dist/esm/input/RadioGroup.js +27 -12
  85. package/dist/esm/input/{Range.js → RangeSlider.js} +62 -67
  86. package/dist/esm/input/Search.js +61 -67
  87. package/dist/esm/input/Slider.js +58 -67
  88. package/dist/esm/input/Switch.js +31 -29
  89. package/dist/esm/input/Textarea.js +67 -55
  90. package/dist/esm/internal/ErrorIcon.js +11 -11
  91. package/dist/esm/internal/FieldWrapper.js +23 -13
  92. package/dist/esm/internal/InputWrapper.js +88 -90
  93. package/dist/esm/ranger/index.js +7 -7
  94. package/dist/esm/ranger/utils.js +9 -4
  95. package/dist/esm/select/AutoComplete.js +95 -78
  96. package/dist/esm/select/DualList.js +233 -152
  97. package/dist/esm/select/List.js +125 -92
  98. package/dist/esm/select/Options.js +58 -54
  99. package/dist/esm/select/Select.js +122 -92
  100. package/dist/esm/select/helpers.js +5 -5
  101. package/dist/esm/select/useSelect.js +84 -59
  102. package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
  103. package/dist/esm/utils/eventHandlers.js +16 -6
  104. package/dist/esm/utils/getColor.js +6 -6
  105. package/dist/esm/utils/getProps.js +49 -0
  106. package/dist/types/builder/FileField.d.ts +7 -4
  107. package/dist/types/builder/FormField.d.ts +4 -2
  108. package/dist/types/builder/SchemaEditor.d.ts +6 -0
  109. package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
  110. package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
  111. package/dist/types/builder/components/SchemaField.d.ts +12 -0
  112. package/dist/types/form/Controller.d.ts +45 -3
  113. package/dist/types/form/Form.d.ts +38 -7
  114. package/dist/types/form/useForm.d.ts +6 -0
  115. package/dist/types/hooks/useFileUploader.d.ts +24 -3
  116. package/dist/types/hooks/useFormBuilder.d.ts +41 -3
  117. package/dist/types/index.d.ts +32 -2
  118. package/dist/types/input/ArrayInput.d.ts +68 -13
  119. package/dist/types/input/AvatarInput.d.ts +23 -6
  120. package/dist/types/input/Checkbox.d.ts +12 -10
  121. package/dist/types/input/ColorInput.d.ts +15 -5
  122. package/dist/types/input/ColorPicker.d.ts +10 -2
  123. package/dist/types/input/DateInput.d.ts +21 -0
  124. package/dist/types/input/Field.d.ts +9 -36
  125. package/dist/types/input/File.d.ts +16 -4
  126. package/dist/types/input/Hidden.d.ts +7 -6
  127. package/dist/types/input/Input.d.ts +11 -4
  128. package/dist/types/input/Number.d.ts +9 -4
  129. package/dist/types/input/Password.d.ts +9 -4
  130. package/dist/types/input/Radio.d.ts +9 -4
  131. package/dist/types/input/RadioGroup.d.ts +14 -6
  132. package/dist/types/input/{Range.d.ts → RangeSlider.d.ts} +11 -6
  133. package/dist/types/input/Search.d.ts +14 -4
  134. package/dist/types/input/Slider.d.ts +9 -6
  135. package/dist/types/input/Switch.d.ts +13 -8
  136. package/dist/types/input/Textarea.d.ts +15 -4
  137. package/dist/types/internal/ErrorIcon.d.ts +4 -1
  138. package/dist/types/internal/FieldWrapper.d.ts +10 -1
  139. package/dist/types/internal/InputWrapper.d.ts +19 -1
  140. package/dist/types/ranger/index.d.ts +7 -3
  141. package/dist/types/ranger/utils.d.ts +2 -2
  142. package/dist/types/select/AutoComplete.d.ts +7 -2
  143. package/dist/types/select/DualList.d.ts +11 -37
  144. package/dist/types/select/List.d.ts +7 -2
  145. package/dist/types/select/Options.d.ts +8 -7
  146. package/dist/types/select/Select.d.ts +7 -2
  147. package/dist/types/select/helpers.d.ts +2 -2
  148. package/dist/types/select/useSelect.d.ts +10 -28
  149. package/dist/types/types/index.d.ts +73 -39
  150. package/dist/types/types/schema.d.ts +78 -32
  151. package/dist/types/utils/eventHandlers.d.ts +4 -4
  152. package/dist/types/utils/getColor.d.ts +4 -4
  153. package/dist/types/utils/getProps.d.ts +26 -0
  154. package/dist/types/utils/index.d.ts +1 -0
  155. package/package.json +25 -25
  156. package/src/builder/FileField.tsx +73 -56
  157. package/src/builder/FormField.tsx +66 -58
  158. package/src/builder/SchemaEditor.tsx +78 -0
  159. package/src/builder/components/AddSchemaFields.tsx +64 -0
  160. package/src/builder/components/SchemaArrayForm.tsx +146 -0
  161. package/src/builder/components/SchemaField.tsx +405 -0
  162. package/src/form/Controller.tsx +61 -24
  163. package/src/form/Form.tsx +74 -50
  164. package/src/form/useForm.ts +53 -0
  165. package/src/hooks/useFileUploader.ts +115 -84
  166. package/src/hooks/useFormBuilder.tsx +80 -41
  167. package/src/i18n/{ar.json → ar/form.json} +5 -4
  168. package/src/i18n/{en.json → en/form.json} +5 -5
  169. package/src/i18n/index.ts +2 -2
  170. package/src/index.ts +34 -20
  171. package/src/input/ArrayInput.tsx +255 -173
  172. package/src/input/AvatarInput.tsx +82 -39
  173. package/src/input/Checkbox.tsx +30 -54
  174. package/src/input/ColorInput.tsx +146 -105
  175. package/src/input/ColorPicker.tsx +76 -102
  176. package/src/input/DateInput.tsx +225 -0
  177. package/src/input/Field.tsx +23 -65
  178. package/src/input/File.tsx +76 -98
  179. package/src/input/Hidden.tsx +36 -24
  180. package/src/input/Input.tsx +55 -53
  181. package/src/input/Number.tsx +49 -54
  182. package/src/input/Password.tsx +61 -66
  183. package/src/input/Radio.tsx +28 -37
  184. package/src/input/RadioGroup.tsx +30 -25
  185. package/src/input/{Range.tsx → RangeSlider.tsx} +81 -109
  186. package/src/input/Search.tsx +64 -77
  187. package/src/input/Slider.tsx +80 -109
  188. package/src/input/Switch.tsx +39 -53
  189. package/src/input/Textarea.tsx +72 -59
  190. package/src/internal/ErrorIcon.tsx +22 -21
  191. package/src/internal/FieldWrapper.tsx +33 -23
  192. package/src/internal/InputWrapper.tsx +132 -143
  193. package/src/ranger/index.tsx +37 -117
  194. package/src/ranger/utils.ts +12 -11
  195. package/src/select/AutoComplete.tsx +113 -123
  196. package/src/select/DualList.tsx +218 -204
  197. package/src/select/List.tsx +130 -97
  198. package/src/select/Options.tsx +59 -57
  199. package/src/select/Select.tsx +148 -122
  200. package/src/select/helpers.ts +13 -8
  201. package/src/select/useSelect.tsx +110 -127
  202. package/src/types/index.ts +76 -45
  203. package/src/types/schema.ts +97 -40
  204. package/src/utils/eventHandlers.ts +24 -26
  205. package/src/utils/getColor.ts +9 -8
  206. package/src/utils/getProps.ts +47 -0
  207. package/src/utils/index.ts +1 -0
  208. package/dist/cjs/input/ArrayInput.module.css +0 -1
  209. package/dist/cjs/input/ColorPicker.module.css +0 -1
  210. package/dist/cjs/input/File.module.css +0 -1
  211. package/dist/cjs/internal/Field.module.css +0 -1
  212. package/dist/esm/input/ArrayInput.module.css +0 -1
  213. package/dist/esm/input/ColorPicker.module.css +0 -1
  214. package/dist/esm/input/File.module.css +0 -1
  215. package/dist/esm/internal/Field.module.css +0 -1
@@ -34,56 +34,59 @@ import {
34
34
  useListNavigation,
35
35
  useTypeahead,
36
36
  } from "@floating-ui/react";
37
- import { Chip, CoreIcons, Icon } from "@react-fabric/core";
38
- import { isArray, isEmpty } from "@react-fabric/utilities";
39
- import classNames from "classnames";
37
+ import { Chip, Icon } from "@react-fabric/core";
38
+ import type { RefProp } from "@react-fabric/core/dist/types/types";
39
+ import { cn, EMPTY_ARRAY, isArray, isEmpty } from "@react-fabric/utilities";
40
40
  import { useCallback, useId, useLayoutEffect, useMemo, useRef } from "react";
41
41
  import { InputWrapper } from "../internal/InputWrapper";
42
42
  import { type SelectProps } from "../types";
43
+ import { getWrapperProps } from "../utils";
43
44
  import { Options } from "./Options";
44
45
  import { useSelect } from "./useSelect";
45
46
 
46
- type AutoCompleteProps = Omit<
47
- SelectProps<string>,
48
- "options" | "allowCreate" | "createOption"
49
- > & {
50
- /**
51
- * auto-complete history
52
- */
53
- history?: string[];
54
- /**
55
- * expand input on edit
56
- */
57
- expandOnEdit?: boolean;
58
- /**
59
- * input change handler
60
- */
61
- onInput?: (query: string) => void;
62
- };
47
+ type AutoCompleteProps = Omit<SelectProps<string>, "ref" | "options" | "allowCreate" | "createOption"> &
48
+ RefProp<HTMLTextAreaElement> & {
49
+ /**
50
+ * auto-complete history
51
+ */
52
+ history?: string[];
53
+ /**
54
+ * expand input on edit
55
+ */
56
+ expandOnEdit?: boolean;
57
+ /**
58
+ * input change handler
59
+ */
60
+ onInput?: (query: string) => void;
61
+ };
63
62
 
64
- export const AutoComplete = ({
65
- ref,
66
- name,
67
- value,
68
- invalid,
69
- readOnly,
70
- disabled,
71
- required,
72
- placeholder,
73
- autoFocus,
74
- expandOnEdit,
75
- error,
76
- history,
77
- multiple,
78
- onChange,
79
- onSelect,
80
- onInput,
81
- onFocus,
82
- onBlur,
83
- onEnterPressed,
84
- ...rest
85
- }: AutoCompleteProps) => {
86
- const options = useRef(history);
63
+ /**
64
+ * AutoComplete component for selecting or entering values with history suggestions.
65
+ * It supports multiple selections, history suggestions, and custom styling.
66
+ */
67
+ export function AutoComplete(props: AutoCompleteProps) {
68
+ const {
69
+ ref,
70
+ name,
71
+ value,
72
+ invalid,
73
+ readOnly,
74
+ disabled,
75
+ placeholder,
76
+ autoFocus,
77
+ expandOnEdit,
78
+ history = EMPTY_ARRAY,
79
+ multiple,
80
+ allowClear,
81
+ onChange,
82
+ onSelect,
83
+ onInput,
84
+ onFocus,
85
+ onBlur,
86
+ onQuery,
87
+ onEnterPressed,
88
+ } = props;
89
+ const optionsRef = useRef(history);
87
90
  const submitRef = useRef<HTMLButtonElement>(null);
88
91
 
89
92
  const {
@@ -100,18 +103,19 @@ export const AutoComplete = ({
100
103
  } = useSelect({
101
104
  value,
102
105
  autoComplete: true,
103
- options: options.current,
106
+ options: optionsRef.current,
104
107
  multiple,
105
108
  onChange,
106
109
  onSelect,
110
+ onQuery,
107
111
  });
108
112
 
109
- const dropdownKey = useId();
113
+ const dropdownKeyId = useId();
110
114
 
111
115
  const { context, floatingStyles, refs } = useFloating({
112
116
  open: state.open,
113
- onOpenChange: (open, evt, reason) => {
114
- !open && (listRef.current = []);
117
+ onOpenChange: (open) => {
118
+ if (!open) listRef.current = [];
115
119
  setOpen(open);
116
120
  },
117
121
  strategy: "fixed",
@@ -143,28 +147,24 @@ export const AutoComplete = ({
143
147
  return list.find((item) => macthOption(item, typedString));
144
148
  },
145
149
  onMatch(index) {
146
- state.open && setActiveIndex(index);
150
+ if (state.open) setActiveIndex(index);
147
151
  },
148
152
  });
149
153
 
150
- const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions(
151
- [dismiss, navigation, typeahead],
152
- );
154
+ const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([dismiss, navigation, typeahead]);
153
155
 
154
156
  const referenceProps = useMemo(() => {
155
- const props: AnyObject = getReferenceProps();
157
+ const props = getReferenceProps();
156
158
 
157
159
  return {
158
160
  ...props,
159
161
  onFocus,
160
162
  onBlur(evt: React.FocusEvent) {
161
- if (
162
- evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKey}"]`)
163
- ) {
163
+ if (evt.relatedTarget?.closest(`[data-select-dropdown="${dropdownKeyId}"]`)) {
164
164
  refs.domReference.current?.querySelector("input")?.focus();
165
165
  return;
166
166
  }
167
- state.open && handleChange(state.query);
167
+ if (state.open) handleChange(state.query);
168
168
  handleQuery("");
169
169
  setOpen(false);
170
170
  onBlur?.(evt);
@@ -180,19 +180,17 @@ export const AutoComplete = ({
180
180
  handleChange("");
181
181
  return false;
182
182
  } else {
183
- onEnterPressed?.(evt);
184
- submitRef.current?.click();
183
+ onEnterPressed?.(evt as React.KeyboardEvent<HTMLInputElement>);
184
+ setOpen(false);
185
185
  }
186
186
  } else if (evt.key === "Backspace") {
187
- !state.query && multiple && handleRemove();
187
+ if (!state.query && multiple) handleRemove();
188
188
  } else if (["ArrowUp", "ArrowDown"].includes(evt.key)) {
189
- if (
190
- ["ArrowUp", "ArrowDown"].includes(evt.key) &&
191
- state.activeIndex === null
192
- ) {
189
+ if (["ArrowUp", "ArrowDown"].includes(evt.key) && state.activeIndex === null) {
193
190
  setActiveIndex(state.selectedIndex);
194
191
  }
195
192
  setTimeout(() => {
193
+ // @ts-expect-error ignore
196
194
  props.onKeyDown?.(evt);
197
195
  }, 50);
198
196
  }
@@ -200,33 +198,39 @@ export const AutoComplete = ({
200
198
  };
201
199
  }, [
202
200
  getReferenceProps,
203
- onEnterPressed,
204
- handleQuery,
205
201
  onFocus,
206
- onBlur,
207
- multiple,
208
- refs,
202
+ dropdownKeyId,
203
+ state.open,
209
204
  state.query,
210
205
  state.activeIndex,
206
+ state.selectedIndex,
207
+ handleChange,
208
+ handleQuery,
209
+ setOpen,
210
+ onBlur,
211
+ refs.domReference,
212
+ listContentRef,
213
+ onEnterPressed,
214
+ multiple,
215
+ handleRemove,
216
+ setActiveIndex,
211
217
  ]);
212
218
 
213
219
  const floatingProps = useMemo(() => {
214
220
  return getFloatingProps({
215
- "data-select-dropdown": dropdownKey,
216
- } as AnyObject);
217
- }, [getFloatingProps]);
221
+ "data-select-dropdown": dropdownKeyId,
222
+ } as KeyValue);
223
+ }, [dropdownKeyId, getFloatingProps]);
218
224
 
219
225
  const makeItemProps = useCallback(
220
226
  (item: AnyObject) => {
221
- const selected = isArray(state.value)
222
- ? state.value?.includes?.(item)
223
- : state.value === item;
227
+ const selected = isArray(state.value) ? state.value?.includes?.(item) : state.value === item;
224
228
  return getItemProps({
225
229
  "data-selected": selected ? true : undefined,
226
230
  onClick() {
227
231
  handleChange(item);
228
232
  },
229
- } as AnyObject);
233
+ } as KeyValue);
230
234
  },
231
235
  [getItemProps, handleChange, state.value],
232
236
  );
@@ -234,53 +238,53 @@ export const AutoComplete = ({
234
238
  const displayValue = useMemo(() => {
235
239
  if (isArray(state.value)) {
236
240
  return state.value.map((item: AnyObject, index) => (
241
+ // eslint-disable-next-line @eslint-react/no-array-index-key
237
242
  <Chip key={index} onRemove={() => handleRemove(index)}>
238
243
  {item}
239
244
  </Chip>
240
245
  ));
241
246
  }
242
- }, [state.value, state.query, placeholder]);
247
+ }, [state.value, handleRemove]);
243
248
 
244
249
  useLayoutEffect(() => {
245
- state.open &&
246
- setTimeout(() => {
247
- state.selectedIndex &&
250
+ if (state.open) {
251
+ const tmr = setTimeout(() => {
252
+ if (state.selectedIndex)
248
253
  listRef.current[state.selectedIndex]?.scrollIntoView({
249
254
  block: "center",
250
255
  });
251
256
  }, 100);
252
- }, [state.open]);
257
+
258
+ return () => {
259
+ clearTimeout(tmr);
260
+ };
261
+ }
262
+ }, [listRef, state.open, state.selectedIndex]);
253
263
 
254
264
  const inputValue = useMemo(() => {
255
265
  if (multiple) return state.query ?? "";
256
266
 
257
- return state.query ?? state.value ?? "";
267
+ return state.query ?? (state.value as string) ?? "";
258
268
  }, [multiple, state.query, state.value]);
259
269
 
260
270
  return (
261
271
  <InputWrapper
262
- showClear={!isEmpty(state.value)}
272
+ isOpen={state.open}
273
+ showClear={allowClear && !isEmpty(state.value)}
263
274
  onClear={handleChange}
264
- invalid={invalid}
265
- readOnly={readOnly}
266
- disabled={disabled}
267
- required={required}
268
- error={error}
269
- wrapperRef={refs.setReference}
270
- className={!multiple && expandOnEdit && state.open ? "!z-[99]" : ""}
275
+ ref={(el) => refs.setReference(el)}
276
+ className={!multiple && expandOnEdit && state.open ? "z-99!" : ""}
271
277
  floatingExpand={!multiple && expandOnEdit && state.open}
272
- {...rest}
278
+ {...getWrapperProps(props)}
273
279
  >
274
280
  <div
275
281
  role="none"
276
282
  data-select-display="true"
277
- className={classNames(
283
+ className={cn(
278
284
  "group flex-1 py-1 px-2 truncate text-start flex gap-1 relative min-h-5 justify-start",
279
285
  multiple ? "flex-wrap" : "flex-nowrap overflow-hidden",
280
286
  )}
281
- onMouseUp={(e) =>
282
- e.currentTarget.querySelector<HTMLElement>("input")?.focus()
283
- }
287
+ onMouseUp={(e) => e.currentTarget.querySelector<HTMLElement>("input")?.focus()}
284
288
  >
285
289
  {displayValue}
286
290
  <textarea
@@ -290,10 +294,12 @@ export const AutoComplete = ({
290
294
  aria-invalid={invalid}
291
295
  data-testid={name}
292
296
  name={name}
293
- size={1}
294
- onInput={onInput}
297
+ ref={ref}
298
+ autoComplete="off"
299
+ onInput={(e) => onInput?.(e.currentTarget.value)}
300
+ {...{ autoFocus }}
295
301
  rows={!multiple && expandOnEdit && state.open ? 5 : 1}
296
- className={classNames(
302
+ className={cn(
297
303
  "appearance-none bg-transparent outline-none border-none ring-0 flex-1 resize-none",
298
304
  disabled && "cursor-not-allowed pointer-events-none",
299
305
  multiple && "min-w-24 overflow-hidden",
@@ -303,32 +309,20 @@ export const AutoComplete = ({
303
309
  {...referenceProps}
304
310
  onChange={(evt) => handleQuery(evt.target.value)}
305
311
  />
306
- <button
307
- type="submit"
308
- ref={submitRef}
309
- tabIndex={-1}
310
- className="opacity-0 absolute"
311
- />
312
+ <button type="submit" ref={submitRef} tabIndex={-1} className="opacity-0 absolute" />
312
313
  </div>
313
314
  {state.loading && (
314
315
  <Icon
315
- animate="spin"
316
- className={classNames(
317
- "flex-content p-2 z-0 order-9 text-muted pointer-events-none",
318
- )}
319
- icon={CoreIcons.spinner}
316
+ className={cn("flex-content p-2 z-0 order-9 text-muted pointer-events-none")}
317
+ icon="icon-[svg-spinners--eclipse]"
320
318
  />
321
319
  )}
322
320
  {state.open && !state.loading && (
323
- <FloatingPortal>
324
- <FloatingFocusManager
325
- context={context}
326
- initialFocus={-1}
327
- visuallyHiddenDismiss
328
- >
321
+ <FloatingPortal root={refs.domReference.current?.closest<HTMLElement>(".theme-base") ?? undefined}>
322
+ <FloatingFocusManager context={context} initialFocus={-1} visuallyHiddenDismiss closeOnFocusOut>
329
323
  <Options
330
- ref={refs.setFloating}
331
- className="outline shadow-lg max-h-[40vh] z-[var(--z-popover)]"
324
+ ref={(el) => refs.setFloating(el)}
325
+ className="outline shadow-lg max-h-[40vh] z-(--z-popover)"
332
326
  style={{
333
327
  width: refs.reference.current?.getBoundingClientRect().width,
334
328
  ...floatingStyles,
@@ -338,17 +332,13 @@ export const AutoComplete = ({
338
332
  active={state.activeIndex}
339
333
  itemRef={setItemRef}
340
334
  itemProps={makeItemProps}
341
- empty={
342
- <div className="text-muted text-sm px-2 py-1">
343
- No history available
344
- </div>
345
- }
335
+ empty={<div className="text-muted text-sm px-2 py-1">No history available</div>}
346
336
  >
347
- {(item) => item}
337
+ {(item) => item as undefined}
348
338
  </Options>
349
339
  </FloatingFocusManager>
350
340
  </FloatingPortal>
351
341
  )}
352
342
  </InputWrapper>
353
343
  );
354
- };
344
+ }