@povio/ui 2.2.9-rc.9 → 2.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/components/buttons/Button/Button.d.ts +2 -2
  2. package/dist/components/buttons/Button/Button.js +1 -1
  3. package/dist/components/buttons/PillButton/PillButton.d.ts +2 -2
  4. package/dist/components/buttons/PillButton/PillButton.js +1 -1
  5. package/dist/components/buttons/TextButton/TextButton.d.ts +2 -1
  6. package/dist/components/buttons/ToggleButton/ToggleButton.d.ts +2 -1
  7. package/dist/components/buttons/shared/ButtonContent.d.ts +3 -3
  8. package/dist/components/buttons/shared/ButtonContent.js +2 -2
  9. package/dist/components/inputs/Checkbox/Checkbox.js +1 -6
  10. package/dist/components/inputs/Checkbox/checkbox.cva.d.ts +0 -3
  11. package/dist/components/inputs/Checkbox/checkbox.cva.js +1 -2
  12. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +9 -8
  13. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +82 -35
  14. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +4 -7
  15. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +5 -15
  16. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +8 -7
  17. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +42 -23
  18. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +3 -3
  19. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +14 -21
  20. package/dist/components/inputs/DateTime/shared/Calendar.d.ts +6 -1
  21. package/dist/components/inputs/DateTime/shared/Calendar.js +85 -12
  22. package/dist/components/inputs/DateTime/shared/CalendarHeader.d.ts +2 -1
  23. package/dist/components/inputs/DateTime/shared/CalendarHeader.js +28 -4
  24. package/dist/components/inputs/DateTime/shared/DateField.d.ts +5 -1
  25. package/dist/components/inputs/DateTime/shared/DateField.js +54 -14
  26. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +7 -5
  27. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +20 -18
  28. package/dist/components/inputs/DateTime/shared/MonthPicker.d.ts +5 -1
  29. package/dist/components/inputs/DateTime/shared/MonthPicker.js +40 -8
  30. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +1 -2
  31. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +2 -7
  32. package/dist/components/inputs/DateTime/shared/YearPicker.d.ts +5 -1
  33. package/dist/components/inputs/DateTime/shared/YearPicker.js +42 -8
  34. package/dist/components/inputs/FormField/FormFieldHeader.js +1 -3
  35. package/dist/components/inputs/Input/NumberInput/NumberInput.js +0 -1
  36. package/dist/components/inputs/Input/TextInput/TextInput.js +0 -3
  37. package/dist/components/inputs/Inputs/InputItem.d.ts +16 -10
  38. package/dist/components/inputs/Inputs/InputItem.js +0 -4
  39. package/dist/components/inputs/RadioGroup/RadioGroup.js +1 -6
  40. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +0 -3
  41. package/dist/components/inputs/RadioGroup/radio.cva.js +1 -2
  42. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +1 -3
  43. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +3 -4
  44. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +18 -3
  45. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +7 -23
  46. package/dist/components/inputs/Selection/Select/Select.d.ts +2 -4
  47. package/dist/components/inputs/Selection/Select/Select.js +3 -4
  48. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +1 -8
  49. package/dist/components/inputs/Selection/shared/SelectBase.js +1 -3
  50. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  51. package/dist/components/inputs/Selection/shared/SelectDesktop.js +2 -8
  52. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  53. package/dist/components/inputs/Selection/shared/SelectInput.js +3 -23
  54. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  55. package/dist/components/inputs/Selection/shared/SelectMobile.js +5 -10
  56. package/dist/components/inputs/Selection/shared/select.context.d.ts +2 -3
  57. package/dist/components/inputs/Selection/shared/select.context.js +4 -22
  58. package/dist/components/inputs/Selection/shared/select.types.d.ts +2 -2
  59. package/dist/components/inputs/TextEditor/TextEditor.d.ts +0 -1
  60. package/dist/components/inputs/TextEditor/TextEditor.js +3 -7
  61. package/dist/components/inputs/Toggle/Toggle.js +1 -6
  62. package/dist/components/inputs/Toggle/toggle.cva.d.ts +0 -3
  63. package/dist/components/inputs/Toggle/toggle.cva.js +1 -2
  64. package/dist/components/inputs/shared/CheckContent.d.ts +1 -2
  65. package/dist/components/inputs/shared/CheckContent.js +4 -3
  66. package/dist/components/overlays/BottomSheet/BottomSheet.js +1 -2
  67. package/dist/components/overlays/Tooltip/TooltipEllipsis.d.ts +2 -2
  68. package/dist/config/link.context.js +4 -2
  69. package/dist/config/uiConfig.context.d.ts +2 -8
  70. package/dist/config/uiConfig.context.js +3 -5
  71. package/dist/config/uiStyle.context.d.ts +1 -6
  72. package/dist/helpers/dynamicInputs.d.ts +5 -5
  73. package/dist/helpers/dynamicInputs.js +0 -3
  74. package/dist/index.d.ts +0 -4
  75. package/dist/index.js +4 -5
  76. package/dist/utils/date-time.utils.d.ts +7 -6
  77. package/dist/utils/date-time.utils.js +66 -16
  78. package/package.json +1 -1
  79. package/dist/components/inputs/DateTime/shared/datePicker.types.d.ts +0 -3
  80. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +0 -6
  81. package/dist/components/inputs/FormField/formFieldHeader.cva.js +0 -11
  82. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +0 -30
  83. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +0 -14
  84. package/dist/components/inputs/Selection/Select/QuerySelect.js +0 -56
  85. package/dist/components/inputs/Selection/shared/querySelect.utils.d.ts +0 -6
  86. package/dist/components/inputs/Selection/shared/querySelect.utils.js +0 -13
  87. package/dist/hooks/useQueryAutocomplete.d.ts +0 -25
  88. package/dist/hooks/useQueryAutocomplete.js +0 -41
