@povio/ui 2.2.9-rc.41 → 2.2.9-rc.44
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/buttons/Button/Button.d.ts +3 -4
- package/dist/components/buttons/Button/Button.js +32 -41
- package/dist/components/buttons/PillButton/PillButton.d.ts +2 -2
- package/dist/components/buttons/PillButton/PillButton.js +1 -1
- package/dist/components/buttons/TextButton/TextButton.d.ts +2 -1
- package/dist/components/buttons/ToggleButton/ToggleButton.d.ts +2 -1
- package/dist/components/buttons/shared/ButtonContent.d.ts +3 -3
- package/dist/components/buttons/shared/ButtonContent.js +2 -2
- package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +5 -1
- package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +82 -28
- package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +3 -1
- package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +4 -0
- package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +40 -10
- package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +1 -0
- package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +12 -5
- package/dist/components/inputs/DateTime/shared/Calendar.d.ts +6 -1
- package/dist/components/inputs/DateTime/shared/Calendar.js +112 -15
- package/dist/components/inputs/DateTime/shared/CalendarHeader.d.ts +2 -1
- package/dist/components/inputs/DateTime/shared/CalendarHeader.js +28 -4
- package/dist/components/inputs/DateTime/shared/DateField.d.ts +5 -1
- package/dist/components/inputs/DateTime/shared/DateField.js +60 -13
- package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +5 -1
- package/dist/components/inputs/DateTime/shared/DatePickerInput.js +15 -6
- package/dist/components/inputs/DateTime/shared/MonthPicker.d.ts +5 -1
- package/dist/components/inputs/DateTime/shared/MonthPicker.js +40 -8
- package/dist/components/inputs/DateTime/shared/YearPicker.d.ts +5 -1
- package/dist/components/inputs/DateTime/shared/YearPicker.js +42 -8
- package/dist/components/inputs/Input/NumberInput/NumberInput.js +2 -0
- package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +2 -0
- package/dist/components/inputs/Input/TextInput/TextInput.js +2 -0
- package/dist/components/inputs/Inputs/InputItem.d.ts +1 -1
- package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +5 -0
- package/dist/components/inputs/Selection/Select/Select.js +5 -0
- package/dist/components/inputs/Selection/shared/SelectMobile.js +2 -1
- package/dist/components/inputs/Selection/shared/select.context.js +1 -1
- package/dist/components/inputs/Skeleton/InputFrame.js +2 -2
- package/dist/components/overlays/BottomSheet/BottomSheet.js +2 -3
- package/dist/components/overlays/Tooltip/TooltipEllipsis.d.ts +2 -2
- package/dist/components/segment/Segment.js +2 -1
- package/dist/components/segment/SegmentItem.d.ts +1 -1
- package/dist/components/segment/SegmentItem.js +5 -2
- package/dist/components/segment/segment.types.d.ts +1 -0
- package/dist/config/link.context.js +4 -2
- package/dist/config/uiConfig.context.d.ts +1 -1
- package/dist/config/uiConfig.context.js +3 -1
- package/dist/index.js +1 -1
- package/dist/utils/date-time.utils.d.ts +7 -6
- package/dist/utils/date-time.utils.js +55 -16
- package/package.json +4 -4
- package/dist/components/inputs/DateTime/shared/dateSegment.utils.js +0 -9
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { UIConfig } from "../../../../config/uiConfig.context.js";
|
|
2
2
|
import { TimePickerForm } from "../shared/TimePickerForm.js";
|
|
3
|
+
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
3
4
|
import { DateTimeDialog } from "../shared/DateTimeDialog.js";
|
|
4
5
|
import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
|
|
5
|
-
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
6
6
|
import { getStaticTimeSegments } from "../shared/staticDateTimeSegments.js";
|
|
7
7
|
import { FormField } from "../../FormField/FormField.js";
|
|
8
8
|
import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
|
|
@@ -141,6 +141,8 @@ var TimePickerBase = (props) => {
|
|
|
141
141
|
};
|
|
142
142
|
var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
143
143
|
const ui = UIConfig.useConfig();
|
|
144
|
+
let effectiveTimeZone = getLocalTimeZone();
|
|
145
|
+
if (props.timeZone) effectiveTimeZone = props.timeZone;
|
|
144
146
|
const { locale } = useLocale();
|
|
145
147
|
const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
|
|
146
148
|
const inputRef = useRef(null);
|
|
@@ -159,13 +161,16 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
159
161
|
const rawValue = watchedValue ?? props.value ?? null;
|
|
160
162
|
const formatTimeValue = (timeValue) => {
|
|
161
163
|
if (timeValue === null) return null;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
let parsedDate;
|
|
165
|
+
if (props.date) parsedDate = DateTime.fromISO(props.date, { zone: effectiveTimeZone }).toJSDate();
|
|
166
|
+
let dateValue = now(effectiveTimeZone);
|
|
167
|
+
if (parsedDate) dateValue = DateTimeUtils.fromLocalToZonedDateTime(parsedDate, effectiveTimeZone);
|
|
168
|
+
const dateTimeValue = dateValue.set(timeValue);
|
|
169
|
+
return DateTimeUtils.fromDateValueToISO(dateTimeValue, effectiveTimeZone);
|
|
165
170
|
};
|
|
166
171
|
const parseTimeValue = (isoString) => {
|
|
167
172
|
if (isoString == null) return isoString;
|
|
168
|
-
return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString));
|
|
173
|
+
return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString, effectiveTimeZone));
|
|
169
174
|
};
|
|
170
175
|
if (!renderInput) {
|
|
171
176
|
const timeValue = rawValue ? parseTimeValue(rawValue) : null;
|
|
@@ -185,6 +190,7 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
185
190
|
isDisabled,
|
|
186
191
|
className: clsx("relative inline-flex w-full flex-col text-left", props.className),
|
|
187
192
|
inputClassName: clsx("min-w-input-width-min-width", props.inputClassName),
|
|
193
|
+
contentClassName: "pr-0!",
|
|
188
194
|
labelPlacement: "content-row",
|
|
189
195
|
dataAttributes: {
|
|
190
196
|
dataIsEmpty: timeValue === null,
|
|
@@ -198,6 +204,7 @@ var TimePicker = ({ renderStaticInput, ...props }) => {
|
|
|
198
204
|
},
|
|
199
205
|
renderStatic: true,
|
|
200
206
|
onStaticInteract: renderRealInput,
|
|
207
|
+
trailingClassName: "py-0! pl-0!",
|
|
201
208
|
trailingContent: showDropdown ? ui.dateInput.timeIcon : void 0,
|
|
202
209
|
children: staticSegments
|
|
203
210
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CalendarDate } from '@internationalized/date';
|
|
1
2
|
import { CalendarState, CalendarStateOptions } from '@react-stately/calendar';
|
|
2
3
|
import { DateValue } from 'react-aria';
|
|
3
4
|
import { DatePickerState } from 'react-stately';
|
|
@@ -17,7 +18,11 @@ type CalendarProps = DateTimeCalendarProps & {
|
|
|
17
18
|
onApply: (selectedDate?: DateValue) => void;
|
|
18
19
|
onDateSelectionChange?: (selectedDate: DateValue) => void;
|
|
19
20
|
setDateValueOnDateSelection?: boolean;
|
|
21
|
+
onMonthYearChange?: (selectedDate: CalendarDate) => void;
|
|
22
|
+
onMonthYearCommit?: () => void;
|
|
23
|
+
selectedDate?: CalendarDate | null;
|
|
24
|
+
granularity?: "day" | "month" | "year";
|
|
20
25
|
};
|
|
21
26
|
export type ToggleState = "month" | "year" | "time";
|
|
22
|
-
export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply,
|
|
27
|
+
export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity, setDateValueOnDateSelection, onDateSelectionChange, ...props }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
23
28
|
export {};
|
|
@@ -5,12 +5,77 @@ import { TimePickerForm } from "./TimePickerForm.js";
|
|
|
5
5
|
import { YearPicker } from "./YearPicker.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { clsx } from "clsx";
|
|
8
|
-
import { useCallback, useState } from "react";
|
|
8
|
+
import { useCallback, useEffect, useState } from "react";
|
|
9
9
|
import { useCalendar } from "@react-aria/calendar";
|
|
10
10
|
//#region src/components/inputs/DateTime/shared/Calendar.tsx
|
|
11
|
-
var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
|
|
12
|
-
const [toggleState, setToggleState] = useState(
|
|
11
|
+
var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity = "day", setDateValueOnDateSelection = false, onDateSelectionChange, ...props }) => {
|
|
12
|
+
const [toggleState, setToggleState] = useState(() => {
|
|
13
|
+
if (granularity === "year") return "year";
|
|
14
|
+
if (granularity === "month") return "month";
|
|
15
|
+
return null;
|
|
16
|
+
});
|
|
13
17
|
const { calendarProps, prevButtonProps, nextButtonProps } = useCalendar(props.calendarProps, props.state);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (granularity === "year" && toggleState !== "year") {
|
|
20
|
+
setToggleState("year");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (granularity === "month" && toggleState === null) {
|
|
24
|
+
setToggleState("month");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (granularity === "month" && toggleState === "time") {
|
|
28
|
+
setToggleState("month");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (granularity === "day" && toggleState === "time" && !includesTime) setToggleState(null);
|
|
32
|
+
}, [
|
|
33
|
+
granularity,
|
|
34
|
+
toggleState,
|
|
35
|
+
includesTime
|
|
36
|
+
]);
|
|
37
|
+
const onMonthSelectionChange = () => {
|
|
38
|
+
if (granularity === "day") {
|
|
39
|
+
setToggleState(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
setToggleState("month");
|
|
43
|
+
};
|
|
44
|
+
const onYearSelectionChange = () => {
|
|
45
|
+
if (granularity === "day") {
|
|
46
|
+
setToggleState(null);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (granularity === "month") {
|
|
50
|
+
setToggleState("month");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
setToggleState("year");
|
|
54
|
+
};
|
|
55
|
+
const handleHeaderMonthNavigation = (months) => {
|
|
56
|
+
if (toggleState) return;
|
|
57
|
+
if (!onMonthYearChange) return;
|
|
58
|
+
const focusedDate = props.state.focusedDate;
|
|
59
|
+
if (months === -1) {
|
|
60
|
+
onMonthYearChange(focusedDate.subtract({ months: 1 }));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
onMonthYearChange(focusedDate.add({ months: 1 }));
|
|
64
|
+
};
|
|
65
|
+
const headerPrevButtonProps = {
|
|
66
|
+
...prevButtonProps,
|
|
67
|
+
onPress: (event) => {
|
|
68
|
+
prevButtonProps.onPress?.(event);
|
|
69
|
+
handleHeaderMonthNavigation(-1);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const headerNextButtonProps = {
|
|
73
|
+
...nextButtonProps,
|
|
74
|
+
onPress: (event) => {
|
|
75
|
+
nextButtonProps.onPress?.(event);
|
|
76
|
+
handleHeaderMonthNavigation(1);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
14
79
|
const onDateSelection = useCallback((date) => {
|
|
15
80
|
if (!includesTime || !setDateValueOnDateSelection) return;
|
|
16
81
|
datePickerState.setDateValue(date);
|
|
@@ -32,18 +97,49 @@ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
|
|
|
32
97
|
if (datePickerState?.value && !setDateValueOnDateSelection) onApply(resolvedDate);
|
|
33
98
|
};
|
|
34
99
|
const getContent = () => {
|
|
35
|
-
if (!toggleState)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
100
|
+
if (!toggleState) {
|
|
101
|
+
if (granularity === "month") return /* @__PURE__ */ jsx(MonthPicker, {
|
|
102
|
+
state: props.state,
|
|
103
|
+
onSelectionChange: onMonthSelectionChange,
|
|
104
|
+
onDateChange: onMonthYearChange,
|
|
105
|
+
onCommit: onMonthYearCommit,
|
|
106
|
+
selectedDate
|
|
107
|
+
});
|
|
108
|
+
if (granularity === "year") return /* @__PURE__ */ jsx(YearPicker, {
|
|
109
|
+
state: props.state,
|
|
110
|
+
onSelectionChange: onYearSelectionChange,
|
|
111
|
+
onDateChange: onMonthYearChange,
|
|
112
|
+
onCommit: onMonthYearCommit,
|
|
113
|
+
selectedDate
|
|
114
|
+
});
|
|
115
|
+
return /* @__PURE__ */ jsx(CalendarGrid, {
|
|
116
|
+
state: props.state,
|
|
117
|
+
onApply: handleDateChange,
|
|
118
|
+
onDateSelection
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (toggleState === "month") {
|
|
122
|
+
if (granularity === "year") return /* @__PURE__ */ jsx(YearPicker, {
|
|
123
|
+
state: props.state,
|
|
124
|
+
onSelectionChange: onYearSelectionChange,
|
|
125
|
+
onDateChange: onMonthYearChange,
|
|
126
|
+
onCommit: onMonthYearCommit,
|
|
127
|
+
selectedDate
|
|
128
|
+
});
|
|
129
|
+
return /* @__PURE__ */ jsx(MonthPicker, {
|
|
130
|
+
state: props.state,
|
|
131
|
+
onSelectionChange: onMonthSelectionChange,
|
|
132
|
+
onDateChange: onMonthYearChange,
|
|
133
|
+
onCommit: onMonthYearCommit,
|
|
134
|
+
selectedDate
|
|
135
|
+
});
|
|
136
|
+
}
|
|
44
137
|
if (toggleState === "year") return /* @__PURE__ */ jsx(YearPicker, {
|
|
45
138
|
state: props.state,
|
|
46
|
-
onSelectionChange:
|
|
139
|
+
onSelectionChange: onYearSelectionChange,
|
|
140
|
+
onDateChange: onMonthYearChange,
|
|
141
|
+
onCommit: onMonthYearCommit,
|
|
142
|
+
selectedDate
|
|
47
143
|
});
|
|
48
144
|
if (toggleState === "time" && includesTime) return /* @__PURE__ */ jsx("div", {
|
|
49
145
|
className: "flex h-72 w-80 items-center justify-center",
|
|
@@ -57,10 +153,11 @@ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
|
|
|
57
153
|
children: [/* @__PURE__ */ jsx(CalendarHeader, {
|
|
58
154
|
calendarState: props.state,
|
|
59
155
|
datePickerState,
|
|
60
|
-
prevButtonProps,
|
|
61
|
-
nextButtonProps,
|
|
156
|
+
prevButtonProps: headerPrevButtonProps,
|
|
157
|
+
nextButtonProps: headerNextButtonProps,
|
|
62
158
|
includesTime,
|
|
63
159
|
hourCycle,
|
|
160
|
+
granularity,
|
|
64
161
|
toggleState,
|
|
65
162
|
setToggleState
|
|
66
163
|
}), /* @__PURE__ */ jsx("div", {
|
|
@@ -9,8 +9,9 @@ interface CalendarProps {
|
|
|
9
9
|
nextButtonProps: AriaButtonProps;
|
|
10
10
|
includesTime?: boolean;
|
|
11
11
|
hourCycle?: 12 | 24;
|
|
12
|
+
granularity?: "day" | "month" | "year";
|
|
12
13
|
toggleState: ToggleState | null;
|
|
13
14
|
setToggleState: (state: ToggleState | null) => void;
|
|
14
15
|
}
|
|
15
|
-
export declare const CalendarHeader: ({ calendarState, datePickerState, prevButtonProps, nextButtonProps, includesTime, hourCycle, toggleState, setToggleState, }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare const CalendarHeader: ({ calendarState, datePickerState, prevButtonProps, nextButtonProps, includesTime, hourCycle, granularity, toggleState, setToggleState, }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export {};
|
|
@@ -13,7 +13,7 @@ var HourCycle = {
|
|
|
13
13
|
12: "h12",
|
|
14
14
|
24: "h23"
|
|
15
15
|
};
|
|
16
|
-
var CalendarHeader = ({ calendarState, datePickerState, prevButtonProps, nextButtonProps, includesTime, hourCycle, toggleState, setToggleState }) => {
|
|
16
|
+
var CalendarHeader = ({ calendarState, datePickerState, prevButtonProps, nextButtonProps, includesTime, hourCycle, granularity = "day", toggleState, setToggleState }) => {
|
|
17
17
|
const formatter = useDateFormatter({
|
|
18
18
|
month: "long",
|
|
19
19
|
timeZone: calendarState.timeZone
|
|
@@ -43,14 +43,24 @@ var CalendarHeader = ({ calendarState, datePickerState, prevButtonProps, nextBut
|
|
|
43
43
|
/* @__PURE__ */ jsxs(ToggleButtonGroup, {
|
|
44
44
|
className: "flex gap-2",
|
|
45
45
|
children: [
|
|
46
|
-
/* @__PURE__ */ jsx(PillButton, {
|
|
46
|
+
granularity !== "year" && /* @__PURE__ */ jsx(PillButton, {
|
|
47
47
|
color: "secondary",
|
|
48
48
|
variant: "subtle",
|
|
49
49
|
iconPosition: "right",
|
|
50
50
|
icon: toggleState === "month" ? ArrowDropUpIcon : ArrowDropDownIcon,
|
|
51
51
|
toggle: true,
|
|
52
52
|
isSelected: toggleState === "month",
|
|
53
|
-
onChange: (isSelected) =>
|
|
53
|
+
onChange: (isSelected) => {
|
|
54
|
+
if (!isSelected) {
|
|
55
|
+
if (granularity === "day") {
|
|
56
|
+
setToggleState(null);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
setToggleState("month");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
setToggleState("month");
|
|
63
|
+
},
|
|
54
64
|
children: month
|
|
55
65
|
}),
|
|
56
66
|
/* @__PURE__ */ jsx(PillButton, {
|
|
@@ -60,7 +70,21 @@ var CalendarHeader = ({ calendarState, datePickerState, prevButtonProps, nextBut
|
|
|
60
70
|
icon: toggleState === "year" ? ArrowDropUpIcon : ArrowDropDownIcon,
|
|
61
71
|
toggle: true,
|
|
62
72
|
isSelected: toggleState === "year",
|
|
63
|
-
onChange: (isSelected) =>
|
|
73
|
+
onChange: (isSelected) => {
|
|
74
|
+
if (isSelected) {
|
|
75
|
+
setToggleState("year");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (granularity === "day") {
|
|
79
|
+
setToggleState(null);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (granularity === "month") {
|
|
83
|
+
setToggleState("month");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setToggleState("year");
|
|
87
|
+
},
|
|
64
88
|
children: year
|
|
65
89
|
}),
|
|
66
90
|
includesTime && /* @__PURE__ */ jsx(PillButton, {
|
|
@@ -9,6 +9,10 @@ interface DateFieldProps extends Omit<DateFieldStateOptions, "locale" | "createC
|
|
|
9
9
|
onClearChange?: (canClear: boolean) => void;
|
|
10
10
|
hidePlaceholder?: boolean;
|
|
11
11
|
disableManualEntry?: boolean;
|
|
12
|
+
dateGranularity?: "day" | "month" | "year";
|
|
13
|
+
isTimeOptional?: boolean;
|
|
14
|
+
format?: string;
|
|
15
|
+
timeZone?: string;
|
|
12
16
|
}
|
|
13
|
-
export declare const DateField: ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, ...props }: DateFieldProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare const DateField: ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, dateGranularity, isTimeOptional, format, timeZone, ...props }: DateFieldProps) => import("react/jsx-runtime").JSX.Element;
|
|
14
18
|
export {};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { DateSegmentItem } from "./DateSegmentItem.js";
|
|
2
|
-
import {
|
|
3
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
|
|
3
|
+
import { Fragment, jsx } from "react/jsx-runtime";
|
|
4
4
|
import { clsx } from "clsx";
|
|
5
|
-
import { useEffect, useImperativeHandle, useRef } from "react";
|
|
5
|
+
import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from "react";
|
|
6
6
|
import { useDateField, useLocale } from "react-aria";
|
|
7
7
|
import { createCalendar } from "@internationalized/date";
|
|
8
|
+
import { DateTime } from "luxon";
|
|
8
9
|
import { useDateFieldState } from "react-stately";
|
|
9
10
|
//#region src/components/inputs/DateTime/shared/DateField.tsx
|
|
10
|
-
var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, ...props }) => {
|
|
11
|
+
var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, dateGranularity = "day", isTimeOptional = false, format, timeZone, ...props }) => {
|
|
11
12
|
const { locale } = useLocale();
|
|
12
13
|
const state = useDateFieldState({
|
|
13
14
|
...props,
|
|
@@ -22,6 +23,20 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
|
|
|
22
23
|
isDisabled,
|
|
23
24
|
isReadOnly: disableManualEntry
|
|
24
25
|
}, state, dataFieldRef);
|
|
26
|
+
const isSegmentVisible = useCallback((segmentType) => {
|
|
27
|
+
if (dateGranularity === "day") return true;
|
|
28
|
+
if (dateGranularity === "month") return segmentType !== "day";
|
|
29
|
+
if (dateGranularity === "year") return segmentType === "year";
|
|
30
|
+
return true;
|
|
31
|
+
}, [dateGranularity]);
|
|
32
|
+
const getSegmentsToRender = useCallback(() => {
|
|
33
|
+
const segments = [];
|
|
34
|
+
for (const segment of state.segments) if (segment.type !== "literal") {
|
|
35
|
+
if (isSegmentVisible(segment.type)) segments.push(segment);
|
|
36
|
+
} else if (segments.length > 0 && segments.at(-1)?.type !== "literal") segments.push(segment);
|
|
37
|
+
return segments;
|
|
38
|
+
}, [state.segments, isSegmentVisible]);
|
|
39
|
+
const segmentsToRender = useMemo(() => getSegmentsToRender(), [getSegmentsToRender]);
|
|
25
40
|
const autoFixYear = () => {
|
|
26
41
|
const monthSegment = state.segments.find((segment) => segment.type === "month");
|
|
27
42
|
const daySegment = state.segments.find((segment) => segment.type === "day");
|
|
@@ -30,10 +45,27 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
|
|
|
30
45
|
const minuteSegment = state.segments.find((segment) => segment.type === "minute");
|
|
31
46
|
const isMonthFilled = monthSegment && !monthSegment.isPlaceholder;
|
|
32
47
|
const isDayFilled = daySegment && !daySegment.isPlaceholder;
|
|
48
|
+
const isYearFilled = yearSegment && !yearSegment.isPlaceholder && yearSegment.text?.length > 0;
|
|
33
49
|
const isYearEmpty = yearSegment && !(parseInt(yearSegment.text) && yearSegment.text?.length === 4);
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
50
|
+
const isDateFilled = isMonthFilled && isDayFilled && isYearFilled;
|
|
51
|
+
const isHourEmpty = hourSegment && (hourSegment.isPlaceholder || Number.isNaN(parseInt(hourSegment.text ?? "", 10)));
|
|
52
|
+
const isMinuteEmpty = minuteSegment && (minuteSegment.isPlaceholder || Number.isNaN(parseInt(minuteSegment.text ?? "", 10)));
|
|
53
|
+
if (!isTimeOptional && isDateFilled && minuteSegment && isMinuteEmpty) {
|
|
54
|
+
let minute = minuteSegment?.value || 0;
|
|
55
|
+
if (minuteSegment?.text?.length && minuteSegment?.text?.length > 0) {
|
|
56
|
+
minute = parseInt(minuteSegment?.text ?? "00");
|
|
57
|
+
if (isNaN(minute)) minute = 0;
|
|
58
|
+
}
|
|
59
|
+
state.setSegment("minute", minute);
|
|
60
|
+
}
|
|
61
|
+
if (!isTimeOptional && isDateFilled && hourSegment && isHourEmpty) {
|
|
62
|
+
let hour = hourSegment?.value || 0;
|
|
63
|
+
if (hourSegment?.text?.length && hourSegment?.text?.length > 0) {
|
|
64
|
+
hour = parseInt(hourSegment?.text ?? "00");
|
|
65
|
+
if (isNaN(hour)) hour = 0;
|
|
66
|
+
}
|
|
67
|
+
state.setSegment("hour", hour);
|
|
68
|
+
}
|
|
37
69
|
if (isMonthFilled && isDayFilled && isYearEmpty) {
|
|
38
70
|
let year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
39
71
|
if (yearSegment?.text?.length && yearSegment?.text?.length === 2) year = parseInt(`20${yearSegment?.text}`);
|
|
@@ -64,6 +96,26 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
|
|
|
64
96
|
useEffect(() => {
|
|
65
97
|
onClearChange?.(state.segments.some((segment) => segment.type !== "literal" && segment.isPlaceholder === false));
|
|
66
98
|
}, [state.segments, onClearChange]);
|
|
99
|
+
const getFormattedDisplayValue = () => {
|
|
100
|
+
if (!disableManualEntry) return null;
|
|
101
|
+
if (!format) return null;
|
|
102
|
+
if (!state.value) return null;
|
|
103
|
+
const jsDate = DateTimeUtils.fromDateValueToLocal(state.value, timeZone);
|
|
104
|
+
const formattedDate = DateTime.fromJSDate(jsDate);
|
|
105
|
+
if (!formattedDate.isValid) return null;
|
|
106
|
+
return formattedDate.toFormat(format);
|
|
107
|
+
};
|
|
108
|
+
const formattedDisplayValue = getFormattedDisplayValue();
|
|
109
|
+
let fieldContent = /* @__PURE__ */ jsx(Fragment, { children: segmentsToRender.map((segment, i) => /* @__PURE__ */ jsx(DateSegmentItem, {
|
|
110
|
+
segment,
|
|
111
|
+
state,
|
|
112
|
+
isDisabled,
|
|
113
|
+
hidePlaceholder
|
|
114
|
+
}, i)) });
|
|
115
|
+
if (formattedDisplayValue) fieldContent = /* @__PURE__ */ jsx("span", {
|
|
116
|
+
className: clsx("select-none", isDisabled && "text-interactive-text-secondary-disabled"),
|
|
117
|
+
children: formattedDisplayValue
|
|
118
|
+
});
|
|
67
119
|
return /* @__PURE__ */ jsx("div", {
|
|
68
120
|
...fieldProps,
|
|
69
121
|
ref: dataFieldRef,
|
|
@@ -71,12 +123,7 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
|
|
|
71
123
|
className: clsx("relative w-full", disableManualEntry && "pointer-events-none"),
|
|
72
124
|
children: /* @__PURE__ */ jsx("div", {
|
|
73
125
|
className: "flex",
|
|
74
|
-
children:
|
|
75
|
-
segment,
|
|
76
|
-
state,
|
|
77
|
-
isDisabled,
|
|
78
|
-
hidePlaceholder
|
|
79
|
-
}, i))
|
|
126
|
+
children: fieldContent
|
|
80
127
|
})
|
|
81
128
|
});
|
|
82
129
|
};
|
|
@@ -29,6 +29,10 @@ interface DatePickerInputProps extends InputVariantProps {
|
|
|
29
29
|
placeholder?: string;
|
|
30
30
|
className?: string;
|
|
31
31
|
onOpenDropdown?: () => void;
|
|
32
|
+
dateGranularity?: "day" | "month" | "year";
|
|
33
|
+
timeZone?: string;
|
|
34
|
+
isTimeOptional?: boolean;
|
|
35
|
+
format?: string;
|
|
32
36
|
}
|
|
33
|
-
export declare const DatePickerInput: ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize, todayIconPlacement, isDirty, isRequired, disableManualEntry, autoFixYear, placeholder, className, onOpenDropdown, ...props }: DatePickerInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export declare const DatePickerInput: ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize, todayIconPlacement, isDirty, isRequired, disableManualEntry, autoFixYear, placeholder, className, onOpenDropdown, dateGranularity, timeZone, isTimeOptional, format, ...props }: DatePickerInputProps) => import("react/jsx-runtime").JSX.Element;
|
|
34
38
|
export {};
|
|
@@ -15,8 +15,10 @@ import { Button } from "react-aria-components";
|
|
|
15
15
|
import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
|
|
16
16
|
import { getLocalTimeZone, now, toCalendarDateTime, today } from "@internationalized/date";
|
|
17
17
|
//#region src/components/inputs/DateTime/shared/DatePickerInput.tsx
|
|
18
|
-
var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize = "none", todayIconPlacement = "content", isDirty, isRequired, disableManualEntry, autoFixYear = false, placeholder, className, onOpenDropdown, ...props }) => {
|
|
18
|
+
var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize = "none", todayIconPlacement = "content", isDirty, isRequired, disableManualEntry, autoFixYear = false, placeholder, className, onOpenDropdown, dateGranularity = "day", timeZone, isTimeOptional = false, format, ...props }) => {
|
|
19
19
|
const uiConfig = UIConfig.useConfig();
|
|
20
|
+
let effectiveTimeZone = getLocalTimeZone();
|
|
21
|
+
if (timeZone) effectiveTimeZone = timeZone;
|
|
20
22
|
const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
|
|
21
23
|
const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
|
|
22
24
|
const datePickerInputContentRowCva = UIStyle.useCva("datePickerInput.contentRowCva", datePickerInputContentRow);
|
|
@@ -60,12 +62,12 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
|
|
|
60
62
|
};
|
|
61
63
|
const onToday = () => {
|
|
62
64
|
if (isDateTime) {
|
|
63
|
-
const calendarDateTime = toCalendarDateTime(now(
|
|
65
|
+
const calendarDateTime = toCalendarDateTime(now(effectiveTimeZone));
|
|
64
66
|
fieldProps.onChange?.(calendarDateTime);
|
|
65
67
|
if (endFieldProps) endFieldProps.onChange?.(calendarDateTime);
|
|
66
68
|
} else {
|
|
67
|
-
fieldProps.onChange?.(today(
|
|
68
|
-
if (endFieldProps) endFieldProps.onChange?.(today(
|
|
69
|
+
fieldProps.onChange?.(today(effectiveTimeZone));
|
|
70
|
+
if (endFieldProps) endFieldProps.onChange?.(today(effectiveTimeZone));
|
|
69
71
|
}
|
|
70
72
|
fieldProps.onBlur?.(null);
|
|
71
73
|
endFieldProps?.onBlur?.(null);
|
|
@@ -135,7 +137,11 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
|
|
|
135
137
|
isInvalid,
|
|
136
138
|
onClearChange,
|
|
137
139
|
hidePlaceholder,
|
|
138
|
-
disableManualEntry
|
|
140
|
+
disableManualEntry,
|
|
141
|
+
dateGranularity,
|
|
142
|
+
isTimeOptional,
|
|
143
|
+
format,
|
|
144
|
+
timeZone: effectiveTimeZone
|
|
139
145
|
}), endFieldProps && /* @__PURE__ */ jsxs(Fragment, { children: [!((as === "floating" || as === "filter") && hidePlaceholder) && /* @__PURE__ */ jsx("span", {
|
|
140
146
|
className: clsx("pointer-events-none select-none", isDisabled && "text-interactive-text-secondary-disabled"),
|
|
141
147
|
children: "–"
|
|
@@ -146,7 +152,10 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
|
|
|
146
152
|
isInvalid,
|
|
147
153
|
onClearChange,
|
|
148
154
|
hidePlaceholder,
|
|
149
|
-
disableManualEntry
|
|
155
|
+
disableManualEntry,
|
|
156
|
+
isTimeOptional,
|
|
157
|
+
format,
|
|
158
|
+
timeZone: effectiveTimeZone
|
|
150
159
|
})] })] })
|
|
151
160
|
]
|
|
152
161
|
})
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { CalendarDate } from '@internationalized/date';
|
|
1
2
|
import { CalendarState, RangeCalendarState } from '@react-stately/calendar';
|
|
2
3
|
import { Key } from 'react-aria-components';
|
|
3
4
|
export interface MonthPickerProps {
|
|
4
5
|
state: CalendarState | RangeCalendarState;
|
|
5
6
|
onSelectionChange: (key: Set<Key>) => void;
|
|
7
|
+
onDateChange?: (selectedDate: CalendarDate) => void;
|
|
8
|
+
onCommit?: () => void;
|
|
9
|
+
selectedDate?: CalendarDate | null;
|
|
6
10
|
}
|
|
7
|
-
export declare const MonthPicker: ({ state, onSelectionChange }: MonthPickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const MonthPicker: ({ state, onSelectionChange, onDateChange, onCommit, selectedDate }: MonthPickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Typography } from "../../../text/Typography/Typography.js";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { clsx } from "clsx";
|
|
4
|
+
import { useRef } from "react";
|
|
4
5
|
import { ListBox, ListBoxItem } from "react-aria-components";
|
|
5
6
|
import { useDateFormatter } from "@react-aria/i18n";
|
|
6
7
|
//#region src/components/inputs/DateTime/shared/MonthPicker.tsx
|
|
7
|
-
var MonthPicker = ({ state, onSelectionChange }) => {
|
|
8
|
+
var MonthPicker = ({ state, onSelectionChange, onDateChange, onCommit, selectedDate }) => {
|
|
8
9
|
const formatter = useDateFormatter({
|
|
9
10
|
month: "long",
|
|
10
11
|
timeZone: state.timeZone
|
|
@@ -23,34 +24,65 @@ var MonthPicker = ({ state, onSelectionChange }) => {
|
|
|
23
24
|
if (state.maxValue && state.focusedDate.set({ month }) > state.maxValue) return true;
|
|
24
25
|
return false;
|
|
25
26
|
};
|
|
27
|
+
const getSelectedMonth = () => {
|
|
28
|
+
if (!selectedDate) return null;
|
|
29
|
+
return selectedDate.month;
|
|
30
|
+
};
|
|
31
|
+
const selectedMonth = getSelectedMonth();
|
|
32
|
+
const lastPressedMonthRef = useRef(null);
|
|
33
|
+
const listBoxSelectionProps = {};
|
|
34
|
+
if (selectedMonth !== null) listBoxSelectionProps.selectedKeys = [selectedMonth];
|
|
35
|
+
const parseMonthFromKey = (key) => {
|
|
36
|
+
if (typeof key === "number") return key;
|
|
37
|
+
if (typeof key === "string") {
|
|
38
|
+
const parsedMonth = Number.parseInt(key, 10);
|
|
39
|
+
if (!Number.isNaN(parsedMonth)) return parsedMonth;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
};
|
|
26
43
|
return /* @__PURE__ */ jsx(ListBox, {
|
|
27
44
|
autoFocus: true,
|
|
28
45
|
"aria-label": "Month",
|
|
29
46
|
selectionMode: "single",
|
|
30
47
|
layout: "grid",
|
|
31
|
-
|
|
48
|
+
...listBoxSelectionProps,
|
|
32
49
|
onSelectionChange: (key) => {
|
|
33
50
|
if (key === "all") return;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
const selectedKey = [...key][0];
|
|
52
|
+
const selectedMonthValue = parseMonthFromKey(selectedKey);
|
|
53
|
+
if (selectedMonthValue !== null) {
|
|
54
|
+
const nextSelectedDate = state.focusedDate.set({ month: selectedMonthValue });
|
|
55
|
+
state.setFocusedDate(nextSelectedDate);
|
|
56
|
+
onDateChange?.(nextSelectedDate);
|
|
37
57
|
}
|
|
38
58
|
onSelectionChange(key);
|
|
39
59
|
},
|
|
40
60
|
className: "grid size-full min-h-72 grid-cols-3 grid-rows-4 gap-2 p-3 md:w-80",
|
|
41
61
|
children: getMonths().map((month, index) => {
|
|
42
|
-
const
|
|
62
|
+
const monthNumber = index + 1;
|
|
63
|
+
const isDisabled = isMonthDisabled(monthNumber);
|
|
43
64
|
return /* @__PURE__ */ jsx(ListBoxItem, {
|
|
44
|
-
id:
|
|
65
|
+
id: monthNumber,
|
|
45
66
|
textValue: month,
|
|
46
67
|
isDisabled,
|
|
68
|
+
onPress: () => {
|
|
69
|
+
const isSecondConsecutivePress = lastPressedMonthRef.current === monthNumber;
|
|
70
|
+
lastPressedMonthRef.current = monthNumber;
|
|
71
|
+
const nextSelectedDate = state.focusedDate.set({ month: monthNumber });
|
|
72
|
+
state.setFocusedDate(nextSelectedDate);
|
|
73
|
+
onDateChange?.(nextSelectedDate);
|
|
74
|
+
if (!isSecondConsecutivePress) return;
|
|
75
|
+
if (selectedMonth === null) return;
|
|
76
|
+
if (monthNumber !== selectedMonth) return;
|
|
77
|
+
onCommit?.();
|
|
78
|
+
},
|
|
47
79
|
className: clsx("flex items-center justify-center text-interactive-text-secondary-idle", "rounded-button-rounding-m border border-elevation-outline-default-1 border-solid bg-elevation-fill-default-1", "hover:text-interactive-text-secondary-hover", "selected:border-interactive-contained-primary-idle selected:bg-interactive-contained-primary-idle selected:text-interactive-text-secondary-idle-inverted", "focus:outline-none focus-visible:outline-1 focus-visible:outline-interactive-contained-primary-focus focus-visible:outline-offset-1", isDisabled ? "cursor-default opacity-50" : "cursor-pointer"),
|
|
48
80
|
children: /* @__PURE__ */ jsx(Typography, {
|
|
49
81
|
as: "span",
|
|
50
82
|
size: "label-2",
|
|
51
83
|
children: month
|
|
52
84
|
})
|
|
53
|
-
},
|
|
85
|
+
}, monthNumber);
|
|
54
86
|
})
|
|
55
87
|
});
|
|
56
88
|
};
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { CalendarDate } from '@internationalized/date';
|
|
1
2
|
import { CalendarState, RangeCalendarState } from '@react-stately/calendar';
|
|
2
3
|
import { Key } from 'react-aria-components';
|
|
3
4
|
interface YearPickerProps {
|
|
4
5
|
state: CalendarState | RangeCalendarState;
|
|
5
6
|
onSelectionChange: (key: Set<Key>) => void;
|
|
7
|
+
onDateChange?: (selectedDate: CalendarDate) => void;
|
|
8
|
+
onCommit?: () => void;
|
|
9
|
+
selectedDate?: CalendarDate | null;
|
|
6
10
|
}
|
|
7
|
-
export declare const YearPicker: ({ state, onSelectionChange }: YearPickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const YearPicker: ({ state, onSelectionChange, onDateChange, onCommit, selectedDate }: YearPickerProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
12
|
export {};
|