@povio/ui 2.2.9-rc.14 → 2.2.9-rc.16
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.d.ts +2 -1
- package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +62 -4
- package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +2 -1
- package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +91 -4
- package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +2 -1
- package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +62 -4
- package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +2 -1
- package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +58 -3
- package/dist/components/inputs/DateTime/shared/DatePickerInput.js +4 -3
- package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +5 -2
- package/dist/components/inputs/Input/NumberInput/NumberInput.js +80 -8
- package/dist/components/inputs/Input/TextInput/TextInput.d.ts +3 -1
- package/dist/components/inputs/Input/TextInput/TextInput.js +83 -8
- package/dist/components/inputs/Inputs/InputItem.d.ts +7 -7
- package/dist/components/inputs/RadioGroup/RadioGroup.js +15 -12
- package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +3 -1
- package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +64 -3
- package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +1 -1
- package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +13 -9
- package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +22 -26
- package/dist/components/inputs/Selection/Select/QuerySelect.js +1 -1
- package/dist/components/inputs/Selection/Select/Select.d.ts +3 -1
- package/dist/components/inputs/Selection/Select/Select.js +65 -3
- package/dist/components/inputs/Selection/shared/SelectInput.js +7 -5
- package/dist/components/inputs/shared/StaticInput.d.ts +19 -0
- package/dist/components/inputs/shared/StaticInput.js +69 -0
- package/dist/components/inputs/shared/TooltipWrapper.js +5 -1
- package/dist/components/inputs/shared/input.cva.d.ts +5 -0
- package/dist/components/inputs/shared/input.cva.js +10 -1
- package/dist/components/inputs/shared/tooltipWrapper.cva.d.ts +4 -0
- package/dist/components/inputs/shared/tooltipWrapper.cva.js +5 -0
- package/dist/config/uiConfig.context.d.ts +4 -1
- package/dist/config/uiConfig.context.js +5 -0
- package/dist/config/uiStyle.context.d.ts +6 -1
- package/dist/hooks/useQueryAutocomplete.d.ts +5 -17
- package/dist/hooks/useQueryAutocomplete.js +6 -4
- package/dist/index.d.ts +1 -0
- package/dist/utils/date-time.utils.d.ts +10 -0
- package/dist/utils/date-time.utils.js +82 -1
- package/package.json +1 -1
|
@@ -27,7 +27,8 @@ export interface DatePickerProps extends Omit<DatePickerBaseProps, "value" | "on
|
|
|
27
27
|
fullIso?: boolean;
|
|
28
28
|
minValue?: DateValue | string;
|
|
29
29
|
maxValue?: DateValue | string;
|
|
30
|
+
renderStaticInput?: boolean;
|
|
30
31
|
}
|
|
31
32
|
export type ControlledDatePickerProps<TFieldValues extends FieldValues> = ControlProps<DatePickerProps, TFieldValues>;
|
|
32
|
-
export declare const DatePicker: <TFieldValues extends FieldValues>({ fullIso, minValue, maxValue, ...props }: ControlledDatePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare const DatePicker: <TFieldValues extends FieldValues>({ fullIso, minValue, maxValue, renderStaticInput, ...props }: ControlledDatePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
33
34
|
export {};
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
import { CalendarIcon } from "../../../../assets/icons/Calendar.js";
|
|
1
2
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
3
|
+
import { TodayIcon } from "../../../../assets/icons/Today.js";
|
|
2
4
|
import { Calendar } from "../shared/Calendar.js";
|
|
3
5
|
import { DatePickerInput } from "../shared/DatePickerInput.js";
|
|
4
6
|
import { DateTimeDialog } from "../shared/DateTimeDialog.js";
|
|
5
7
|
import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
|
|
6
8
|
import { FormField } from "../../FormField/FormField.js";
|
|
9
|
+
import { StaticInput } from "../../shared/StaticInput.js";
|
|
7
10
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
8
11
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
9
12
|
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
10
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
14
|
import { clsx } from "clsx";
|
|
12
|
-
import { useImperativeHandle, useMemo, useRef } from "react";
|
|
15
|
+
import { useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
13
16
|
import { useDatePicker, useLocale } from "react-aria";
|
|
14
17
|
import { mergeRefs } from "@react-aria/utils";
|
|
15
|
-
import { Controller } from "react-hook-form";
|
|
18
|
+
import { Controller, useWatch } from "react-hook-form";
|
|
16
19
|
import { CalendarDate, createCalendar, getLocalTimeZone, toCalendarDate, today } from "@internationalized/date";
|
|
17
20
|
import { DateTime } from "luxon";
|
|
18
21
|
import { useCalendarState, useDatePickerState } from "react-stately";
|
|
@@ -164,7 +167,19 @@ var DatePickerBase = (props) => {
|
|
|
164
167
|
})
|
|
165
168
|
});
|
|
166
169
|
};
|
|
167
|
-
var DatePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
170
|
+
var DatePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput, ...props }) => {
|
|
171
|
+
const ui = UIConfig.useConfig();
|
|
172
|
+
const { locale } = useLocale();
|
|
173
|
+
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
174
|
+
const [shouldFocus, setShouldFocus] = useState(false);
|
|
175
|
+
const inputRef = useRef(null);
|
|
176
|
+
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
177
|
+
control: props.formControl.control,
|
|
178
|
+
name: props.formControl.name
|
|
179
|
+
}) : props.value;
|
|
180
|
+
let isFormControlDisabled = false;
|
|
181
|
+
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
182
|
+
const rawValue = watchedValue ?? props.value ?? null;
|
|
168
183
|
const formatCalendarDate = (calendarDate) => {
|
|
169
184
|
if (calendarDate === null) return null;
|
|
170
185
|
if (fullIso) return DateTimeUtils.fromCalendarDateToUTCISO(calendarDate);
|
|
@@ -181,6 +196,48 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
181
196
|
minValue: typeof minValue === "string" ? parseCalendarDate(minValue) : minValue,
|
|
182
197
|
maxValue: typeof maxValue === "string" ? parseCalendarDate(maxValue) : maxValue
|
|
183
198
|
};
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
if (!renderInput || !shouldFocus) return;
|
|
201
|
+
requestAnimationFrame(() => {
|
|
202
|
+
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
203
|
+
});
|
|
204
|
+
setShouldFocus(false);
|
|
205
|
+
}, [renderInput, shouldFocus]);
|
|
206
|
+
if (!renderInput) {
|
|
207
|
+
const as = props.as ?? ui.input.as;
|
|
208
|
+
const size = props.size ?? ui.input.size;
|
|
209
|
+
const variant = props.variant ?? ui.input.variant;
|
|
210
|
+
const hideLabel = props.hideLabel ?? ui.input.hideLabel;
|
|
211
|
+
const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
|
|
212
|
+
let isDisabled = !!props.isDisabled;
|
|
213
|
+
if (isFormControlDisabled) isDisabled = true;
|
|
214
|
+
const todayIcon = props.todayIcon ?? ui.dateInput.todayIcon;
|
|
215
|
+
const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
|
|
216
|
+
const showDropdown = !props.disableDropdown || disableManualEntry;
|
|
217
|
+
const staticPlaceholder = props.placeholder ?? DateTimeUtils.getDatePlaceholder(locale);
|
|
218
|
+
const staticDateValue = rawValue ? parseCalendarDate(rawValue) : null;
|
|
219
|
+
const displayValue = staticDateValue ? DateTimeUtils.formatCalendarDateLocalized(staticDateValue, locale) : "";
|
|
220
|
+
return /* @__PURE__ */ jsx(StaticInput, {
|
|
221
|
+
...props,
|
|
222
|
+
onInteract: (focus) => {
|
|
223
|
+
setShouldFocus(focus);
|
|
224
|
+
setRenderInput(true);
|
|
225
|
+
},
|
|
226
|
+
className: clsx("relative inline-flex w-full flex-col text-left", props.className),
|
|
227
|
+
as,
|
|
228
|
+
size,
|
|
229
|
+
variant,
|
|
230
|
+
applyMinInputWidth: true,
|
|
231
|
+
hideLabel,
|
|
232
|
+
isHeaderHidden,
|
|
233
|
+
isDisabled,
|
|
234
|
+
placeholder: staticPlaceholder,
|
|
235
|
+
displayValue,
|
|
236
|
+
isEmpty: !displayValue,
|
|
237
|
+
leadingVisual: todayIcon ? /* @__PURE__ */ jsx(TodayIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0,
|
|
238
|
+
trailingVisual: showDropdown ? /* @__PURE__ */ jsx(CalendarIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0
|
|
239
|
+
});
|
|
240
|
+
}
|
|
184
241
|
if ("formControl" in props && props.formControl) {
|
|
185
242
|
const { formControl, ref, ...innerProps } = props;
|
|
186
243
|
return /* @__PURE__ */ jsx(Controller, {
|
|
@@ -189,7 +246,7 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
189
246
|
render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(DatePickerBase, {
|
|
190
247
|
...innerProps,
|
|
191
248
|
...dateLimits,
|
|
192
|
-
ref: mergeRefs(ref, field.ref),
|
|
249
|
+
ref: mergeRefs(ref, field.ref, inputRef),
|
|
193
250
|
value: parseCalendarDate(field.value),
|
|
194
251
|
onChange: (value) => field.onChange(formatCalendarDate(value)),
|
|
195
252
|
onBlur: field.onBlur,
|
|
@@ -202,6 +259,7 @@ var DatePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
202
259
|
return /* @__PURE__ */ jsx(DatePickerBase, {
|
|
203
260
|
...props,
|
|
204
261
|
...dateLimits,
|
|
262
|
+
ref: mergeRefs(props.ref, inputRef),
|
|
205
263
|
value: parseCalendarDate(props.value),
|
|
206
264
|
onChange: (value) => props.onChange?.(formatCalendarDate(value))
|
|
207
265
|
});
|
|
@@ -35,7 +35,8 @@ export interface DateRangePickerProps extends Omit<DateRangePickerBaseProps, "va
|
|
|
35
35
|
fullIso?: boolean;
|
|
36
36
|
minValue?: DateValue | string;
|
|
37
37
|
maxValue?: DateValue | string;
|
|
38
|
+
renderStaticInput?: boolean;
|
|
38
39
|
}
|
|
39
40
|
export type ControlledDateRangePickerProps<TFieldValues extends FieldValues> = ControlProps<DateRangePickerProps, TFieldValues>;
|
|
40
|
-
export declare const DateRangePicker: <TFieldValues extends FieldValues>({ fullIso, minValue, maxValue, ...props }: ControlledDateRangePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
41
|
+
export declare const DateRangePicker: <TFieldValues extends FieldValues>({ fullIso, minValue, maxValue, renderStaticInput, ...props }: ControlledDateRangePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
41
42
|
export {};
|
|
@@ -1,22 +1,25 @@
|
|
|
1
|
+
import { CalendarIcon } from "../../../../assets/icons/Calendar.js";
|
|
1
2
|
import { Typography } from "../../../text/Typography/Typography.js";
|
|
2
3
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
3
4
|
import "../../../../config/i18n.js";
|
|
5
|
+
import { TodayIcon } from "../../../../assets/icons/Today.js";
|
|
4
6
|
import { DatePickerInput } from "../shared/DatePickerInput.js";
|
|
5
7
|
import { DateTimeDialog } from "../shared/DateTimeDialog.js";
|
|
6
8
|
import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
|
|
7
9
|
import { FormField } from "../../FormField/FormField.js";
|
|
10
|
+
import { StaticInput } from "../../shared/StaticInput.js";
|
|
8
11
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
9
12
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
10
13
|
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
11
14
|
import { RangeCalendar } from "../shared/RangeCalendar.js";
|
|
12
15
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
16
|
import { clsx } from "clsx";
|
|
14
|
-
import { useCallback, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
17
|
+
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
15
18
|
import { Button } from "react-aria-components";
|
|
16
19
|
import { useDateRangePicker, useLocale as useLocale$1 } from "react-aria";
|
|
17
20
|
import { mergeRefs } from "@react-aria/utils";
|
|
18
21
|
import { useTranslation } from "react-i18next";
|
|
19
|
-
import { Controller } from "react-hook-form";
|
|
22
|
+
import { Controller, useWatch } from "react-hook-form";
|
|
20
23
|
import { createCalendar, endOfMonth, endOfWeek, endOfYear, getLocalTimeZone, startOfMonth, startOfWeek, startOfYear, toCalendarDate, today } from "@internationalized/date";
|
|
21
24
|
import { DateTime } from "luxon";
|
|
22
25
|
import { useDateRangePickerState, useRangeCalendarState } from "react-stately";
|
|
@@ -540,7 +543,19 @@ var DateRangePickerBase = (props) => {
|
|
|
540
543
|
})
|
|
541
544
|
});
|
|
542
545
|
};
|
|
543
|
-
var DateRangePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
546
|
+
var DateRangePicker = ({ fullIso = true, minValue, maxValue, renderStaticInput, ...props }) => {
|
|
547
|
+
const ui = UIConfig.useConfig();
|
|
548
|
+
const { locale } = useLocale$1();
|
|
549
|
+
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
550
|
+
const [shouldFocus, setShouldFocus] = useState(false);
|
|
551
|
+
const inputRef = useRef(null);
|
|
552
|
+
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
553
|
+
control: props.formControl.control,
|
|
554
|
+
name: props.formControl.name
|
|
555
|
+
}) : props.value;
|
|
556
|
+
let isFormControlDisabled = false;
|
|
557
|
+
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
558
|
+
const rawValue = watchedValue ?? props.value ?? null;
|
|
544
559
|
const formatDateRange = (range) => {
|
|
545
560
|
if (!range?.start || !range?.end) return null;
|
|
546
561
|
if (fullIso) return {
|
|
@@ -579,6 +594,77 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
579
594
|
minValue: typeof minValue === "string" ? parseCalendarDate(minValue) : minValue,
|
|
580
595
|
maxValue: typeof maxValue === "string" ? parseCalendarDate(maxValue) : maxValue
|
|
581
596
|
};
|
|
597
|
+
useEffect(() => {
|
|
598
|
+
if (!renderInput || !shouldFocus) return;
|
|
599
|
+
requestAnimationFrame(() => {
|
|
600
|
+
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
601
|
+
});
|
|
602
|
+
setShouldFocus(false);
|
|
603
|
+
}, [renderInput, shouldFocus]);
|
|
604
|
+
if (!renderInput) {
|
|
605
|
+
const as = props.as ?? ui.input.as;
|
|
606
|
+
const size = props.size ?? ui.input.size;
|
|
607
|
+
const variant = props.variant ?? ui.input.variant;
|
|
608
|
+
const hideLabel = props.hideLabel ?? ui.input.hideLabel;
|
|
609
|
+
const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
|
|
610
|
+
let isDisabled = !!props.isDisabled;
|
|
611
|
+
if (isFormControlDisabled) isDisabled = true;
|
|
612
|
+
const todayIcon = props.todayIcon ?? ui.dateInput.todayIcon;
|
|
613
|
+
const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
|
|
614
|
+
const showDropdown = !props.disableDropdown || disableManualEntry;
|
|
615
|
+
const defaultDatePlaceholder = DateTimeUtils.getDatePlaceholder(locale);
|
|
616
|
+
const staticPlaceholder = props.placeholder ?? /* @__PURE__ */ jsxs("span", {
|
|
617
|
+
className: "inline-flex items-center gap-input-gap-input-text-to-elements",
|
|
618
|
+
children: [
|
|
619
|
+
/* @__PURE__ */ jsx("span", { children: defaultDatePlaceholder }),
|
|
620
|
+
/* @__PURE__ */ jsx("span", {
|
|
621
|
+
className: "pointer-events-none select-none",
|
|
622
|
+
children: "–"
|
|
623
|
+
}),
|
|
624
|
+
/* @__PURE__ */ jsx("span", { children: defaultDatePlaceholder })
|
|
625
|
+
]
|
|
626
|
+
});
|
|
627
|
+
const formatStaticDate = (value) => {
|
|
628
|
+
if (!value) return "";
|
|
629
|
+
const parsedDate = parseCalendarDate(value);
|
|
630
|
+
if (!parsedDate) return "";
|
|
631
|
+
return DateTimeUtils.formatCalendarDateLocalized(parsedDate, locale);
|
|
632
|
+
};
|
|
633
|
+
const start = formatStaticDate(rawValue?.start ?? null);
|
|
634
|
+
const end = formatStaticDate(rawValue?.end ?? null);
|
|
635
|
+
const hasRangeValue = !!(start && end);
|
|
636
|
+
const displayValue = hasRangeValue ? /* @__PURE__ */ jsxs("span", {
|
|
637
|
+
className: "inline-flex items-center gap-input-gap-input-text-to-elements",
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsx("span", { children: start }),
|
|
640
|
+
/* @__PURE__ */ jsx("span", {
|
|
641
|
+
className: "pointer-events-none select-none",
|
|
642
|
+
children: "–"
|
|
643
|
+
}),
|
|
644
|
+
/* @__PURE__ */ jsx("span", { children: end })
|
|
645
|
+
]
|
|
646
|
+
}) : void 0;
|
|
647
|
+
return /* @__PURE__ */ jsx(StaticInput, {
|
|
648
|
+
...props,
|
|
649
|
+
onInteract: (focus) => {
|
|
650
|
+
setShouldFocus(focus);
|
|
651
|
+
setRenderInput(true);
|
|
652
|
+
},
|
|
653
|
+
className: clsx("relative inline-flex w-full flex-col text-left", props.className),
|
|
654
|
+
as,
|
|
655
|
+
size,
|
|
656
|
+
variant,
|
|
657
|
+
applyMinInputWidth: true,
|
|
658
|
+
hideLabel,
|
|
659
|
+
isHeaderHidden,
|
|
660
|
+
isDisabled,
|
|
661
|
+
placeholder: staticPlaceholder,
|
|
662
|
+
displayValue,
|
|
663
|
+
isEmpty: !hasRangeValue,
|
|
664
|
+
leadingVisual: todayIcon ? /* @__PURE__ */ jsx(TodayIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0,
|
|
665
|
+
trailingVisual: showDropdown ? /* @__PURE__ */ jsx(CalendarIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0
|
|
666
|
+
});
|
|
667
|
+
}
|
|
582
668
|
if ("formControl" in props && props.formControl) {
|
|
583
669
|
const { formControl, ref, ...innerProps } = props;
|
|
584
670
|
return /* @__PURE__ */ jsx(Controller, {
|
|
@@ -587,7 +673,7 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
587
673
|
render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(DateRangePickerBase, {
|
|
588
674
|
...innerProps,
|
|
589
675
|
...dateLimits,
|
|
590
|
-
ref: mergeRefs(ref, field.ref),
|
|
676
|
+
ref: mergeRefs(ref, field.ref, inputRef),
|
|
591
677
|
value: parseDateRange(field.value),
|
|
592
678
|
onChange: (value) => field.onChange(formatDateRange(value)),
|
|
593
679
|
onBlur: field.onBlur,
|
|
@@ -600,6 +686,7 @@ var DateRangePicker = ({ fullIso = true, minValue, maxValue, ...props }) => {
|
|
|
600
686
|
return /* @__PURE__ */ jsx(DateRangePickerBase, {
|
|
601
687
|
...props,
|
|
602
688
|
...dateLimits,
|
|
689
|
+
ref: mergeRefs(props.ref, inputRef),
|
|
603
690
|
value: parseDateRange(props.value),
|
|
604
691
|
onChange: (value) => props.onChange?.(formatDateRange(value))
|
|
605
692
|
});
|
|
@@ -26,7 +26,8 @@ export interface DateTimePickerProps extends Omit<DateTimePickerBaseProps, "valu
|
|
|
26
26
|
value?: string | null;
|
|
27
27
|
onChange?: (value: string | null) => void;
|
|
28
28
|
fullIso?: boolean;
|
|
29
|
+
renderStaticInput?: boolean;
|
|
29
30
|
}
|
|
30
31
|
export type ControlledDateTimePickerProps<TFieldValues extends FieldValues> = ControlProps<DateTimePickerProps, TFieldValues>;
|
|
31
|
-
export declare const DateTimePicker: <TFieldValues extends FieldValues>({ fullIso, ...props }: ControlledDateTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
32
|
+
export declare const DateTimePicker: <TFieldValues extends FieldValues>({ fullIso, renderStaticInput, ...props }: ControlledDateTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
32
33
|
export {};
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
import { DateTimeIcon } from "../../../../assets/icons/DateTime.js";
|
|
1
2
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
3
|
+
import { TodayIcon } from "../../../../assets/icons/Today.js";
|
|
2
4
|
import { Calendar } from "../shared/Calendar.js";
|
|
3
5
|
import { DatePickerInput } from "../shared/DatePickerInput.js";
|
|
4
6
|
import { DateTimeDialog } from "../shared/DateTimeDialog.js";
|
|
5
7
|
import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
|
|
6
8
|
import { FormField } from "../../FormField/FormField.js";
|
|
9
|
+
import { StaticInput } from "../../shared/StaticInput.js";
|
|
7
10
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
8
11
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
9
12
|
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
10
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
-
import { useEffect, useImperativeHandle, useMemo, useRef } from "react";
|
|
14
|
+
import { useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
12
15
|
import { useDatePicker, useLocale } from "react-aria";
|
|
13
16
|
import { mergeRefs } from "@react-aria/utils";
|
|
14
|
-
import { Controller } from "react-hook-form";
|
|
17
|
+
import { Controller, useWatch } from "react-hook-form";
|
|
15
18
|
import { Time, createCalendar, getLocalTimeZone, now, toCalendarDateTime, today } from "@internationalized/date";
|
|
16
19
|
import { useCalendarState, useDatePickerState } from "react-stately";
|
|
17
20
|
//#region src/components/inputs/DateTime/DateTimePicker/DateTimePicker.tsx
|
|
@@ -184,7 +187,19 @@ var DateTimePickerBase = (props) => {
|
|
|
184
187
|
})
|
|
185
188
|
});
|
|
186
189
|
};
|
|
187
|
-
var DateTimePicker = ({ fullIso = true, ...props }) => {
|
|
190
|
+
var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
|
|
191
|
+
const ui = UIConfig.useConfig();
|
|
192
|
+
const { locale } = useLocale();
|
|
193
|
+
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
194
|
+
const [shouldFocus, setShouldFocus] = useState(false);
|
|
195
|
+
const inputRef = useRef(null);
|
|
196
|
+
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
197
|
+
control: props.formControl.control,
|
|
198
|
+
name: props.formControl.name
|
|
199
|
+
}) : props.value;
|
|
200
|
+
let isFormControlDisabled = false;
|
|
201
|
+
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
202
|
+
const rawValue = watchedValue ?? props.value ?? null;
|
|
188
203
|
const formatDateValue = (dateValue) => {
|
|
189
204
|
if (dateValue === null) return null;
|
|
190
205
|
if (fullIso) return DateTimeUtils.fromCalendarDateTimeToUTCISO(dateValue);
|
|
@@ -194,6 +209,48 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
|
|
|
194
209
|
if (isoString == null) return isoString;
|
|
195
210
|
return DateTimeUtils.fromUTCISOToCalendarDateTime(isoString);
|
|
196
211
|
};
|
|
212
|
+
useEffect(() => {
|
|
213
|
+
if (!renderInput || !shouldFocus) return;
|
|
214
|
+
requestAnimationFrame(() => {
|
|
215
|
+
((inputRef.current?.getContainer?.() ?? inputRef.current)?.querySelector("input, button, [tabindex]:not([tabindex='-1'])"))?.focus();
|
|
216
|
+
});
|
|
217
|
+
setShouldFocus(false);
|
|
218
|
+
}, [renderInput, shouldFocus]);
|
|
219
|
+
if (!renderInput) {
|
|
220
|
+
const as = props.as ?? ui.input.as;
|
|
221
|
+
const size = props.size ?? ui.input.size;
|
|
222
|
+
const variant = props.variant ?? ui.input.variant;
|
|
223
|
+
const hideLabel = props.hideLabel ?? ui.input.hideLabel;
|
|
224
|
+
const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
|
|
225
|
+
let isDisabled = !!props.isDisabled;
|
|
226
|
+
if (isFormControlDisabled) isDisabled = true;
|
|
227
|
+
const todayIcon = props.todayIcon ?? ui.dateInput.todayIcon;
|
|
228
|
+
const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
|
|
229
|
+
const showDropdown = !props.disableDropdown || disableManualEntry;
|
|
230
|
+
const staticPlaceholder = props.placeholder ?? DateTimeUtils.getDateTimePlaceholder(locale);
|
|
231
|
+
const staticDateTimeValue = rawValue ? parseDateValue(rawValue) : null;
|
|
232
|
+
const displayValue = staticDateTimeValue && "hour" in staticDateTimeValue ? DateTimeUtils.formatCalendarDateTimeLocalized(staticDateTimeValue, locale) : "";
|
|
233
|
+
return /* @__PURE__ */ jsx(StaticInput, {
|
|
234
|
+
...props,
|
|
235
|
+
onInteract: (focus) => {
|
|
236
|
+
setShouldFocus(focus);
|
|
237
|
+
setRenderInput(true);
|
|
238
|
+
},
|
|
239
|
+
className: props.className ? `relative inline-flex w-full flex-col text-left ${props.className}` : "relative inline-flex w-full flex-col text-left",
|
|
240
|
+
as,
|
|
241
|
+
size,
|
|
242
|
+
variant,
|
|
243
|
+
applyMinInputWidth: true,
|
|
244
|
+
hideLabel,
|
|
245
|
+
isHeaderHidden,
|
|
246
|
+
isDisabled,
|
|
247
|
+
placeholder: staticPlaceholder,
|
|
248
|
+
displayValue,
|
|
249
|
+
isEmpty: !displayValue,
|
|
250
|
+
leadingVisual: todayIcon ? /* @__PURE__ */ jsx(TodayIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0,
|
|
251
|
+
trailingVisual: showDropdown ? /* @__PURE__ */ jsx(DateTimeIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0
|
|
252
|
+
});
|
|
253
|
+
}
|
|
197
254
|
if ("formControl" in props && props.formControl) {
|
|
198
255
|
const { formControl, ref, ...innerProps } = props;
|
|
199
256
|
return /* @__PURE__ */ jsx(Controller, {
|
|
@@ -201,7 +258,7 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
|
|
|
201
258
|
name: formControl.name,
|
|
202
259
|
render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(DateTimePickerBase, {
|
|
203
260
|
...innerProps,
|
|
204
|
-
ref: mergeRefs(ref, field.ref),
|
|
261
|
+
ref: mergeRefs(ref, field.ref, inputRef),
|
|
205
262
|
value: parseDateValue(field.value),
|
|
206
263
|
onChange: (value) => field.onChange(formatDateValue(value)),
|
|
207
264
|
onBlur: field.onBlur,
|
|
@@ -213,6 +270,7 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
|
|
|
213
270
|
}
|
|
214
271
|
return /* @__PURE__ */ jsx(DateTimePickerBase, {
|
|
215
272
|
...props,
|
|
273
|
+
ref: mergeRefs(props.ref, inputRef),
|
|
216
274
|
value: parseDateValue(props.value),
|
|
217
275
|
onChange: (value) => props.onChange?.(formatDateValue(value))
|
|
218
276
|
});
|
|
@@ -19,7 +19,8 @@ export interface TimePickerProps extends Omit<TimePickerBaseProps, "value" | "on
|
|
|
19
19
|
value?: string | null;
|
|
20
20
|
onChange?: (value: string | null) => void;
|
|
21
21
|
fullIso?: boolean;
|
|
22
|
+
renderStaticInput?: boolean;
|
|
22
23
|
}
|
|
23
24
|
export type ControlledTimePickerProps<TFieldValues extends FieldValues> = ControlProps<TimePickerProps, TFieldValues>;
|
|
24
|
-
export declare const TimePicker: <TFieldValues extends FieldValues>(props: ControlledTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export declare const TimePicker: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
25
26
|
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { ClockIcon } from "../../../../assets/icons/Clock.js";
|
|
1
2
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
2
3
|
import { TimePickerForm } from "../shared/TimePickerForm.js";
|
|
3
4
|
import { DateTimeDialog } from "../shared/DateTimeDialog.js";
|
|
4
5
|
import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
|
|
5
6
|
import { FormField } from "../../FormField/FormField.js";
|
|
7
|
+
import { StaticInput } from "../../shared/StaticInput.js";
|
|
6
8
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
7
9
|
import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
|
|
8
10
|
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
@@ -12,7 +14,7 @@ import { clsx } from "clsx";
|
|
|
12
14
|
import { useEffect, useRef, useState } from "react";
|
|
13
15
|
import { useLocale, useTimeField } from "react-aria";
|
|
14
16
|
import { mergeRefs } from "@react-aria/utils";
|
|
15
|
-
import { Controller } from "react-hook-form";
|
|
17
|
+
import { Controller, useWatch } from "react-hook-form";
|
|
16
18
|
import { getLocalTimeZone, now, toTime } from "@internationalized/date";
|
|
17
19
|
import { DateTime } from "luxon";
|
|
18
20
|
import { useTimeFieldState } from "react-stately";
|
|
@@ -136,7 +138,19 @@ var TimePickerBase = (props) => {
|
|
|
136
138
|
})
|
|
137
139
|
});
|
|
138
140
|
};
|
|
139
|
-
var TimePicker = (props) => {
|
|
141
|
+
var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
142
|
+
const ui = UIConfig.useConfig();
|
|
143
|
+
const { locale } = useLocale();
|
|
144
|
+
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
145
|
+
const [shouldFocus, setShouldFocus] = useState(false);
|
|
146
|
+
const inputRef = useRef(null);
|
|
147
|
+
const watchedValue = "formControl" in props && props.formControl ? useWatch({
|
|
148
|
+
control: props.formControl.control,
|
|
149
|
+
name: props.formControl.name
|
|
150
|
+
}) : props.value;
|
|
151
|
+
let isFormControlDisabled = false;
|
|
152
|
+
if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
|
|
153
|
+
const rawValue = watchedValue ?? props.value ?? null;
|
|
140
154
|
const formatTimeValue = (timeValue) => {
|
|
141
155
|
if (timeValue === null) return null;
|
|
142
156
|
const parsedDate = props.date ? DateTime.fromISO(props.date).toJSDate() : void 0;
|
|
@@ -147,6 +161,46 @@ var TimePicker = (props) => {
|
|
|
147
161
|
if (isoString == null) return isoString;
|
|
148
162
|
return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString));
|
|
149
163
|
};
|
|
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
|
+
if (!renderInput) {
|
|
172
|
+
const as = props.as ?? ui.input.as;
|
|
173
|
+
const size = props.size ?? ui.input.size;
|
|
174
|
+
const variant = props.variant ?? ui.input.variant;
|
|
175
|
+
const hideLabel = props.hideLabel ?? ui.input.hideLabel;
|
|
176
|
+
const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
|
|
177
|
+
let isDisabled = !!props.isDisabled;
|
|
178
|
+
if (isFormControlDisabled) isDisabled = true;
|
|
179
|
+
const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
|
|
180
|
+
const showDropdown = !props.disableDropdown || disableManualEntry;
|
|
181
|
+
const staticPlaceholder = props.placeholder ?? DateTimeUtils.getTimePlaceholder(locale);
|
|
182
|
+
const staticTimeValue = rawValue ? parseTimeValue(rawValue) : null;
|
|
183
|
+
const displayValue = staticTimeValue ? DateTimeUtils.formatTimeLocalized(staticTimeValue, locale) : "";
|
|
184
|
+
return /* @__PURE__ */ jsx(StaticInput, {
|
|
185
|
+
...props,
|
|
186
|
+
onInteract: (focus) => {
|
|
187
|
+
setShouldFocus(focus);
|
|
188
|
+
setRenderInput(true);
|
|
189
|
+
},
|
|
190
|
+
className: clsx("relative inline-flex w-full flex-col text-left", props.className),
|
|
191
|
+
as,
|
|
192
|
+
size,
|
|
193
|
+
variant,
|
|
194
|
+
applyMinInputWidth: true,
|
|
195
|
+
hideLabel,
|
|
196
|
+
isHeaderHidden,
|
|
197
|
+
isDisabled,
|
|
198
|
+
placeholder: staticPlaceholder,
|
|
199
|
+
displayValue,
|
|
200
|
+
isEmpty: !displayValue,
|
|
201
|
+
trailingVisual: showDropdown ? /* @__PURE__ */ jsx(ClockIcon, { className: "size-6 text-interactive-text-secondary-idle" }) : void 0
|
|
202
|
+
});
|
|
203
|
+
}
|
|
150
204
|
if ("formControl" in props && props.formControl) {
|
|
151
205
|
const { formControl, ref, ...innerProps } = props;
|
|
152
206
|
return /* @__PURE__ */ jsx(Controller, {
|
|
@@ -154,7 +208,7 @@ var TimePicker = (props) => {
|
|
|
154
208
|
name: formControl.name,
|
|
155
209
|
render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TimePickerBase, {
|
|
156
210
|
...innerProps,
|
|
157
|
-
ref: mergeRefs(ref, field.ref),
|
|
211
|
+
ref: mergeRefs(ref, field.ref, inputRef),
|
|
158
212
|
value: parseTimeValue(field.value),
|
|
159
213
|
onChange: (value) => field.onChange(formatTimeValue(value)),
|
|
160
214
|
onBlur: field.onBlur,
|
|
@@ -166,6 +220,7 @@ var TimePicker = (props) => {
|
|
|
166
220
|
}
|
|
167
221
|
return /* @__PURE__ */ jsx(TimePickerBase, {
|
|
168
222
|
...props,
|
|
223
|
+
ref: mergeRefs(props.ref, inputRef),
|
|
169
224
|
value: parseTimeValue(props.value),
|
|
170
225
|
onChange: (value) => props.onChange?.(formatTimeValue(value))
|
|
171
226
|
});
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { CalendarIcon } from "../../../../assets/icons/Calendar.js";
|
|
2
|
-
import { DateTimeIcon } from "../../../../assets/icons/DateTime.js";
|
|
3
1
|
import { UIStyle } from "../../../../config/uiStyle.context.js";
|
|
4
2
|
import { Typography } from "../../../text/Typography/Typography.js";
|
|
3
|
+
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
5
4
|
import { InlineIconButton } from "../../../buttons/InlineIconButton/InlineIconButton.js";
|
|
6
5
|
import { TodayIcon } from "../../../../assets/icons/Today.js";
|
|
7
6
|
import { DateField } from "./DateField.js";
|
|
@@ -17,6 +16,7 @@ import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
|
|
|
17
16
|
import { getLocalTimeZone, now, toCalendarDateTime, today } from "@internationalized/date";
|
|
18
17
|
//#region src/components/inputs/DateTime/shared/DatePickerInput.tsx
|
|
19
18
|
var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize = "none", isDirty, isRequired, disableManualEntry, autoFixYear = false, placeholder, className, onOpenDropdown, ...props }) => {
|
|
19
|
+
const uiConfig = UIConfig.useConfig();
|
|
20
20
|
const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
|
|
21
21
|
const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
|
|
22
22
|
const datePickerInputContentRowCva = UIStyle.useCva("datePickerInput.contentRowCva", datePickerInputContentRow);
|
|
@@ -72,6 +72,7 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
|
|
|
72
72
|
};
|
|
73
73
|
const hidePlaceholder = as === "floating" && !fieldProps.value && !isFocused;
|
|
74
74
|
const todayIconComponent = todayIcon === true ? TodayIcon : todayIcon || null;
|
|
75
|
+
const pickerIcon = isDateTime ? uiConfig.dateInput.dateTimeIcon : uiConfig.dateInput.calendarIcon;
|
|
75
76
|
return /* @__PURE__ */ jsxs("div", {
|
|
76
77
|
ref: containerRef,
|
|
77
78
|
className: clsx(inputBaseCva({
|
|
@@ -155,7 +156,7 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
|
|
|
155
156
|
label: "",
|
|
156
157
|
color: "secondary",
|
|
157
158
|
...buttonProps,
|
|
158
|
-
icon:
|
|
159
|
+
icon: pickerIcon,
|
|
159
160
|
isDisabled,
|
|
160
161
|
className: "border-0!"
|
|
161
162
|
})]
|
|
@@ -13,8 +13,11 @@ interface NumberInputBaseProps extends FormFieldProps, InputVariantProps, Omit<I
|
|
|
13
13
|
value?: number | null;
|
|
14
14
|
onChange?: (value: number | null) => void;
|
|
15
15
|
onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
|
|
16
|
+
autoFocusOnMount?: boolean;
|
|
16
17
|
}
|
|
17
|
-
export type NumberInputProps = NumberInputBaseProps
|
|
18
|
+
export type NumberInputProps = NumberInputBaseProps & {
|
|
19
|
+
renderStaticInput?: boolean;
|
|
20
|
+
};
|
|
18
21
|
export type ControlledNumberInputProps<TFieldValues extends FieldValues> = ControlProps<NumberInputProps, TFieldValues>;
|
|
19
|
-
export declare const NumberInput: <TFieldValues extends FieldValues>(props: ControlledNumberInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare const NumberInput: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledNumberInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
|
|
20
23
|
export {};
|