@@ -1,12 +1,11 @@
1
1
  import { UIConfig } from "../../../../config/uiConfig.context.js";
2
2
  import { Calendar } from "../shared/Calendar.js";
3
+ import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
3
4
  import { DatePickerInput } from "../shared/DatePickerInput.js";
4
5
  import { DateTimeDialog } from "../shared/DateTimeDialog.js";
5
6
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
6
7
  import { FormField } from "../../FormField/FormField.js";
7
8
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
- import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
9
- import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
10
9
  import { jsx, jsxs } from "react/jsx-runtime";
11
10
  import { useEffect, useImperativeHandle, useMemo, useRef } from "react";
12
11
  import { useDatePicker, useLocale } from "react-aria";
@@ -17,7 +16,9 @@ import { useCalendarState, useDatePickerState } from "react-stately";
17
16
  //#region src/components/inputs/DateTime/DateTimePicker/DateTimePicker.tsx
18
17
  var DateTimePickerBase = (props) => {
19
18
  const ui = UIConfig.useConfig();
20
- const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, onBlur, value, disableDropdown, isTimeOptional, placeholder, inputClassName, hideLabel = ui.input.hideLabel, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, isClearable = ui.input.isClearable, todayIcon = ui.dateInput.todayIcon, todayIconButtonSize = ui.dateInput.todayIconButtonSize, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, autoFixYear = ui.dateInput.autoFixYear, ...rest } = props;
19
+ const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, isTimeOptional, placeholder, inputClassName, hideLabel = ui.input.hideLabel, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, isClearable = ui.input.isClearable, todayIcon = ui.dateInput.todayIcon, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, shouldUpdateDateOnMonthYearChange = ui.dateInput.shouldUpdateDateOnMonthYearChange, timeZone, autoFixYear = ui.dateInput.autoFixYear, format, ...rest } = props;
20
+ let effectiveTimeZone = getLocalTimeZone();
21
+ if (timeZone) effectiveTimeZone = timeZone;
21
22
  const formFieldProps = {
22
23
  error,
23
24
  label,
@@ -38,10 +39,6 @@ var DateTimePickerBase = (props) => {
38
39
  useImperativeHandle(ref, () => ({ clear: () => {
39
40
  datePickerInputRef.current?.clear();
40
41
  } }));
41
- const handleBlur = (val) => {
42
- onBlur?.({ target: { value: val } });
43
- };
44
- const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
45
42
  const dialogState = useDatePickerState({
46
43
  ...rest,
47
44
  defaultValue: value || rest.defaultValue,
@@ -60,8 +57,7 @@ var DateTimePickerBase = (props) => {
60
57
  onChange: (val) => {
61
58
  onChange?.(val);
62
59
  dialogState.setValue(val);
63
- calendarState.setFocusedDate(val || today(getLocalTimeZone()));
64
- debouncedBlur(val);
60
+ calendarState.setFocusedDate(val || today(effectiveTimeZone));
65
61
  },
66
62
  shouldCloseOnSelect: false,
67
63
  granularity: "minute",
@@ -97,24 +93,41 @@ var DateTimePickerBase = (props) => {
97
93
  labelProps
98
94
  };
99
95
  const onApply = () => {
100
- const newValue = dialogState.value;
101
- state.setValue(newValue);
96
+ state.setValue(dialogState.value);
102
97
  state.toggle();
103
- handleBlur(newValue);
98
+ };
99
+ const onMonthYearChange = (selectedDate) => {
100
+ if (!shouldUpdateDateOnMonthYearChange) return;
101
+ const baseDate = dialogState.value || state.value;
102
+ if (baseDate) {
103
+ const updatedDate = baseDate.set({
104
+ year: selectedDate.year,
105
+ month: selectedDate.month
106
+ });
107
+ dialogState.setValue(updatedDate);
108
+ calendarState.setFocusedDate(updatedDate);
109
+ return;
110
+ }
111
+ dialogState.setValue(toCalendarDateTime(selectedDate));
112
+ calendarState.setFocusedDate(selectedDate);
104
113
  };
105
114
  const onTodayPress = () => {
106
- dialogState.setValue(toCalendarDateTime(now(getLocalTimeZone())));
107
- calendarState.setFocusedDate(today(getLocalTimeZone()));
115
+ dialogState.setValue(toCalendarDateTime(now(effectiveTimeZone)));
116
+ calendarState.setFocusedDate(today(effectiveTimeZone));
108
117
  };
109
118
  const onOpenChange = (isOpen) => {
110
119
  state.toggle();
111
- calendarState.setFocusedDate(state.value || today(getLocalTimeZone()));
120
+ calendarState.setFocusedDate(state.value || today(effectiveTimeZone));
112
121
  if (!isOpen) dialogState.setValue(state.value);
113
122
  };
114
123
  const onInputBlur = (e) => {
115
124
  if (!isTimeOptional) return;
125
+ if (state.value) {
126
+ dialogState.setValue(state.value);
127
+ return;
128
+ }
116
129
  const textValue = e.currentTarget.textContent;
117
- const dateTimeValue = DateTimeUtils.formatTextDateToCalendarDateTime(textValue);
130
+ const dateTimeValue = DateTimeUtils.formatTextDateToCalendarDateTime(textValue, effectiveTimeZone, locale);
118
131
  if (dateTimeValue) {
119
132
  state.setValue(dateTimeValue);
120
133
  dialogState.setValue(dateTimeValue);
@@ -153,13 +166,15 @@ var DateTimePickerBase = (props) => {
153
166
  isClearable,
154
167
  headerProps,
155
168
  todayIcon,
156
- todayIconButtonSize,
157
169
  isRequired,
158
170
  disableManualEntry,
159
- autoFixYear,
160
171
  placeholder,
161
172
  onOpenDropdown: () => state.toggle(),
162
- className: inputClassName
173
+ className: inputClassName,
174
+ timeZone: effectiveTimeZone,
175
+ autoFixYear,
176
+ isTimeOptional,
177
+ format
163
178
  }), (!disableDropdown || disableManualEntry) && /* @__PURE__ */ jsx(DateTimeDialog, {
164
179
  footer: /* @__PURE__ */ jsx(DateTimeDialogFooter, {
165
180
  isDisabled,
@@ -177,21 +192,25 @@ var DateTimePickerBase = (props) => {
177
192
  calendarProps,
178
193
  includesTime: true,
179
194
  datePickerState: dialogState,
180
- onApply
195
+ onApply,
196
+ onMonthYearChange,
197
+ granularity: "day"
181
198
  })
182
199
  })]
183
200
  })
184
201
  });
185
202
  };
186
203
  var DateTimePicker = ({ fullIso = true, ...props }) => {
204
+ let effectiveTimeZone = getLocalTimeZone();
205
+ if (props.timeZone) effectiveTimeZone = props.timeZone;
187
206
  const formatDateValue = (dateValue) => {
188
207
  if (dateValue === null) return null;
189
- if (fullIso) return DateTimeUtils.fromCalendarDateTimeToUTCISO(dateValue);
190
- return DateTimeUtils.fromDateValueToISO(dateValue);
208
+ if (fullIso) return DateTimeUtils.fromDateValueToISO(dateValue, effectiveTimeZone);
209
+ return DateTimeUtils.fromDateValueToISO(dateValue, effectiveTimeZone);
191
210
  };
192
211
  const parseDateValue = (isoString) => {
193
212
  if (isoString == null) return isoString;
194
- return DateTimeUtils.fromUTCISOToCalendarDateTime(isoString);
213
+ return DateTimeUtils.fromUTCISOToCalendarDateTime(isoString, effectiveTimeZone);
195
214
  };
196
215
  if ("formControl" in props && props.formControl) {
197
216
  const { formControl, ref, ...innerProps } = props;
@@ -1,10 +1,10 @@
1
- import { Ref, FocusEvent } from 'react';
1
+ import { Ref } from 'react';
2
2
  import { AriaTimeFieldProps, TimeValue } from 'react-aria';
3
3
  import { FieldValues } from 'react-hook-form';
4
4
  import { FormFieldProps } from '../../FormField/FormField';
5
5
  import { ControlProps } from '../../shared/form.types';
6
6
  import { InputVariantProps } from '../../shared/input.cva';
7
- interface TimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<AriaTimeFieldProps<TimeValue>, "label" | "onBlur"> {
7
+ interface TimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<AriaTimeFieldProps<TimeValue>, "label"> {
8
8
  ref?: Ref<HTMLDivElement>;
9
9
  disableDropdown?: boolean;
10
10
  date?: string | null;
@@ -13,12 +13,12 @@ interface TimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<Ar
13
13
  disableManualEntry?: boolean;
14
14
  placeholder?: string;
15
15
  inputClassName?: string;
16
- onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
17
16
  }
18
17
  export interface TimePickerProps extends Omit<TimePickerBaseProps, "value" | "onChange"> {
19
18
  value?: string | null;
20
19
  onChange?: (value: string | null) => void;
21
20
  fullIso?: boolean;
21
+ timeZone?: string;
22
22
  }
23
23
  export type ControlledTimePickerProps<TFieldValues extends FieldValues> = ControlProps<TimePickerProps, TFieldValues>;
24
24
  export declare const TimePicker: <TFieldValues extends FieldValues>(props: ControlledTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
@@ -1,11 +1,10 @@
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
6
  import { FormField } from "../../FormField/FormField.js";
6
7
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
7
- import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
8
- import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
9
8
  import { TimePickerInput } from "../shared/TimePickerInput.js";
10
9
  import { jsx, jsxs } from "react/jsx-runtime";
11
10
  import { clsx } from "clsx";
@@ -19,7 +18,7 @@ import { useTimeFieldState } from "react-stately";
19
18
  //#region src/components/inputs/DateTime/TimePicker/TimePicker.tsx
20
19
  var TimePickerBase = (props) => {
21
20
  const ui = UIConfig.useConfig();
22
- const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, onBlur, value, disableDropdown, placeholder, className, inputClassName, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, hideLabel = ui.input.hideLabel, isClearable = ui.input.isClearable, disableManualEntry = ui.dateInput.disableManualEntry, ...rest } = props;
21
+ const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, placeholder, className, inputClassName, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, hideLabel = ui.input.hideLabel, isClearable = ui.input.isClearable, disableManualEntry = ui.dateInput.disableManualEntry, ...rest } = props;
23
22
  const formFieldProps = {
24
23
  error,
25
24
  label,
@@ -41,18 +40,11 @@ var TimePickerBase = (props) => {
41
40
  defaultValue: value || rest.defaultValue,
42
41
  locale
43
42
  });
44
- const handleBlur = (val) => {
45
- onBlur?.({ target: { value: val } });
46
- };
47
- const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
48
43
  const state = useTimeFieldState({
49
44
  ...rest,
50
45
  isDisabled,
51
46
  value,
52
- onChange: (val) => {
53
- onChange?.(val);
54
- debouncedBlur(val);
55
- },
47
+ onChange,
56
48
  locale
57
49
  });
58
50
  useEffect(() => {
@@ -80,10 +72,8 @@ var TimePickerBase = (props) => {
80
72
  labelProps
81
73
  };
82
74
  const onApply = () => {
83
- const newValue = dialogState.value;
84
- state.setValue(newValue);
75
+ state.setValue(dialogState.value);
85
76
  setIsOpen(false);
86
- handleBlur(newValue);
87
77
  };
88
78
  const onOpenChange = (open) => {
89
79
  setIsOpen(open);
@@ -111,7 +101,6 @@ var TimePickerBase = (props) => {
111
101
  onPress: onOpen,
112
102
  isDisabled,
113
103
  isDirty,
114
- isRequired,
115
104
  isInvalid: !!error,
116
105
  disableDropdown,
117
106
  variant,
@@ -137,28 +126,32 @@ var TimePickerBase = (props) => {
137
126
  });
138
127
  };
139
128
  var TimePicker = (props) => {
129
+ let effectiveTimeZone = getLocalTimeZone();
130
+ if (props.timeZone) effectiveTimeZone = props.timeZone;
140
131
  const formatTimeValue = (timeValue) => {
141
132
  if (timeValue === null) return null;
142
- const parsedDate = props.date ? DateTime.fromISO(props.date).toJSDate() : void 0;
143
- const dateTimeValue = (parsedDate ? DateTimeUtils.fromLocalToZonedDateTime(parsedDate) : now(getLocalTimeZone())).set(timeValue);
144
- return DateTimeUtils.fromDateValueToISO(dateTimeValue);
133
+ let parsedDate;
134
+ if (props.date) parsedDate = DateTime.fromISO(props.date, { zone: effectiveTimeZone }).toJSDate();
135
+ let dateValue = now(effectiveTimeZone);
136
+ if (parsedDate) dateValue = DateTimeUtils.fromLocalToZonedDateTime(parsedDate, effectiveTimeZone);
137
+ const dateTimeValue = dateValue.set(timeValue);
138
+ return DateTimeUtils.fromDateValueToISO(dateTimeValue, effectiveTimeZone);
145
139
  };
146
140
  const parseTimeValue = (isoString) => {
147
141
  if (isoString == null) return isoString;
148
- return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString));
142
+ return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString, effectiveTimeZone));
149
143
  };
150
144
  if ("formControl" in props && props.formControl) {
151
145
  const { formControl, ref, ...innerProps } = props;
152
146
  return /* @__PURE__ */ jsx(Controller, {
153
147
  control: formControl.control,
154
148
  name: formControl.name,
155
- render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TimePickerBase, {
149
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(TimePickerBase, {
156
150
  ...innerProps,
157
151
  ref: mergeRefs(ref, field.ref),
158
152
  value: parseTimeValue(field.value),
159
153
  onChange: (value) => field.onChange(formatTimeValue(value)),
160
154
  onBlur: field.onBlur,
161
- isDirty,
162
155
  isDisabled: field.disabled || props.isDisabled,
163
156
  error: props.error ?? error?.message
164
157
  })
@@ -1,3 +1,4 @@
1
+ import { CalendarDate } from '@internationalized/date';
1
2
  import { CalendarState, CalendarStateOptions } from '@react-stately/calendar';
2
3
  import { DatePickerState } from 'react-stately';
3
4
  type DateTimeCalendarProps = {
@@ -14,7 +15,11 @@ type CalendarProps = DateTimeCalendarProps & {
14
15
  state: CalendarState;
15
16
  calendarProps: Omit<CalendarStateOptions, "locale" | "createCalendar">;
16
17
  onApply: () => void;
18
+ onMonthYearChange?: (selectedDate: CalendarDate) => void;
19
+ onMonthYearCommit?: () => void;
20
+ selectedDate?: CalendarDate | null;
21
+ granularity?: "day" | "month" | "year";
17
22
  };
18
23
  export type ToggleState = "month" | "year" | "time";
19
- export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply, ...props }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
24
+ export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity, ...props }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
20
25
  export {};
@@ -5,28 +5,100 @@ 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 { useState } from "react";
8
+ import { 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, ...props }) => {
12
- const [toggleState, setToggleState] = useState(null);
11
+ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity = "day", ...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
+ };
14
55
  const handleDateChange = () => {
15
56
  if (includesTime && !datePickerState.value) setToggleState("time");
16
57
  else onApply();
17
58
  };
18
59
  const getContent = () => {
19
- if (!toggleState) return /* @__PURE__ */ jsx(CalendarGrid, {
20
- state: props.state,
21
- onApply: handleDateChange
22
- });
23
- if (toggleState === "month") return /* @__PURE__ */ jsx(MonthPicker, {
24
- state: props.state,
25
- onSelectionChange: () => setToggleState(null)
26
- });
60
+ if (!toggleState) {
61
+ if (granularity === "month") return /* @__PURE__ */ jsx(MonthPicker, {
62
+ state: props.state,
63
+ onSelectionChange: onMonthSelectionChange,
64
+ onDateChange: onMonthYearChange,
65
+ onCommit: onMonthYearCommit,
66
+ selectedDate
67
+ });
68
+ if (granularity === "year") return /* @__PURE__ */ jsx(YearPicker, {
69
+ state: props.state,
70
+ onSelectionChange: onYearSelectionChange,
71
+ onDateChange: onMonthYearChange,
72
+ onCommit: onMonthYearCommit,
73
+ selectedDate
74
+ });
75
+ return /* @__PURE__ */ jsx(CalendarGrid, {
76
+ state: props.state,
77
+ onApply: handleDateChange
78
+ });
79
+ }
80
+ if (toggleState === "month") {
81
+ if (granularity === "year") return /* @__PURE__ */ jsx(YearPicker, {
82
+ state: props.state,
83
+ onSelectionChange: onYearSelectionChange,
84
+ onDateChange: onMonthYearChange,
85
+ onCommit: onMonthYearCommit,
86
+ selectedDate
87
+ });
88
+ return /* @__PURE__ */ jsx(MonthPicker, {
89
+ state: props.state,
90
+ onSelectionChange: onMonthSelectionChange,
91
+ onDateChange: onMonthYearChange,
92
+ onCommit: onMonthYearCommit,
93
+ selectedDate
94
+ });
95
+ }
27
96
  if (toggleState === "year") return /* @__PURE__ */ jsx(YearPicker, {
28
97
  state: props.state,
29
- onSelectionChange: () => setToggleState(null)
98
+ onSelectionChange: onYearSelectionChange,
99
+ onDateChange: onMonthYearChange,
100
+ onCommit: onMonthYearCommit,
101
+ selectedDate
30
102
  });
31
103
  if (toggleState === "time" && includesTime) return /* @__PURE__ */ jsx("div", {
32
104
  className: "flex h-72 w-80 items-center justify-center",
@@ -44,6 +116,7 @@ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
44
116
  nextButtonProps,
45
117
  includesTime,
46
118
  hourCycle,
119
+ granularity,
47
120
  toggleState,
48
121
  setToggleState
49
122
  }), /* @__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) => setToggleState(isSelected ? "month" : null),
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) => setToggleState(isSelected ? "year" : null),
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,12 +1,14 @@
1
1
  import { DateSegmentItem } from "./DateSegmentItem.js";
2
- import { jsx } from "react/jsx-runtime";
2
+ import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
3
+ import { Fragment, jsx } from "react/jsx-runtime";
3
4
  import { clsx } from "clsx";
4
- import { useEffect, useImperativeHandle, useRef } from "react";
5
+ import { useCallback, useEffect, useImperativeHandle, useMemo, useRef } from "react";
5
6
  import { useDateField, useLocale } from "react-aria";
6
7
  import { createCalendar } from "@internationalized/date";
8
+ import { DateTime } from "luxon";
7
9
  import { useDateFieldState } from "react-stately";
8
10
  //#region src/components/inputs/DateTime/shared/DateField.tsx
9
- var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, ...props }) => {
11
+ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManualEntry, dateGranularity = "day", isTimeOptional = false, format, timeZone, ...props }) => {
10
12
  const { locale } = useLocale();
11
13
  const state = useDateFieldState({
12
14
  ...props,
@@ -21,6 +23,20 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
21
23
  isDisabled,
22
24
  isReadOnly: disableManualEntry
23
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]);
24
40
  const autoFixYear = () => {
25
41
  const monthSegment = state.segments.find((segment) => segment.type === "month");
26
42
  const daySegment = state.segments.find((segment) => segment.type === "day");
@@ -29,16 +45,25 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
29
45
  const minuteSegment = state.segments.find((segment) => segment.type === "minute");
30
46
  const isMonthFilled = monthSegment && !monthSegment.isPlaceholder;
31
47
  const isDayFilled = daySegment && !daySegment.isPlaceholder;
48
+ const isYearFilled = yearSegment && !yearSegment.isPlaceholder && yearSegment.text?.length > 0;
32
49
  const isYearEmpty = yearSegment && !(parseInt(yearSegment.text) && yearSegment.text?.length === 4);
33
- const isHourEmpty = hourSegment && !parseInt(hourSegment.text);
34
- if (minuteSegment && !parseInt(minuteSegment.text)) {
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) {
35
54
  let minute = minuteSegment?.value || 0;
36
- if (minuteSegment?.text?.length && minuteSegment?.text?.length > 0) minute = parseInt(minuteSegment?.text ?? "00");
55
+ if (minuteSegment?.text?.length && minuteSegment?.text?.length > 0) {
56
+ minute = parseInt(minuteSegment?.text ?? "00");
57
+ if (isNaN(minute)) minute = 0;
58
+ }
37
59
  state.setSegment("minute", minute);
38
60
  }
39
- if (isHourEmpty) {
61
+ if (!isTimeOptional && isDateFilled && hourSegment && isHourEmpty) {
40
62
  let hour = hourSegment?.value || 0;
41
- if (hourSegment?.text?.length && hourSegment?.text?.length > 0) hour = parseInt(hourSegment?.text ?? "00");
63
+ if (hourSegment?.text?.length && hourSegment?.text?.length > 0) {
64
+ hour = parseInt(hourSegment?.text ?? "00");
65
+ if (isNaN(hour)) hour = 0;
66
+ }
42
67
  state.setSegment("hour", hour);
43
68
  }
44
69
  if (isMonthFilled && isDayFilled && isYearEmpty) {
@@ -71,6 +96,26 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
71
96
  useEffect(() => {
72
97
  onClearChange?.(state.segments.some((segment) => segment.type !== "literal" && segment.isPlaceholder === false));
73
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
+ });
74
119
  return /* @__PURE__ */ jsx("div", {
75
120
  ...fieldProps,
76
121
  ref: dataFieldRef,
@@ -78,12 +123,7 @@ var DateField = ({ ref, onClearChange, hidePlaceholder, isDisabled, disableManua
78
123
  className: clsx("relative w-full", disableManualEntry && "pointer-events-none"),
79
124
  children: /* @__PURE__ */ jsx("div", {
80
125
  className: "flex",
81
- children: state.segments.map((segment, i) => /* @__PURE__ */ jsx(DateSegmentItem, {
82
- segment,
83
- state,
84
- isDisabled,
85
- hidePlaceholder
86
- }, i))
126
+ children: fieldContent
87
127
  })
88
128
  });
89
129
  };
@@ -1,6 +1,5 @@
1
1
  import { Ref } from 'react';
2
2
  import { DatePickerAria } from 'react-aria';
3
- import { DatePickerTodayIcon, DatePickerTodayIconButtonSize } from './datePicker.types';
4
3
  import { FormFieldHeaderProps } from '../../FormField/FormFieldHeader';
5
4
  import { InputVariantProps } from '../../shared/input.cva';
6
5
  export interface DatePickerInputHandle {
@@ -19,15 +18,18 @@ interface DatePickerInputProps extends InputVariantProps {
19
18
  isDateTime?: boolean;
20
19
  isClearable?: boolean;
21
20
  headerProps?: FormFieldHeaderProps;
22
- todayIcon?: DatePickerTodayIcon;
23
- todayIconButtonSize?: DatePickerTodayIconButtonSize;
21
+ todayIcon?: boolean;
24
22
  isDirty?: boolean;
25
23
  isRequired?: boolean;
26
24
  disableManualEntry?: boolean;
27
- autoFixYear?: boolean;
28
25
  placeholder?: string;
29
26
  className?: string;
30
27
  onOpenDropdown?: () => void;
28
+ dateGranularity?: "day" | "month" | "year";
29
+ timeZone?: string;
30
+ autoFixYear?: boolean;
31
+ isTimeOptional?: boolean;
32
+ format?: string;
31
33
  }
32
- export declare const DatePickerInput: ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize, isDirty, isRequired, disableManualEntry, autoFixYear, placeholder, className, onOpenDropdown, ...props }: DatePickerInputProps) => import("react/jsx-runtime").JSX.Element;
34
+ export declare const DatePickerInput: ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, isDirty, isRequired, disableManualEntry, placeholder, className, onOpenDropdown, dateGranularity, timeZone, autoFixYear, isTimeOptional, format, ...props }: DatePickerInputProps) => import("react/jsx-runtime").JSX.Element;
33
35
  export {};