@react-fabric/form 1.0.0-beta.9 → 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.
- package/{src/input/ArrayInput.module.css → css/_arrayInput.css} +8 -8
- package/css/_colorPicker.css +95 -0
- package/{src/internal/Field.module.css → css/_field.css} +94 -33
- package/{src/input/File.module.css → css/_file.css} +21 -6
- package/css/styles.css +27 -0
- package/dist/cjs/builder/FileField.js +107 -78
- package/dist/cjs/builder/FormField.js +60 -39
- package/dist/cjs/builder/SchemaEditor.js +72 -0
- package/dist/cjs/builder/components/AddSchemaFields.js +64 -0
- package/dist/cjs/builder/components/SchemaArrayForm.js +146 -0
- package/dist/cjs/builder/components/SchemaField.js +423 -0
- package/dist/cjs/form/Controller.js +66 -19
- package/dist/cjs/form/Form.js +97 -39
- package/dist/cjs/form/useForm.js +32 -0
- package/dist/cjs/hooks/useFileUploader.js +74 -45
- package/dist/cjs/hooks/useFormBuilder.js +85 -31
- package/dist/cjs/i18n/{ar.json.js → ar/form.json.js} +5 -4
- package/dist/cjs/i18n/{en.json.js → en/form.json.js} +5 -5
- package/dist/cjs/i18n/index.js +4 -4
- package/dist/cjs/index.js +41 -2
- package/dist/cjs/input/ArrayInput.js +259 -135
- package/dist/cjs/input/AvatarInput.js +99 -63
- package/dist/cjs/input/Checkbox.js +24 -25
- package/dist/cjs/input/ColorInput.js +138 -81
- package/dist/cjs/input/ColorPicker.js +78 -95
- package/dist/cjs/input/DateInput.js +192 -0
- package/dist/cjs/input/Field.js +21 -20
- package/dist/cjs/input/File.js +85 -80
- package/dist/cjs/input/Hidden.js +27 -13
- package/dist/cjs/input/Input.js +49 -48
- package/dist/cjs/input/Number.js +46 -44
- package/dist/cjs/input/Password.js +51 -49
- package/dist/cjs/input/Radio.js +26 -16
- package/dist/cjs/input/RadioGroup.js +26 -11
- package/dist/cjs/input/{Range.js → RangeSlider.js} +61 -66
- package/dist/cjs/input/Search.js +58 -64
- package/dist/cjs/input/Slider.js +57 -66
- package/dist/cjs/input/Switch.js +29 -27
- package/dist/cjs/input/Textarea.js +65 -53
- package/dist/cjs/internal/ErrorIcon.js +9 -9
- package/dist/cjs/internal/FieldWrapper.js +23 -13
- package/dist/cjs/internal/InputWrapper.js +85 -87
- package/dist/cjs/ranger/index.js +7 -7
- package/dist/cjs/ranger/utils.js +9 -4
- package/dist/cjs/select/AutoComplete.js +93 -76
- package/dist/cjs/select/DualList.js +235 -154
- package/dist/cjs/select/List.js +122 -89
- package/dist/cjs/select/Options.js +58 -54
- package/dist/cjs/select/Select.js +119 -89
- package/dist/cjs/select/helpers.js +5 -5
- package/dist/cjs/select/useSelect.js +83 -58
- package/dist/cjs/types/schema.js +43 -0
- package/dist/cjs/utils/eventHandlers.js +16 -6
- package/dist/cjs/utils/getColor.js +6 -6
- package/dist/cjs/utils/getProps.js +49 -0
- package/dist/esm/builder/FileField.js +109 -80
- package/dist/esm/builder/FormField.js +60 -39
- package/dist/esm/builder/SchemaEditor.js +72 -0
- package/dist/esm/builder/components/AddSchemaFields.js +64 -0
- package/dist/esm/builder/components/SchemaArrayForm.js +146 -0
- package/dist/esm/builder/components/SchemaField.js +423 -0
- package/dist/esm/form/Controller.js +66 -19
- package/dist/esm/form/Form.js +97 -39
- package/dist/esm/form/useForm.js +32 -0
- package/dist/esm/hooks/useFileUploader.js +75 -46
- package/dist/esm/hooks/useFormBuilder.js +84 -30
- package/dist/esm/i18n/{ar.json.js → ar/form.json.js} +5 -4
- package/dist/esm/i18n/{en.json.js → en/form.json.js} +5 -5
- package/dist/esm/i18n/index.js +2 -2
- package/dist/esm/index.js +36 -1
- package/dist/esm/input/ArrayInput.js +260 -136
- package/dist/esm/input/AvatarInput.js +99 -63
- package/dist/esm/input/Checkbox.js +26 -27
- package/dist/esm/input/ColorInput.js +141 -84
- package/dist/esm/input/ColorPicker.js +80 -97
- package/dist/esm/input/DateInput.js +192 -0
- package/dist/esm/input/Field.js +21 -20
- package/dist/esm/input/File.js +89 -84
- package/dist/esm/input/Hidden.js +28 -14
- package/dist/esm/input/Input.js +51 -50
- package/dist/esm/input/Number.js +48 -46
- package/dist/esm/input/Password.js +54 -52
- package/dist/esm/input/Radio.js +27 -17
- package/dist/esm/input/RadioGroup.js +27 -12
- package/dist/esm/input/{Range.js → RangeSlider.js} +62 -67
- package/dist/esm/input/Search.js +61 -67
- package/dist/esm/input/Slider.js +58 -67
- package/dist/esm/input/Switch.js +31 -29
- package/dist/esm/input/Textarea.js +67 -55
- package/dist/esm/internal/ErrorIcon.js +11 -11
- package/dist/esm/internal/FieldWrapper.js +23 -13
- package/dist/esm/internal/InputWrapper.js +88 -90
- package/dist/esm/ranger/index.js +7 -7
- package/dist/esm/ranger/utils.js +9 -4
- package/dist/esm/select/AutoComplete.js +95 -78
- package/dist/esm/select/DualList.js +233 -152
- package/dist/esm/select/List.js +125 -92
- package/dist/esm/select/Options.js +58 -54
- package/dist/esm/select/Select.js +122 -92
- package/dist/esm/select/helpers.js +5 -5
- package/dist/esm/select/useSelect.js +84 -59
- package/{src/input/ColorPicker.module.css → dist/esm/types/schema.js} +18 -27
- package/dist/esm/utils/eventHandlers.js +16 -6
- package/dist/esm/utils/getColor.js +6 -6
- package/dist/esm/utils/getProps.js +49 -0
- package/dist/types/builder/FileField.d.ts +7 -4
- package/dist/types/builder/FormField.d.ts +4 -2
- package/dist/types/builder/SchemaEditor.d.ts +6 -0
- package/dist/types/builder/components/AddSchemaFields.d.ts +2 -0
- package/dist/types/builder/components/SchemaArrayForm.d.ts +2 -0
- package/dist/types/builder/components/SchemaField.d.ts +12 -0
- package/dist/types/form/Controller.d.ts +45 -3
- package/dist/types/form/Form.d.ts +38 -7
- package/dist/types/form/useForm.d.ts +6 -0
- package/dist/types/hooks/useFileUploader.d.ts +24 -3
- package/dist/types/hooks/useFormBuilder.d.ts +41 -3
- package/dist/types/index.d.ts +32 -2
- package/dist/types/input/ArrayInput.d.ts +68 -13
- package/dist/types/input/AvatarInput.d.ts +23 -6
- package/dist/types/input/Checkbox.d.ts +12 -10
- package/dist/types/input/ColorInput.d.ts +15 -5
- package/dist/types/input/ColorPicker.d.ts +10 -2
- package/dist/types/input/DateInput.d.ts +21 -0
- package/dist/types/input/Field.d.ts +9 -36
- package/dist/types/input/File.d.ts +16 -4
- package/dist/types/input/Hidden.d.ts +7 -6
- package/dist/types/input/Input.d.ts +11 -4
- package/dist/types/input/Number.d.ts +9 -4
- package/dist/types/input/Password.d.ts +9 -4
- package/dist/types/input/Radio.d.ts +9 -4
- package/dist/types/input/RadioGroup.d.ts +14 -6
- package/dist/types/input/{Range.d.ts → RangeSlider.d.ts} +11 -6
- package/dist/types/input/Search.d.ts +14 -4
- package/dist/types/input/Slider.d.ts +9 -6
- package/dist/types/input/Switch.d.ts +13 -8
- package/dist/types/input/Textarea.d.ts +15 -4
- package/dist/types/internal/ErrorIcon.d.ts +4 -1
- package/dist/types/internal/FieldWrapper.d.ts +10 -1
- package/dist/types/internal/InputWrapper.d.ts +19 -1
- package/dist/types/ranger/index.d.ts +7 -3
- package/dist/types/ranger/utils.d.ts +2 -2
- package/dist/types/select/AutoComplete.d.ts +7 -2
- package/dist/types/select/DualList.d.ts +11 -37
- package/dist/types/select/List.d.ts +7 -2
- package/dist/types/select/Options.d.ts +8 -7
- package/dist/types/select/Select.d.ts +7 -2
- package/dist/types/select/helpers.d.ts +2 -2
- package/dist/types/select/useSelect.d.ts +10 -28
- package/dist/types/types/index.d.ts +73 -39
- package/dist/types/types/schema.d.ts +78 -32
- package/dist/types/utils/eventHandlers.d.ts +4 -4
- package/dist/types/utils/getColor.d.ts +4 -4
- package/dist/types/utils/getProps.d.ts +26 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/package.json +25 -25
- package/src/builder/FileField.tsx +73 -56
- package/src/builder/FormField.tsx +66 -58
- package/src/builder/SchemaEditor.tsx +78 -0
- package/src/builder/components/AddSchemaFields.tsx +64 -0
- package/src/builder/components/SchemaArrayForm.tsx +146 -0
- package/src/builder/components/SchemaField.tsx +405 -0
- package/src/form/Controller.tsx +61 -24
- package/src/form/Form.tsx +74 -50
- package/src/form/useForm.ts +53 -0
- package/src/hooks/useFileUploader.ts +115 -84
- package/src/hooks/useFormBuilder.tsx +80 -41
- package/src/i18n/{ar.json → ar/form.json} +5 -4
- package/src/i18n/{en.json → en/form.json} +5 -5
- package/src/i18n/index.ts +2 -2
- package/src/index.ts +34 -20
- package/src/input/ArrayInput.tsx +255 -173
- package/src/input/AvatarInput.tsx +82 -39
- package/src/input/Checkbox.tsx +30 -54
- package/src/input/ColorInput.tsx +146 -105
- package/src/input/ColorPicker.tsx +76 -102
- package/src/input/DateInput.tsx +225 -0
- package/src/input/Field.tsx +23 -65
- package/src/input/File.tsx +76 -98
- package/src/input/Hidden.tsx +36 -24
- package/src/input/Input.tsx +55 -53
- package/src/input/Number.tsx +49 -54
- package/src/input/Password.tsx +61 -66
- package/src/input/Radio.tsx +28 -37
- package/src/input/RadioGroup.tsx +30 -25
- package/src/input/{Range.tsx → RangeSlider.tsx} +81 -109
- package/src/input/Search.tsx +64 -77
- package/src/input/Slider.tsx +80 -109
- package/src/input/Switch.tsx +39 -53
- package/src/input/Textarea.tsx +72 -59
- package/src/internal/ErrorIcon.tsx +22 -21
- package/src/internal/FieldWrapper.tsx +33 -23
- package/src/internal/InputWrapper.tsx +132 -143
- package/src/ranger/index.tsx +37 -117
- package/src/ranger/utils.ts +12 -11
- package/src/select/AutoComplete.tsx +113 -123
- package/src/select/DualList.tsx +218 -204
- package/src/select/List.tsx +130 -97
- package/src/select/Options.tsx +59 -57
- package/src/select/Select.tsx +148 -122
- package/src/select/helpers.ts +13 -8
- package/src/select/useSelect.tsx +110 -127
- package/src/types/index.ts +76 -45
- package/src/types/schema.ts +97 -40
- package/src/utils/eventHandlers.ts +24 -26
- package/src/utils/getColor.ts +9 -8
- package/src/utils/getProps.ts +47 -0
- package/src/utils/index.ts +1 -0
- package/dist/cjs/input/ArrayInput.module.css +0 -1
- package/dist/cjs/input/ColorPicker.module.css +0 -1
- package/dist/cjs/input/File.module.css +0 -1
- package/dist/cjs/internal/Field.module.css +0 -1
- package/dist/esm/input/ArrayInput.module.css +0 -1
- package/dist/esm/input/ColorPicker.module.css +0 -1
- package/dist/esm/input/File.module.css +0 -1
- 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,
|
|
38
|
-
import {
|
|
39
|
-
import
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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:
|
|
106
|
+
options: optionsRef.current,
|
|
104
107
|
multiple,
|
|
105
108
|
onChange,
|
|
106
109
|
onSelect,
|
|
110
|
+
onQuery,
|
|
107
111
|
});
|
|
108
112
|
|
|
109
|
-
const
|
|
113
|
+
const dropdownKeyId = useId();
|
|
110
114
|
|
|
111
115
|
const { context, floatingStyles, refs } = useFloating({
|
|
112
116
|
open: state.open,
|
|
113
|
-
onOpenChange: (open
|
|
114
|
-
!open
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
183
|
+
onEnterPressed?.(evt as React.KeyboardEvent<HTMLInputElement>);
|
|
184
|
+
setOpen(false);
|
|
185
185
|
}
|
|
186
186
|
} else if (evt.key === "Backspace") {
|
|
187
|
-
!state.query && multiple
|
|
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
|
-
|
|
207
|
-
|
|
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":
|
|
216
|
-
} as
|
|
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
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
272
|
+
isOpen={state.open}
|
|
273
|
+
showClear={allowClear && !isEmpty(state.value)}
|
|
263
274
|
onClear={handleChange}
|
|
264
|
-
|
|
265
|
-
|
|
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
|
-
{...
|
|
278
|
+
{...getWrapperProps(props)}
|
|
273
279
|
>
|
|
274
280
|
<div
|
|
275
281
|
role="none"
|
|
276
282
|
data-select-display="true"
|
|
277
|
-
className={
|
|
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
|
-
|
|
294
|
-
|
|
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={
|
|
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
|
-
|
|
316
|
-
|
|
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-
|
|
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
|
+
}
|