@povio/ui 2.2.9-rc.32 → 2.2.9-rc.34
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/dist/components/inputs/DateTime/DatePicker/DatePicker.js +11 -13
- package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +11 -13
- package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +10 -12
- package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +8 -12
- package/dist/components/inputs/Input/NumberInput/NumberInput.js +8 -11
- package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +8 -10
- package/dist/components/inputs/Input/TextInput/TextInput.js +8 -11
- package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +10 -14
- package/dist/components/inputs/Selection/Select/Select.js +10 -14
- package/dist/components/inputs/shared/useStaticInputHandoff.d.ts +13 -0
- package/dist/components/inputs/shared/useStaticInputHandoff.js +47 -0
- package/package.json +1 -1
|
@@ -11,10 +11,11 @@ import { getStaticCalendarDateSegments } from "../shared/staticDateTimeSegments.
|
|
|
11
11
|
import { FormField } from "../../FormField/FormField.js";
|
|
12
12
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
13
13
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
14
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
14
15
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
15
16
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
17
|
import { clsx } from "clsx";
|
|
17
|
-
import {
|
|
18
|
+
import { useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
18
19
|
import { useDatePicker, useLocale } from "react-aria";
|
|
19
20
|
import { mergeRefs } from "@react-aria/utils";
|
|
20
21
|
import { Controller, useWatch } from "react-hook-form";
|
|
@@ -176,8 +177,15 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput, ...pr
|
|
|
176
177
|
const { locale } = useLocale();
|
|
177
178
|
const shouldForceLeadingZeros = props.shouldForceLeadingZeros ?? ui.dateInput.shouldForceLeadingZeros;
|
|
178
179
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
179
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
180
180
|
const inputRef = useRef(null);
|
|
181
|
+
const { renderRealInput } = useStaticInputHandoff({
|
|
182
|
+
inputRef,
|
|
183
|
+
renderInput,
|
|
184
|
+
setRenderInput,
|
|
185
|
+
getFocusTarget: (input) => {
|
|
186
|
+
return (input.getContainer?.() ?? input).querySelector("input, button, [tabindex]:not([tabindex='-1'])");
|
|
187
|
+
}
|
|
188
|
+
});
|
|
181
189
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
182
190
|
control: props.formControl.control,
|
|
183
191
|
name: props.formControl.name
|
|
@@ -201,13 +209,6 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput, ...pr
|
|
|
201
209
|
minValue: typeof minValue === "string" ? parseCalendarDate(minValue) : minValue,
|
|
202
210
|
maxValue: typeof maxValue === "string" ? parseCalendarDate(maxValue) : maxValue
|
|
203
211
|
};
|
|
204
|
-
useEffect(() => {
|
|
205
|
-
if (!renderInput || !shouldFocus) return;
|
|
206
|
-
requestAnimationFrame(() => {
|
|
207
|
-
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
208
|
-
});
|
|
209
|
-
setShouldFocus(false);
|
|
210
|
-
}, [renderInput, shouldFocus]);
|
|
211
212
|
if (!renderInput) {
|
|
212
213
|
const dateValue = rawValue ? parseCalendarDate(rawValue) : null;
|
|
213
214
|
const as = props.as ?? ui.input.as;
|
|
@@ -245,10 +246,7 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput, ...pr
|
|
|
245
246
|
dataHasSelection: dateValue !== null
|
|
246
247
|
},
|
|
247
248
|
renderStatic: true,
|
|
248
|
-
onStaticInteract:
|
|
249
|
-
setShouldFocus(focus);
|
|
250
|
-
setRenderInput(true);
|
|
251
|
-
},
|
|
249
|
+
onStaticInteract: renderRealInput,
|
|
252
250
|
actionContent: staticTodayIcon,
|
|
253
251
|
actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
|
|
254
252
|
trailingContent: showDropdown ? ui.dateInput.calendarIcon : void 0,
|
|
@@ -12,11 +12,12 @@ import { getStaticDateRangeSegments } from "../shared/staticDateTimeSegments.js"
|
|
|
12
12
|
import { FormField } from "../../FormField/FormField.js";
|
|
13
13
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
14
14
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
15
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
15
16
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
16
17
|
import { RangeCalendar } from "../shared/RangeCalendar.js";
|
|
17
18
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
19
|
import { clsx } from "clsx";
|
|
19
|
-
import { useCallback,
|
|
20
|
+
import { useCallback, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
20
21
|
import { Button } from "react-aria-components";
|
|
21
22
|
import { useDateRangePicker, useLocale as useLocale$1 } from "react-aria";
|
|
22
23
|
import { mergeRefs } from "@react-aria/utils";
|
|
@@ -552,8 +553,15 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput,
|
|
|
552
553
|
const { locale } = useLocale$1();
|
|
553
554
|
const shouldForceLeadingZeros = props.shouldForceLeadingZeros ?? ui.dateInput.shouldForceLeadingZeros;
|
|
554
555
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
555
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
556
556
|
const inputRef = useRef(null);
|
|
557
|
+
const { renderRealInput } = useStaticInputHandoff({
|
|
558
|
+
inputRef,
|
|
559
|
+
renderInput,
|
|
560
|
+
setRenderInput,
|
|
561
|
+
getFocusTarget: (input) => {
|
|
562
|
+
return (input.getContainer?.() ?? input).querySelector("input, button, [tabindex]:not([tabindex='-1'])");
|
|
563
|
+
}
|
|
564
|
+
});
|
|
557
565
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
558
566
|
control: props.formControl.control,
|
|
559
567
|
name: props.formControl.name
|
|
@@ -599,13 +607,6 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput,
|
|
|
599
607
|
minValue: typeof minValue === "string" ? parseCalendarDate(minValue) : minValue,
|
|
600
608
|
maxValue: typeof maxValue === "string" ? parseCalendarDate(maxValue) : maxValue
|
|
601
609
|
};
|
|
602
|
-
useEffect(() => {
|
|
603
|
-
if (!renderInput || !shouldFocus) return;
|
|
604
|
-
requestAnimationFrame(() => {
|
|
605
|
-
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
606
|
-
});
|
|
607
|
-
setShouldFocus(false);
|
|
608
|
-
}, [renderInput, shouldFocus]);
|
|
609
610
|
if (!renderInput) {
|
|
610
611
|
const startDateValue = parseCalendarDate(rawValue?.start ?? null);
|
|
611
612
|
const endDateValue = parseCalendarDate(rawValue?.end ?? null);
|
|
@@ -646,10 +647,7 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput,
|
|
|
646
647
|
dataHasSelection: hasProvidedRangeValue
|
|
647
648
|
},
|
|
648
649
|
renderStatic: true,
|
|
649
|
-
onStaticInteract:
|
|
650
|
-
setShouldFocus(focus);
|
|
651
|
-
setRenderInput(true);
|
|
652
|
-
},
|
|
650
|
+
onStaticInteract: renderRealInput,
|
|
653
651
|
actionContent: staticTodayIcon,
|
|
654
652
|
actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
|
|
655
653
|
trailingContent: showDropdown ? ui.dateInput.calendarIcon : void 0,
|
|
@@ -11,6 +11,7 @@ import { getStaticCalendarDateTimeSegments } from "../shared/staticDateTimeSegme
|
|
|
11
11
|
import { FormField } from "../../FormField/FormField.js";
|
|
12
12
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
13
13
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
14
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
14
15
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
15
16
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
17
|
import { clsx } from "clsx";
|
|
@@ -197,8 +198,15 @@ var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
|
|
|
197
198
|
const { locale } = useLocale();
|
|
198
199
|
const shouldForceLeadingZeros = props.shouldForceLeadingZeros ?? ui.dateInput.shouldForceLeadingZeros;
|
|
199
200
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
200
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
201
201
|
const inputRef = useRef(null);
|
|
202
|
+
const { renderRealInput } = useStaticInputHandoff({
|
|
203
|
+
inputRef,
|
|
204
|
+
renderInput,
|
|
205
|
+
setRenderInput,
|
|
206
|
+
getFocusTarget: (input) => {
|
|
207
|
+
return (input.getContainer?.() ?? input).querySelector("input, button, [tabindex]:not([tabindex='-1'])");
|
|
208
|
+
}
|
|
209
|
+
});
|
|
202
210
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
203
211
|
control: props.formControl.control,
|
|
204
212
|
name: props.formControl.name
|
|
@@ -215,13 +223,6 @@ var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
|
|
|
215
223
|
if (isoString == null) return isoString;
|
|
216
224
|
return DateTimeUtils.fromUTCISOToCalendarDateTime(isoString);
|
|
217
225
|
};
|
|
218
|
-
useEffect(() => {
|
|
219
|
-
if (!renderInput || !shouldFocus) return;
|
|
220
|
-
requestAnimationFrame(() => {
|
|
221
|
-
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
222
|
-
});
|
|
223
|
-
setShouldFocus(false);
|
|
224
|
-
}, [renderInput, shouldFocus]);
|
|
225
226
|
if (!renderInput) {
|
|
226
227
|
const dateTimeValue = rawValue ? parseDateValue(rawValue) : null;
|
|
227
228
|
const as = props.as ?? ui.input.as;
|
|
@@ -259,10 +260,7 @@ var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
|
|
|
259
260
|
dataHasSelection: dateTimeValue !== null
|
|
260
261
|
},
|
|
261
262
|
renderStatic: true,
|
|
262
|
-
onStaticInteract:
|
|
263
|
-
setShouldFocus(focus);
|
|
264
|
-
setRenderInput(true);
|
|
265
|
-
},
|
|
263
|
+
onStaticInteract: renderRealInput,
|
|
266
264
|
actionContent: staticTodayIcon,
|
|
267
265
|
actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
|
|
268
266
|
trailingContent: showDropdown ? ui.dateInput.dateTimeIcon : void 0,
|
|
@@ -7,6 +7,7 @@ import { getStaticTimeSegments } from "../shared/staticDateTimeSegments.js";
|
|
|
7
7
|
import { FormField } from "../../FormField/FormField.js";
|
|
8
8
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
9
9
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
10
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
10
11
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
11
12
|
import { TimePickerInput } from "../shared/TimePickerInput.js";
|
|
12
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -142,8 +143,13 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
142
143
|
const ui = UIConfig.useConfig();
|
|
143
144
|
const { locale } = useLocale();
|
|
144
145
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
145
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
146
146
|
const inputRef = useRef(null);
|
|
147
|
+
const { renderRealInput } = useStaticInputHandoff({
|
|
148
|
+
inputRef,
|
|
149
|
+
renderInput,
|
|
150
|
+
setRenderInput,
|
|
151
|
+
getFocusTarget: (input) => input.querySelector("input, button, [tabindex]:not([tabindex='-1'])")
|
|
152
|
+
});
|
|
147
153
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
148
154
|
control: props.formControl.control,
|
|
149
155
|
name: props.formControl.name
|
|
@@ -161,13 +167,6 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
161
167
|
if (isoString == null) return isoString;
|
|
162
168
|
return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString));
|
|
163
169
|
};
|
|
164
|
-
useEffect(() => {
|
|
165
|
-
if (!renderInput || !shouldFocus) return;
|
|
166
|
-
requestAnimationFrame(() => {
|
|
167
|
-
(inputRef.current?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
168
|
-
});
|
|
169
|
-
setShouldFocus(false);
|
|
170
|
-
}, [renderInput, shouldFocus]);
|
|
171
170
|
if (!renderInput) {
|
|
172
171
|
const timeValue = rawValue ? parseTimeValue(rawValue) : null;
|
|
173
172
|
const as = props.as ?? ui.input.as;
|
|
@@ -198,10 +197,7 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
198
197
|
dataHasSelection: timeValue !== null
|
|
199
198
|
},
|
|
200
199
|
renderStatic: true,
|
|
201
|
-
onStaticInteract:
|
|
202
|
-
setShouldFocus(focus);
|
|
203
|
-
setRenderInput(true);
|
|
204
|
-
},
|
|
200
|
+
onStaticInteract: renderRealInput,
|
|
205
201
|
trailingContent: showDropdown ? ui.dateInput.timeIcon : void 0,
|
|
206
202
|
children: staticSegments
|
|
207
203
|
});
|
|
@@ -4,6 +4,7 @@ import { inputBase } from "../../shared/input.cva.js";
|
|
|
4
4
|
import { FormField } from "../../FormField/FormField.js";
|
|
5
5
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
6
6
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
7
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
7
8
|
import { InputContent } from "../shared/InputContent.js";
|
|
8
9
|
import { getStaticNumberDisplayValue } from "../shared/numberStatic.utils.js";
|
|
9
10
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -124,19 +125,18 @@ var NumberInput = ({ renderStaticInput, ...props }) => {
|
|
|
124
125
|
const ui = UIConfig.useConfig();
|
|
125
126
|
const { locale } = useLocale();
|
|
126
127
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
127
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
128
128
|
const inputRef = useRef(null);
|
|
129
|
+
const { shouldFocus, renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
|
|
130
|
+
inputRef,
|
|
131
|
+
renderInput,
|
|
132
|
+
setRenderInput
|
|
133
|
+
});
|
|
129
134
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
130
135
|
control: props.formControl.control,
|
|
131
136
|
name: props.formControl.name
|
|
132
137
|
}) : props.value;
|
|
133
138
|
let isFormControlDisabled = false;
|
|
134
139
|
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
135
|
-
useEffect(() => {
|
|
136
|
-
if (!renderInput || !shouldFocus) return;
|
|
137
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
138
|
-
setShouldFocus(false);
|
|
139
|
-
}, [renderInput, shouldFocus]);
|
|
140
140
|
if (!renderInput) {
|
|
141
141
|
const staticValue = watchedValue ?? props.value ?? props.defaultValue;
|
|
142
142
|
const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
|
|
@@ -161,19 +161,16 @@ var NumberInput = ({ renderStaticInput, ...props }) => {
|
|
|
161
161
|
className: clsx("group w-full", as === "inline" && "h-full", props.className),
|
|
162
162
|
dataAttributes,
|
|
163
163
|
renderStatic: true,
|
|
164
|
-
onStaticInteract:
|
|
165
|
-
setShouldFocus(focus);
|
|
166
|
-
setRenderInput(true);
|
|
167
|
-
},
|
|
164
|
+
onStaticInteract: renderRealInput,
|
|
168
165
|
inputClassName: props.inputClassName,
|
|
169
166
|
children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
|
|
170
167
|
ref: inputRef,
|
|
171
|
-
readOnly: true,
|
|
172
168
|
disabled: isDisabled,
|
|
173
169
|
tabIndex: -1,
|
|
174
170
|
value: displayValue,
|
|
175
171
|
placeholder: as === "floating" ? "" : props.placeholder,
|
|
176
172
|
className: "w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled",
|
|
173
|
+
onChange: (event) => replayStaticInputChange(event.target.value),
|
|
177
174
|
...dataAttributeProps,
|
|
178
175
|
"data-rac": true
|
|
179
176
|
})
|
|
@@ -3,11 +3,12 @@ import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
|
3
3
|
import { InputClear } from "../../shared/InputClear.js";
|
|
4
4
|
import { inputBase, inputSize } from "../../shared/input.cva.js";
|
|
5
5
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
6
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
6
7
|
import { getStaticNumberDisplayValue } from "../shared/numberStatic.utils.js";
|
|
7
8
|
import { NumberRangeField } from "./NumberRangeField.js";
|
|
8
9
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
10
|
import { clsx } from "clsx";
|
|
10
|
-
import {
|
|
11
|
+
import { useRef, useState } from "react";
|
|
11
12
|
import { useLocale } from "react-aria-components";
|
|
12
13
|
import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
|
|
13
14
|
import { Controller, useWatch } from "react-hook-form";
|
|
@@ -122,17 +123,17 @@ var NumberRangeInput = ({ renderStaticInput, ...props }) => {
|
|
|
122
123
|
const ui = UIConfig.useConfig();
|
|
123
124
|
const { locale } = useLocale();
|
|
124
125
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
125
|
-
const
|
|
126
|
+
const { shouldFocus, renderRealInput } = useStaticInputHandoff({
|
|
127
|
+
inputRef: useRef(null),
|
|
128
|
+
renderInput,
|
|
129
|
+
setRenderInput
|
|
130
|
+
});
|
|
126
131
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
127
132
|
control: props.formControl.control,
|
|
128
133
|
name: props.formControl.name
|
|
129
134
|
}) : props.value;
|
|
130
135
|
let isFormControlDisabled = false;
|
|
131
136
|
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
132
|
-
useEffect(() => {
|
|
133
|
-
if (!renderInput || !shouldFocus) return;
|
|
134
|
-
setShouldFocus(false);
|
|
135
|
-
}, [renderInput, shouldFocus]);
|
|
136
137
|
if (!renderInput) {
|
|
137
138
|
const staticValue = normalizeRangeValue(watchedValue, props.minValue, props.maxValue);
|
|
138
139
|
const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
|
|
@@ -165,10 +166,7 @@ var NumberRangeInput = ({ renderStaticInput, ...props }) => {
|
|
|
165
166
|
contentWrapperClassName: "flex w-full items-center gap-input-gap-input-text-to-elements",
|
|
166
167
|
dataAttributes,
|
|
167
168
|
renderStatic: true,
|
|
168
|
-
onStaticInteract:
|
|
169
|
-
setShouldFocus(focus);
|
|
170
|
-
setRenderInput(true);
|
|
171
|
-
},
|
|
169
|
+
onStaticInteract: renderRealInput,
|
|
172
170
|
isClearable: false,
|
|
173
171
|
labelPlacement: "content-row",
|
|
174
172
|
children: ({ id, ...dataAttributeProps }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -4,6 +4,7 @@ import { inputBase } from "../../shared/input.cva.js";
|
|
|
4
4
|
import { FormField } from "../../FormField/FormField.js";
|
|
5
5
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
6
6
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
7
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
7
8
|
import { InputContent } from "../shared/InputContent.js";
|
|
8
9
|
import { jsx } from "react/jsx-runtime";
|
|
9
10
|
import { clsx } from "clsx";
|
|
@@ -119,8 +120,12 @@ var TextInputBase = (props) => {
|
|
|
119
120
|
var TextInput = ({ renderStaticInput, ...props }) => {
|
|
120
121
|
const ui = UIConfig.useConfig();
|
|
121
122
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
122
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
123
123
|
const inputRef = useRef(null);
|
|
124
|
+
const { shouldFocus, renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
|
|
125
|
+
inputRef,
|
|
126
|
+
renderInput,
|
|
127
|
+
setRenderInput
|
|
128
|
+
});
|
|
124
129
|
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
125
130
|
control: props.formControl.control,
|
|
126
131
|
name: props.formControl.name
|
|
@@ -130,11 +135,6 @@ var TextInput = ({ renderStaticInput, ...props }) => {
|
|
|
130
135
|
const staticValue = watchedValue ?? props.value ?? props.defaultValue ?? "";
|
|
131
136
|
const inputType = props.type;
|
|
132
137
|
if (!renderInput && inputType === "password" && `${staticValue}`.length > 0) setRenderInput(true);
|
|
133
|
-
useEffect(() => {
|
|
134
|
-
if (!renderInput || !shouldFocus) return;
|
|
135
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
136
|
-
setShouldFocus(false);
|
|
137
|
-
}, [renderInput, shouldFocus]);
|
|
138
138
|
if (!renderInput) {
|
|
139
139
|
const as = props.as ?? ui.input.as;
|
|
140
140
|
let isDisabled = !!props.isDisabled;
|
|
@@ -158,20 +158,17 @@ var TextInput = ({ renderStaticInput, ...props }) => {
|
|
|
158
158
|
className: clsx("group w-full", as === "inline" && "h-full", props.className),
|
|
159
159
|
dataAttributes,
|
|
160
160
|
renderStatic: true,
|
|
161
|
-
onStaticInteract:
|
|
162
|
-
setShouldFocus(focus);
|
|
163
|
-
setRenderInput(true);
|
|
164
|
-
},
|
|
161
|
+
onStaticInteract: renderRealInput,
|
|
165
162
|
inputClassName: props.inputClassName,
|
|
166
163
|
children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
|
|
167
164
|
ref: inputRef,
|
|
168
165
|
type: inputType === "hidden" ? "password" : inputType,
|
|
169
|
-
readOnly: true,
|
|
170
166
|
disabled: isDisabled,
|
|
171
167
|
tabIndex: -1,
|
|
172
168
|
value: displayValue,
|
|
173
169
|
placeholder: as === "floating" ? "" : props.placeholder,
|
|
174
170
|
className: "w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled",
|
|
171
|
+
onChange: (event) => replayStaticInputChange(event.target.value),
|
|
175
172
|
...dataAttributeProps,
|
|
176
173
|
"data-rac": true
|
|
177
174
|
})
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ArrowDropDownIcon } from "../../../../assets/icons/ArrowDropDown.js";
|
|
2
2
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
3
3
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
4
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
4
5
|
import { SelectBase } from "../shared/SelectBase.js";
|
|
5
6
|
import { getStaticSelectValue } from "../shared/staticSelect.utils.js";
|
|
6
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { clsx } from "clsx";
|
|
8
|
-
import {
|
|
9
|
+
import { useRef, useState } from "react";
|
|
9
10
|
import { mergeRefs } from "@react-aria/utils";
|
|
10
11
|
import { Controller, useWatch } from "react-hook-form";
|
|
11
12
|
//#region src/components/inputs/Selection/Autocomplete/Autocomplete.tsx
|
|
@@ -37,8 +38,13 @@ function _Autocomplete(props) {
|
|
|
37
38
|
function Autocomplete({ renderStaticInput, ...props }) {
|
|
38
39
|
const ui = UIConfig.useConfig();
|
|
39
40
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
40
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
41
41
|
const rootRef = useRef(null);
|
|
42
|
+
const { renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
|
|
43
|
+
inputRef: rootRef,
|
|
44
|
+
renderInput,
|
|
45
|
+
setRenderInput,
|
|
46
|
+
getFocusTarget: (root) => root.querySelector("input, [data-type='select-trigger'], button, [tabindex]")
|
|
47
|
+
});
|
|
42
48
|
const currentValue = ("formControl" in props && props.formControl ? useWatch({
|
|
43
49
|
control: props.formControl.control,
|
|
44
50
|
name: props.formControl.name
|
|
@@ -46,13 +52,6 @@ function Autocomplete({ renderStaticInput, ...props }) {
|
|
|
46
52
|
let isFormControlDisabled = false;
|
|
47
53
|
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
48
54
|
if (!renderInput && !!props.customTrigger) setRenderInput(true);
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
if (!renderInput || !shouldFocus) return;
|
|
51
|
-
requestAnimationFrame(() => {
|
|
52
|
-
(rootRef.current?.querySelector("input, [data-type='select-trigger'], button, [tabindex]"))?.focus();
|
|
53
|
-
});
|
|
54
|
-
setShouldFocus(false);
|
|
55
|
-
}, [renderInput, shouldFocus]);
|
|
56
55
|
if (!renderInput) {
|
|
57
56
|
const as = props.as ?? ui.input.as;
|
|
58
57
|
let isDisabled = !!props.isDisabled;
|
|
@@ -94,22 +93,19 @@ function Autocomplete({ renderStaticInput, ...props }) {
|
|
|
94
93
|
labelPlacement: "content-row",
|
|
95
94
|
dataAttributes,
|
|
96
95
|
renderStatic: true,
|
|
97
|
-
onStaticInteract:
|
|
98
|
-
setShouldFocus(focus);
|
|
99
|
-
setRenderInput(true);
|
|
100
|
-
},
|
|
96
|
+
onStaticInteract: renderRealInput,
|
|
101
97
|
leadingContent: props.leadingContent && /* @__PURE__ */ jsx("div", {
|
|
102
98
|
className: "ml-input-side-default flex shrink-0 items-center",
|
|
103
99
|
children: props.leadingContent
|
|
104
100
|
}),
|
|
105
101
|
trailingContent,
|
|
106
102
|
children: (dataAttributeProps) => /* @__PURE__ */ jsxs(Fragment, { children: [isMultiple && !isEmpty && displayValue, /* @__PURE__ */ jsx("input", {
|
|
107
|
-
readOnly: true,
|
|
108
103
|
disabled: isDisabled,
|
|
109
104
|
tabIndex: -1,
|
|
110
105
|
value: inputValue,
|
|
111
106
|
placeholder: isMultiple && shouldRenderPlaceholderAfterValue ? props.placeholder : placeholder ?? void 0,
|
|
112
107
|
className: clsx("w-full flex-1 bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.inputClassName),
|
|
108
|
+
onChange: (event) => replayStaticInputChange(event.target.value),
|
|
113
109
|
...dataAttributeProps,
|
|
114
110
|
"data-rac": true
|
|
115
111
|
})] })
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ArrowDropDownIcon } from "../../../../assets/icons/ArrowDropDown.js";
|
|
2
2
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
3
3
|
import { InputFrame } from "../../Skeleton/InputFrame.js";
|
|
4
|
+
import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
|
|
4
5
|
import { SelectBase } from "../shared/SelectBase.js";
|
|
5
6
|
import { getStaticSelectValue } from "../shared/staticSelect.utils.js";
|
|
6
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
8
|
import { clsx } from "clsx";
|
|
8
|
-
import {
|
|
9
|
+
import { useRef, useState } from "react";
|
|
9
10
|
import { mergeRefs } from "@react-aria/utils";
|
|
10
11
|
import { Controller, useWatch } from "react-hook-form";
|
|
11
12
|
//#region src/components/inputs/Selection/Select/Select.tsx
|
|
@@ -32,8 +33,13 @@ function _Select(props) {
|
|
|
32
33
|
function Select({ renderStaticInput, ...props }) {
|
|
33
34
|
const ui = UIConfig.useConfig();
|
|
34
35
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
35
|
-
const [shouldFocus, setShouldFocus] = useState(false);
|
|
36
36
|
const rootRef = useRef(null);
|
|
37
|
+
const { renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
|
|
38
|
+
inputRef: rootRef,
|
|
39
|
+
renderInput,
|
|
40
|
+
setRenderInput,
|
|
41
|
+
getFocusTarget: (root) => root.querySelector("[data-type='select-trigger'], input, button, [tabindex]")
|
|
42
|
+
});
|
|
37
43
|
const currentValue = ("formControl" in props && props.formControl ? useWatch({
|
|
38
44
|
control: props.formControl.control,
|
|
39
45
|
name: props.formControl.name
|
|
@@ -42,13 +48,6 @@ function Select({ renderStaticInput, ...props }) {
|
|
|
42
48
|
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
43
49
|
if (!renderInput && props.selectionMode !== "multiple" && !!props.showSelectionContent && currentValue != null) setRenderInput(true);
|
|
44
50
|
if (!renderInput && !!props.customTrigger) setRenderInput(true);
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (!renderInput || !shouldFocus) return;
|
|
47
|
-
requestAnimationFrame(() => {
|
|
48
|
-
(rootRef.current?.querySelector("[data-type='select-trigger'], input, button, [tabindex]"))?.focus();
|
|
49
|
-
});
|
|
50
|
-
setShouldFocus(false);
|
|
51
|
-
}, [renderInput, shouldFocus]);
|
|
52
51
|
if (!renderInput) {
|
|
53
52
|
const as = props.as ?? ui.input.as;
|
|
54
53
|
let isDisabled = !!props.isDisabled;
|
|
@@ -95,10 +94,7 @@ function Select({ renderStaticInput, ...props }) {
|
|
|
95
94
|
labelPlacement: "content-row",
|
|
96
95
|
dataAttributes,
|
|
97
96
|
renderStatic: true,
|
|
98
|
-
onStaticInteract:
|
|
99
|
-
setShouldFocus(focus);
|
|
100
|
-
setRenderInput(true);
|
|
101
|
-
},
|
|
97
|
+
onStaticInteract: renderRealInput,
|
|
102
98
|
leadingContent: props.leadingContent && /* @__PURE__ */ jsx("div", {
|
|
103
99
|
className: "ml-input-side-default flex shrink-0 items-center",
|
|
104
100
|
children: props.leadingContent
|
|
@@ -106,12 +102,12 @@ function Select({ renderStaticInput, ...props }) {
|
|
|
106
102
|
showClear: false,
|
|
107
103
|
trailingContent,
|
|
108
104
|
children: (dataAttributeProps) => /* @__PURE__ */ jsxs(Fragment, { children: [isMultiple && !isEmpty && displayValue, isSearchable ? /* @__PURE__ */ jsx("input", {
|
|
109
|
-
readOnly: true,
|
|
110
105
|
disabled: isDisabled,
|
|
111
106
|
tabIndex: -1,
|
|
112
107
|
value: inputValue,
|
|
113
108
|
placeholder: shouldRenderPlaceholderAfterValue ? props.placeholder : placeholder ?? void 0,
|
|
114
109
|
className: clsx("w-full flex-1 bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.inputClassName),
|
|
110
|
+
onChange: (event) => replayStaticInputChange(event.target.value),
|
|
115
111
|
...dataAttributeProps,
|
|
116
112
|
"data-rac": true
|
|
117
113
|
}) : /* @__PURE__ */ jsx("button", {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Dispatch, RefObject, SetStateAction } from 'react';
|
|
2
|
+
interface StaticInputHandoffOptions<TElement extends HTMLElement> {
|
|
3
|
+
inputRef: RefObject<TElement | null>;
|
|
4
|
+
renderInput: boolean;
|
|
5
|
+
setRenderInput: Dispatch<SetStateAction<boolean>>;
|
|
6
|
+
getFocusTarget?: (element: TElement) => HTMLElement | null | undefined;
|
|
7
|
+
}
|
|
8
|
+
export declare const useStaticInputHandoff: <TElement extends HTMLElement = HTMLInputElement>({ inputRef, renderInput, setRenderInput, getFocusTarget, }: StaticInputHandoffOptions<TElement>) => {
|
|
9
|
+
shouldFocus: boolean;
|
|
10
|
+
renderRealInput: (focus: boolean) => void;
|
|
11
|
+
replayStaticInputChange: (value: string) => void;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
2
|
+
//#region src/components/inputs/shared/useStaticInputHandoff.ts
|
|
3
|
+
var useStaticInputHandoff = ({ inputRef, renderInput, setRenderInput, getFocusTarget }) => {
|
|
4
|
+
const [shouldFocus, setShouldFocus] = useState(false);
|
|
5
|
+
const pendingStaticChangeRef = useRef(null);
|
|
6
|
+
useLayoutEffect(() => {
|
|
7
|
+
if (!renderInput || !shouldFocus) return;
|
|
8
|
+
const focusRealInput = (replayPendingChange) => {
|
|
9
|
+
const input = inputRef.current;
|
|
10
|
+
const pendingValue = pendingStaticChangeRef.current;
|
|
11
|
+
const focusTarget = input ? getFocusTarget?.(input) ?? input : null;
|
|
12
|
+
if (replayPendingChange && focusTarget instanceof HTMLInputElement && pendingValue != null) {
|
|
13
|
+
(Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set)?.call(focusTarget, pendingValue);
|
|
14
|
+
focusTarget.dispatchEvent(new Event("input", { bubbles: true }));
|
|
15
|
+
pendingStaticChangeRef.current = null;
|
|
16
|
+
}
|
|
17
|
+
focusTarget?.focus();
|
|
18
|
+
};
|
|
19
|
+
focusRealInput(true);
|
|
20
|
+
const frame = requestAnimationFrame(() => {
|
|
21
|
+
focusRealInput(false);
|
|
22
|
+
setShouldFocus(false);
|
|
23
|
+
});
|
|
24
|
+
return () => {
|
|
25
|
+
cancelAnimationFrame(frame);
|
|
26
|
+
};
|
|
27
|
+
}, [
|
|
28
|
+
getFocusTarget,
|
|
29
|
+
inputRef,
|
|
30
|
+
renderInput,
|
|
31
|
+
shouldFocus
|
|
32
|
+
]);
|
|
33
|
+
return {
|
|
34
|
+
shouldFocus,
|
|
35
|
+
renderRealInput: (focus) => {
|
|
36
|
+
setShouldFocus(focus);
|
|
37
|
+
setRenderInput(true);
|
|
38
|
+
},
|
|
39
|
+
replayStaticInputChange: (value) => {
|
|
40
|
+
pendingStaticChangeRef.current = value;
|
|
41
|
+
setShouldFocus(true);
|
|
42
|
+
setRenderInput(true);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { useStaticInputHandoff };
|