@povio/ui 2.2.12 → 2.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/components/buttons/InlineIconButton/InlineIconButton.d.ts +2 -1
  2. package/dist/components/buttons/InlineIconButton/InlineIconButton.js +2 -2
  3. package/dist/components/inputs/Checkbox/Checkbox.js +6 -1
  4. package/dist/components/inputs/Checkbox/checkbox.cva.d.ts +3 -0
  5. package/dist/components/inputs/Checkbox/checkbox.cva.js +2 -1
  6. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +10 -5
  7. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +89 -9
  8. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +10 -5
  9. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +95 -7
  10. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +11 -5
  11. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +95 -9
  12. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +5 -3
  13. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +77 -7
  14. package/dist/components/inputs/DateTime/shared/Calendar.d.ts +5 -2
  15. package/dist/components/inputs/DateTime/shared/Calendar.js +23 -6
  16. package/dist/components/inputs/DateTime/shared/CalendarCell.d.ts +1 -1
  17. package/dist/components/inputs/DateTime/shared/CalendarCell.js +3 -3
  18. package/dist/components/inputs/DateTime/shared/CalendarGrid.d.ts +1 -1
  19. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +6 -3
  20. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +78 -61
  21. package/dist/components/inputs/DateTime/shared/DateSegmentItem.d.ts +14 -0
  22. package/dist/components/inputs/DateTime/shared/DateSegmentItem.js +19 -6
  23. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +2 -1
  24. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +11 -4
  25. package/dist/components/inputs/DateTime/shared/datePicker.types.d.ts +4 -0
  26. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.d.ts +7 -0
  27. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.js +13 -0
  28. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.d.ts +6 -0
  29. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.js +21 -0
  30. package/dist/components/inputs/DateTime/shared/dateSegment.utils.d.ts +2 -0
  31. package/dist/components/inputs/DateTime/shared/dateSegment.utils.spec.d.ts +1 -0
  32. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.d.ts +35 -0
  33. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.js +80 -0
  34. package/dist/components/inputs/File/FileUpload.js +1 -0
  35. package/dist/components/inputs/File/shared/InputUploadContent.js +1 -0
  36. package/dist/components/inputs/FormField/FormField.d.ts +3 -3
  37. package/dist/components/inputs/FormField/FormFieldHeader.d.ts +2 -2
  38. package/dist/components/inputs/FormField/FormFieldHeader.js +3 -1
  39. package/dist/components/inputs/FormField/FormFieldLabel.d.ts +2 -2
  40. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +6 -0
  41. package/dist/components/inputs/FormField/formFieldHeader.cva.js +11 -0
  42. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +5 -2
  43. package/dist/components/inputs/Input/NumberInput/NumberInput.js +81 -7
  44. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.d.ts +45 -0
  45. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.js +146 -0
  46. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +35 -0
  47. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +235 -0
  48. package/dist/components/inputs/Input/TextArea/TextArea.cva.d.ts +4 -0
  49. package/dist/components/inputs/Input/TextArea/TextArea.cva.js +5 -0
  50. package/dist/components/inputs/Input/TextArea/TextArea.js +3 -1
  51. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +3 -1
  52. package/dist/components/inputs/Input/TextInput/TextInput.js +82 -7
  53. package/dist/components/inputs/Input/shared/InputContent.js +7 -6
  54. package/dist/components/inputs/Input/shared/numberStatic.utils.d.ts +1 -0
  55. package/dist/components/inputs/Input/shared/numberStatic.utils.js +7 -0
  56. package/dist/components/inputs/Inputs/InputItem.d.ts +16 -21
  57. package/dist/components/inputs/Inputs/InputItem.js +6 -0
  58. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +2 -1
  59. package/dist/components/inputs/RadioGroup/RadioGroup.js +106 -25
  60. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +17 -0
  61. package/dist/components/inputs/RadioGroup/radio.cva.js +42 -1
  62. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +6 -2
  63. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +102 -7
  64. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +3 -18
  65. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +33 -8
  66. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +36 -0
  67. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +14 -0
  68. package/dist/components/inputs/Selection/Select/QuerySelect.js +42 -0
  69. package/dist/components/inputs/Selection/Select/Select.d.ts +7 -3
  70. package/dist/components/inputs/Selection/Select/Select.js +115 -5
  71. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +8 -1
  72. package/dist/components/inputs/Selection/shared/SelectBase.js +4 -2
  73. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  74. package/dist/components/inputs/Selection/shared/SelectDesktop.js +11 -3
  75. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  76. package/dist/components/inputs/Selection/shared/SelectInput.js +27 -4
  77. package/dist/components/inputs/Selection/shared/SelectListBox.d.ts +2 -2
  78. package/dist/components/inputs/Selection/shared/SelectListBox.js +3 -3
  79. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  80. package/dist/components/inputs/Selection/shared/SelectMobile.js +9 -3
  81. package/dist/components/inputs/Selection/shared/querySelect.utils.d.ts +6 -0
  82. package/dist/components/inputs/Selection/shared/querySelect.utils.js +13 -0
  83. package/dist/components/inputs/Selection/shared/select.context.d.ts +3 -2
  84. package/dist/components/inputs/Selection/shared/select.context.js +27 -4
  85. package/dist/components/inputs/Selection/shared/select.types.d.ts +3 -2
  86. package/dist/components/inputs/Selection/shared/selectDesktop.cva.d.ts +3 -0
  87. package/dist/components/inputs/Selection/shared/selectDesktop.cva.js +5 -0
  88. package/dist/components/inputs/Selection/shared/staticSelect.utils.d.ts +23 -0
  89. package/dist/components/inputs/Selection/shared/staticSelect.utils.js +37 -0
  90. package/dist/components/inputs/Selection/shared/staticSelect.utils.spec.d.ts +1 -0
  91. package/dist/components/inputs/Skeleton/InputFrame.d.ts +77 -0
  92. package/dist/components/inputs/Skeleton/InputFrame.js +200 -0
  93. package/dist/components/inputs/TextEditor/TextEditor.d.ts +1 -0
  94. package/dist/components/inputs/TextEditor/TextEditor.js +8 -3
  95. package/dist/components/inputs/Toggle/Toggle.js +6 -1
  96. package/dist/components/inputs/Toggle/toggle.cva.d.ts +3 -0
  97. package/dist/components/inputs/Toggle/toggle.cva.js +2 -1
  98. package/dist/components/inputs/shared/CheckContent.d.ts +2 -1
  99. package/dist/components/inputs/shared/CheckContent.js +3 -4
  100. package/dist/components/inputs/shared/InputClear.d.ts +2 -1
  101. package/dist/components/inputs/shared/InputClear.js +13 -1
  102. package/dist/components/inputs/shared/StaticInput.d.ts +38 -0
  103. package/dist/components/inputs/shared/TooltipWrapper.js +5 -1
  104. package/dist/components/inputs/shared/input.cva.d.ts +10 -0
  105. package/dist/components/inputs/shared/input.cva.js +19 -1
  106. package/dist/components/inputs/shared/tooltipWrapper.cva.d.ts +4 -0
  107. package/dist/components/inputs/shared/tooltipWrapper.cva.js +5 -0
  108. package/dist/components/inputs/shared/useStaticInputHandoff.d.ts +13 -0
  109. package/dist/components/inputs/shared/useStaticInputHandoff.js +47 -0
  110. package/dist/config/router.context.d.ts +3 -4
  111. package/dist/config/router.context.js +1 -3
  112. package/dist/config/uiConfig.context.d.ts +15 -3
  113. package/dist/config/uiConfig.context.js +16 -3
  114. package/dist/config/uiStyle.context.d.ts +27 -4
  115. package/dist/helpers/dynamicInputs.d.ts +5 -5
  116. package/dist/helpers/dynamicInputs.js +3 -0
  117. package/dist/hooks/useFilters.js +27 -23
  118. package/dist/hooks/useIntersectionObserver.d.ts +1 -1
  119. package/dist/hooks/useIntersectionObserver.js +27 -14
  120. package/dist/hooks/usePagination.js +8 -4
  121. package/dist/hooks/useQueryAutocomplete.d.ts +14 -0
  122. package/dist/hooks/useQueryAutocomplete.js +56 -0
  123. package/dist/hooks/useSorting.js +7 -4
  124. package/dist/index.d.ts +7 -0
  125. package/dist/index.js +5 -3
  126. package/dist/tw-ui-plugin.js +2 -0
  127. package/dist/utils/date-time.utils.d.ts +31 -10
  128. package/dist/utils/date-time.utils.js +123 -22
  129. package/dist/utils/query.utils.d.ts +4 -0
  130. package/dist/utils/query.utils.js +8 -0
  131. package/dist/utils/routing.utils.d.ts +1 -0
  132. package/dist/utils/routing.utils.js +14 -0
  133. package/package.json +2 -2
@@ -1,22 +1,30 @@
1
+ import { UIStyle } from "../../../../config/uiStyle.context.js";
1
2
  import { UIConfig } from "../../../../config/uiConfig.context.js";
2
3
  import { Calendar } from "../shared/Calendar.js";
3
4
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
5
+ import { datePickerInputContentRow } from "../shared/datePickerInput.cva.js";
6
+ import { renderDatePickerTodayIcon } from "../shared/datePickerTodayIcon.js";
4
7
  import { DatePickerInput } from "../shared/DatePickerInput.js";
5
8
  import { DateTimeDialog } from "../shared/DateTimeDialog.js";
6
9
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
10
+ import { getStaticCalendarDateTimeSegments } from "../shared/staticDateTimeSegments.js";
7
11
  import { FormField } from "../../FormField/FormField.js";
8
12
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
13
+ import { InputFrame } from "../../Skeleton/InputFrame.js";
14
+ import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
15
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
9
16
  import { jsx, jsxs } from "react/jsx-runtime";
10
- import { useEffect, useImperativeHandle, useMemo, useRef } from "react";
17
+ import { clsx } from "clsx";
18
+ import { useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
11
19
  import { useDatePicker, useLocale } from "react-aria";
12
20
  import { mergeRefs } from "@react-aria/utils";
13
- import { Controller } from "react-hook-form";
21
+ import { Controller, useWatch } from "react-hook-form";
14
22
  import { Time, createCalendar, getLocalTimeZone, now, toCalendarDateTime, today } from "@internationalized/date";
15
23
  import { useCalendarState, useDatePickerState } from "react-stately";
16
24
  //#region src/components/inputs/DateTime/DateTimePicker/DateTimePicker.tsx
17
25
  var DateTimePickerBase = (props) => {
18
26
  const ui = UIConfig.useConfig();
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;
27
+ 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, todayIconPlacement = ui.dateInput.todayIconPlacement, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, shouldUpdateDateOnMonthYearChange = ui.dateInput.shouldUpdateDateOnMonthYearChange, timeZone, autoFixYear = ui.dateInput.autoFixYear, format, setDateValueOnDateSelection = ui.dateInput.setDateValueOnDateSelection, ...rest } = props;
20
28
  let effectiveTimeZone = getLocalTimeZone();
21
29
  if (timeZone) effectiveTimeZone = timeZone;
22
30
  const formFieldProps = {
@@ -39,6 +47,10 @@ var DateTimePickerBase = (props) => {
39
47
  useImperativeHandle(ref, () => ({ clear: () => {
40
48
  datePickerInputRef.current?.clear();
41
49
  } }));
50
+ const handleBlur = (val) => {
51
+ onBlur?.({ target: { value: val } });
52
+ };
53
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
42
54
  const dialogState = useDatePickerState({
43
55
  ...rest,
44
56
  defaultValue: value || rest.defaultValue,
@@ -57,7 +69,8 @@ var DateTimePickerBase = (props) => {
57
69
  onChange: (val) => {
58
70
  onChange?.(val);
59
71
  dialogState.setValue(val);
60
- calendarState.setFocusedDate(val || today(effectiveTimeZone));
72
+ calendarState.setFocusedDate(val || today(getLocalTimeZone()));
73
+ debouncedBlur(val);
61
74
  },
62
75
  shouldCloseOnSelect: false,
63
76
  granularity: "minute",
@@ -93,8 +106,10 @@ var DateTimePickerBase = (props) => {
93
106
  labelProps
94
107
  };
95
108
  const onApply = () => {
96
- state.setValue(dialogState.value);
109
+ const newValue = dialogState.value;
110
+ state.setValue(newValue);
97
111
  state.toggle();
112
+ handleBlur(newValue);
98
113
  };
99
114
  const onMonthYearChange = (selectedDate) => {
100
115
  if (!shouldUpdateDateOnMonthYearChange) return;
@@ -166,13 +181,15 @@ var DateTimePickerBase = (props) => {
166
181
  isClearable,
167
182
  headerProps,
168
183
  todayIcon,
184
+ todayIconButtonSize,
185
+ todayIconPlacement,
169
186
  isRequired,
170
187
  disableManualEntry,
188
+ autoFixYear,
171
189
  placeholder,
172
190
  onOpenDropdown: () => state.toggle(),
173
191
  className: inputClassName,
174
192
  timeZone: effectiveTimeZone,
175
- autoFixYear,
176
193
  isTimeOptional,
177
194
  format
178
195
  }), (!disableDropdown || disableManualEntry) && /* @__PURE__ */ jsx(DateTimeDialog, {
@@ -194,13 +211,35 @@ var DateTimePickerBase = (props) => {
194
211
  datePickerState: dialogState,
195
212
  onApply,
196
213
  onMonthYearChange,
197
- granularity: "day"
214
+ granularity: "day",
215
+ setDateValueOnDateSelection
198
216
  })
199
217
  })]
200
218
  })
201
219
  });
202
220
  };
203
- var DateTimePicker = ({ fullIso = true, ...props }) => {
221
+ var DateTimePicker = ({ fullIso = true, renderStaticInput, ...props }) => {
222
+ const ui = UIConfig.useConfig();
223
+ const datePickerInputContentRowCva = UIStyle.useCva("datePickerInput.contentRowCva", datePickerInputContentRow);
224
+ const { locale } = useLocale();
225
+ const shouldForceLeadingZeros = props.shouldForceLeadingZeros ?? ui.dateInput.shouldForceLeadingZeros;
226
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
227
+ const inputRef = useRef(null);
228
+ const { renderRealInput } = useStaticInputHandoff({
229
+ inputRef,
230
+ renderInput,
231
+ setRenderInput,
232
+ getFocusTarget: (input) => {
233
+ return (input.getContainer?.() ?? input).querySelector("input, button, [tabindex]:not([tabindex='-1'])");
234
+ }
235
+ });
236
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
237
+ control: props.formControl.control,
238
+ name: props.formControl.name
239
+ }) : props.value;
240
+ let isFormControlDisabled = false;
241
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
242
+ const rawValue = watchedValue ?? props.value ?? null;
204
243
  let effectiveTimeZone = getLocalTimeZone();
205
244
  if (props.timeZone) effectiveTimeZone = props.timeZone;
206
245
  const formatDateValue = (dateValue) => {
@@ -212,6 +251,52 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
212
251
  if (isoString == null) return isoString;
213
252
  return DateTimeUtils.fromUTCISOToCalendarDateTime(isoString, effectiveTimeZone);
214
253
  };
254
+ if (!renderInput) {
255
+ const dateTimeValue = rawValue ? parseDateValue(rawValue) : null;
256
+ const as = props.as ?? ui.input.as;
257
+ const size = props.size ?? ui.input.size;
258
+ const isDisabled = isFormControlDisabled || !!props.isDisabled;
259
+ const todayIcon = props.todayIcon ?? ui.dateInput.todayIcon;
260
+ const todayIconButtonSize = props.todayIconButtonSize ?? ui.dateInput.todayIconButtonSize;
261
+ const todayIconPlacement = props.todayIconPlacement ?? ui.dateInput.todayIconPlacement;
262
+ const staticTodayIcon = renderDatePickerTodayIcon(todayIcon, todayIconButtonSize);
263
+ const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
264
+ const showDropdown = !props.disableDropdown || disableManualEntry;
265
+ const staticSegments = getStaticCalendarDateTimeSegments({
266
+ value: dateTimeValue,
267
+ locale,
268
+ placeholder: props.placeholder,
269
+ shouldForceLeadingZeros,
270
+ isDisabled,
271
+ hidePlaceholder: as === "floating" && !dateTimeValue
272
+ });
273
+ return /* @__PURE__ */ jsx(InputFrame, {
274
+ ...props,
275
+ isDisabled,
276
+ className: clsx("relative inline-flex w-full flex-col text-left", props.className),
277
+ inputClassName: clsx("min-w-input-width-min-width", props.inputClassName),
278
+ contentClassName: "pr-0!",
279
+ contentWrapperClassName: datePickerInputContentRowCva({ size }),
280
+ labelPlacement: "content-row",
281
+ dataAttributes: {
282
+ dataIsEmpty: dateTimeValue === null,
283
+ dataIsFilled: dateTimeValue !== null,
284
+ dataIsDirty: props.isDirty,
285
+ dataIsRequired: props.isRequired,
286
+ dataIsDisabled: isDisabled,
287
+ dataDisabled: isDisabled,
288
+ dataInvalid: !!props.error,
289
+ dataHasSelection: dateTimeValue !== null
290
+ },
291
+ renderStatic: true,
292
+ onStaticInteract: renderRealInput,
293
+ actionContent: staticTodayIcon,
294
+ actionContentPlacement: todayIconPlacement === "fieldLabel" ? "content-row" : "content-wrapper",
295
+ trailingClassName: "py-0! pl-0!",
296
+ trailingContent: showDropdown ? ui.dateInput.dateTimeIcon : void 0,
297
+ children: staticSegments
298
+ });
299
+ }
215
300
  if ("formControl" in props && props.formControl) {
216
301
  const { formControl, ref, ...innerProps } = props;
217
302
  return /* @__PURE__ */ jsx(Controller, {
@@ -219,7 +304,7 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
219
304
  name: formControl.name,
220
305
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(DateTimePickerBase, {
221
306
  ...innerProps,
222
- ref: mergeRefs(ref, field.ref),
307
+ ref: mergeRefs(ref, field.ref, inputRef),
223
308
  value: parseDateValue(field.value),
224
309
  onChange: (value) => field.onChange(formatDateValue(value)),
225
310
  onBlur: field.onBlur,
@@ -231,6 +316,7 @@ var DateTimePicker = ({ fullIso = true, ...props }) => {
231
316
  }
232
317
  return /* @__PURE__ */ jsx(DateTimePickerBase, {
233
318
  ...props,
319
+ ref: mergeRefs(props.ref, inputRef),
234
320
  value: parseDateValue(props.value),
235
321
  onChange: (value) => props.onChange?.(formatDateValue(value))
236
322
  });
@@ -1,10 +1,10 @@
1
- import { Ref } from 'react';
1
+ import { Ref, FocusEvent } 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"> {
7
+ interface TimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<AriaTimeFieldProps<TimeValue>, "label" | "onBlur"> {
8
8
  ref?: Ref<HTMLDivElement>;
9
9
  disableDropdown?: boolean;
10
10
  date?: string | null;
@@ -13,13 +13,15 @@ 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;
16
17
  }
17
18
  export interface TimePickerProps extends Omit<TimePickerBaseProps, "value" | "onChange"> {
18
19
  value?: string | null;
19
20
  onChange?: (value: string | null) => void;
20
21
  fullIso?: boolean;
21
22
  timeZone?: string;
23
+ renderStaticInput?: boolean;
22
24
  }
23
25
  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;
26
+ export declare const TimePicker: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledTimePickerProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
25
27
  export {};
@@ -3,22 +3,26 @@ import { TimePickerForm } from "../shared/TimePickerForm.js";
3
3
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
4
4
  import { DateTimeDialog } from "../shared/DateTimeDialog.js";
5
5
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
6
+ import { getStaticTimeSegments } from "../shared/staticDateTimeSegments.js";
6
7
  import { FormField } from "../../FormField/FormField.js";
7
8
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
9
+ import { InputFrame } from "../../Skeleton/InputFrame.js";
10
+ import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
11
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
8
12
  import { TimePickerInput } from "../shared/TimePickerInput.js";
9
13
  import { jsx, jsxs } from "react/jsx-runtime";
10
14
  import { clsx } from "clsx";
11
15
  import { useEffect, useRef, useState } from "react";
12
16
  import { useLocale, useTimeField } from "react-aria";
13
17
  import { mergeRefs } from "@react-aria/utils";
14
- import { Controller } from "react-hook-form";
18
+ import { Controller, useWatch } from "react-hook-form";
15
19
  import { getLocalTimeZone, now, toTime } from "@internationalized/date";
16
20
  import { DateTime } from "luxon";
17
21
  import { useTimeFieldState } from "react-stately";
18
22
  //#region src/components/inputs/DateTime/TimePicker/TimePicker.tsx
19
23
  var TimePickerBase = (props) => {
20
24
  const ui = UIConfig.useConfig();
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;
25
+ 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;
22
26
  const formFieldProps = {
23
27
  error,
24
28
  label,
@@ -40,11 +44,18 @@ var TimePickerBase = (props) => {
40
44
  defaultValue: value || rest.defaultValue,
41
45
  locale
42
46
  });
47
+ const handleBlur = (val) => {
48
+ onBlur?.({ target: { value: val } });
49
+ };
50
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
43
51
  const state = useTimeFieldState({
44
52
  ...rest,
45
53
  isDisabled,
46
54
  value,
47
- onChange,
55
+ onChange: (val) => {
56
+ onChange?.(val);
57
+ debouncedBlur(val);
58
+ },
48
59
  locale
49
60
  });
50
61
  useEffect(() => {
@@ -72,8 +83,10 @@ var TimePickerBase = (props) => {
72
83
  labelProps
73
84
  };
74
85
  const onApply = () => {
75
- state.setValue(dialogState.value);
86
+ const newValue = dialogState.value;
87
+ state.setValue(newValue);
76
88
  setIsOpen(false);
89
+ handleBlur(newValue);
77
90
  };
78
91
  const onOpenChange = (open) => {
79
92
  setIsOpen(open);
@@ -101,6 +114,7 @@ var TimePickerBase = (props) => {
101
114
  onPress: onOpen,
102
115
  isDisabled,
103
116
  isDirty,
117
+ isRequired,
104
118
  isInvalid: !!error,
105
119
  disableDropdown,
106
120
  variant,
@@ -125,9 +139,26 @@ var TimePickerBase = (props) => {
125
139
  })
126
140
  });
127
141
  };
128
- var TimePicker = (props) => {
142
+ var TimePicker = ({ renderStaticInput, ...props }) => {
143
+ const ui = UIConfig.useConfig();
129
144
  let effectiveTimeZone = getLocalTimeZone();
130
145
  if (props.timeZone) effectiveTimeZone = props.timeZone;
146
+ const { locale } = useLocale();
147
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
148
+ const inputRef = useRef(null);
149
+ const { renderRealInput } = useStaticInputHandoff({
150
+ inputRef,
151
+ renderInput,
152
+ setRenderInput,
153
+ getFocusTarget: (input) => input.querySelector("input, button, [tabindex]:not([tabindex='-1'])")
154
+ });
155
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
156
+ control: props.formControl.control,
157
+ name: props.formControl.name
158
+ }) : props.value;
159
+ let isFormControlDisabled = false;
160
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
161
+ const rawValue = watchedValue ?? props.value ?? null;
131
162
  const formatTimeValue = (timeValue) => {
132
163
  if (timeValue === null) return null;
133
164
  let parsedDate;
@@ -141,17 +172,55 @@ var TimePicker = (props) => {
141
172
  if (isoString == null) return isoString;
142
173
  return toTime(DateTimeUtils.fromISOtoZonedDateTime(isoString, effectiveTimeZone));
143
174
  };
175
+ if (!renderInput) {
176
+ const timeValue = rawValue ? parseTimeValue(rawValue) : null;
177
+ const as = props.as ?? ui.input.as;
178
+ const isDisabled = isFormControlDisabled || !!props.isDisabled;
179
+ const disableManualEntry = props.disableManualEntry ?? ui.dateInput.disableManualEntry;
180
+ const showDropdown = !props.disableDropdown || disableManualEntry;
181
+ const staticSegments = getStaticTimeSegments({
182
+ value: timeValue,
183
+ locale,
184
+ placeholder: props.placeholder,
185
+ isDisabled,
186
+ hidePlaceholder: as === "floating" && !timeValue
187
+ });
188
+ return /* @__PURE__ */ jsx(InputFrame, {
189
+ ...props,
190
+ isDisabled,
191
+ className: clsx("relative inline-flex w-full flex-col text-left", props.className),
192
+ inputClassName: clsx("min-w-input-width-min-width", props.inputClassName),
193
+ contentClassName: "pr-0!",
194
+ labelPlacement: "content-row",
195
+ dataAttributes: {
196
+ dataIsEmpty: timeValue === null,
197
+ dataIsFilled: timeValue !== null,
198
+ dataIsDirty: props.isDirty,
199
+ dataIsRequired: props.isRequired,
200
+ dataIsDisabled: isDisabled,
201
+ dataDisabled: isDisabled,
202
+ dataInvalid: !!props.error,
203
+ dataHasSelection: timeValue !== null
204
+ },
205
+ renderStatic: true,
206
+ onStaticInteract: renderRealInput,
207
+ trailingClassName: "py-0! pl-0!",
208
+ trailingContent: showDropdown ? ui.dateInput.timeIcon : void 0,
209
+ children: staticSegments
210
+ });
211
+ }
144
212
  if ("formControl" in props && props.formControl) {
145
213
  const { formControl, ref, ...innerProps } = props;
146
214
  return /* @__PURE__ */ jsx(Controller, {
147
215
  control: formControl.control,
148
216
  name: formControl.name,
149
- render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(TimePickerBase, {
217
+ render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TimePickerBase, {
150
218
  ...innerProps,
151
- ref: mergeRefs(ref, field.ref),
219
+ ref: mergeRefs(ref, field.ref, inputRef),
152
220
  value: parseTimeValue(field.value),
153
221
  onChange: (value) => field.onChange(formatTimeValue(value)),
154
222
  onBlur: field.onBlur,
223
+ isDirty,
155
224
  isDisabled: field.disabled || props.isDisabled,
156
225
  error: props.error ?? error?.message
157
226
  })
@@ -159,6 +228,7 @@ var TimePicker = (props) => {
159
228
  }
160
229
  return /* @__PURE__ */ jsx(TimePickerBase, {
161
230
  ...props,
231
+ ref: mergeRefs(props.ref, inputRef),
162
232
  value: parseTimeValue(props.value),
163
233
  onChange: (value) => props.onChange?.(formatTimeValue(value))
164
234
  });
@@ -1,5 +1,6 @@
1
1
  import { CalendarDate } from '@internationalized/date';
2
2
  import { CalendarState, CalendarStateOptions } from '@react-stately/calendar';
3
+ import { DateValue } from 'react-aria';
3
4
  import { DatePickerState } from 'react-stately';
4
5
  type DateTimeCalendarProps = {
5
6
  includesTime?: false;
@@ -14,12 +15,14 @@ type CalendarProps = DateTimeCalendarProps & {
14
15
  className?: string;
15
16
  state: CalendarState;
16
17
  calendarProps: Omit<CalendarStateOptions, "locale" | "createCalendar">;
17
- onApply: () => void;
18
+ onApply: (selectedDate?: DateValue) => void;
19
+ onDateSelectionChange?: (selectedDate: DateValue) => void;
20
+ setDateValueOnDateSelection?: boolean;
18
21
  onMonthYearChange?: (selectedDate: CalendarDate) => void;
19
22
  onMonthYearCommit?: () => void;
20
23
  selectedDate?: CalendarDate | null;
21
24
  granularity?: "day" | "month" | "year";
22
25
  };
23
26
  export type ToggleState = "month" | "year" | "time";
24
- export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity, ...props }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
27
+ export declare const Calendar: ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity, setDateValueOnDateSelection, onDateSelectionChange, ...props }: CalendarProps) => import("react/jsx-runtime").JSX.Element;
25
28
  export {};
@@ -5,10 +5,10 @@ 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 { useEffect, 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, onMonthYearChange, onMonthYearCommit, selectedDate, granularity = "day", ...props }) => {
11
+ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply, onMonthYearChange, onMonthYearCommit, selectedDate, granularity = "day", setDateValueOnDateSelection = false, onDateSelectionChange, ...props }) => {
12
12
  const [toggleState, setToggleState] = useState(() => {
13
13
  if (granularity === "year") return "year";
14
14
  if (granularity === "month") return "month";
@@ -76,9 +76,25 @@ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
76
76
  handleHeaderMonthNavigation(1);
77
77
  }
78
78
  };
79
- const handleDateChange = () => {
80
- if (includesTime && !datePickerState.value) setToggleState("time");
81
- else onApply();
79
+ const onDateSelection = useCallback((date) => {
80
+ if (!includesTime || !setDateValueOnDateSelection) return;
81
+ datePickerState.setDateValue(date);
82
+ }, [
83
+ includesTime,
84
+ datePickerState,
85
+ setDateValueOnDateSelection
86
+ ]);
87
+ const handleDateChange = (selectedDate) => {
88
+ const resolvedDate = selectedDate ?? props.state.focusedDate;
89
+ if (includesTime && resolvedDate && setDateValueOnDateSelection) {
90
+ datePickerState.setDateValue(resolvedDate);
91
+ onDateSelectionChange?.(resolvedDate);
92
+ }
93
+ if (includesTime && toggleState !== "time") {
94
+ setToggleState("time");
95
+ return;
96
+ }
97
+ if (datePickerState?.value && !setDateValueOnDateSelection) onApply(resolvedDate);
82
98
  };
83
99
  const getContent = () => {
84
100
  if (!toggleState) {
@@ -98,7 +114,8 @@ var Calendar = ({ className, includesTime, datePickerState, hourCycle, onApply,
98
114
  });
99
115
  return /* @__PURE__ */ jsx(CalendarGrid, {
100
116
  state: props.state,
101
- onApply: handleDateChange
117
+ onApply: handleDateChange,
118
+ onDateSelection
102
119
  });
103
120
  }
104
121
  if (toggleState === "month") {
@@ -4,7 +4,7 @@ import { KeyboardEvent } from 'react';
4
4
  import { DateValue } from 'react-aria';
5
5
  interface CalendarCellProps extends AriaCalendarCellProps {
6
6
  state: CalendarState | RangeCalendarState;
7
- onApply?: () => void;
7
+ onApply?: (selectedDate?: DateValue) => void;
8
8
  shouldCloseOnSelect?: boolean;
9
9
  onDateSelection?: (date: DateValue) => void;
10
10
  onDateHover?: (date: DateValue | null) => void;
@@ -17,12 +17,12 @@ var CalendarCell = ({ state, onApply, shouldCloseOnSelect = true, onDateSelectio
17
17
  const onClick = useCallback((event) => {
18
18
  buttonProps.onClick?.(event);
19
19
  if (onDateSelection) onDateSelection(props.date);
20
- if (isSelected && shouldCloseOnSelect) onApply?.();
20
+ if (shouldCloseOnSelect && !isDisabled) onApply?.(props.date);
21
21
  }, [
22
22
  buttonProps,
23
23
  onDateSelection,
24
24
  props.date,
25
- isSelected,
25
+ isDisabled,
26
26
  shouldCloseOnSelect,
27
27
  onApply
28
28
  ]);
@@ -87,7 +87,7 @@ var CalendarCell = ({ state, onApply, shouldCloseOnSelect = true, onDateSelectio
87
87
  state.setFocusedDate(props.date);
88
88
  }
89
89
  eventHandler?.(event);
90
- if (isSelected && shouldCloseOnSelect) onApply?.();
90
+ if (isSelected && shouldCloseOnSelect) onApply?.(props.date);
91
91
  };
92
92
  const onMouseEnter = useCallback(() => {
93
93
  if (onDateHover && selectionState.isSelectingMode) onDateHover(props.date);
@@ -4,7 +4,7 @@ import { KeyboardEvent } from 'react';
4
4
  import { DateValue } from 'react-aria';
5
5
  interface CalendarGridProps extends AriaCalendarGridProps {
6
6
  state: CalendarState | RangeCalendarState;
7
- onApply?: () => void;
7
+ onApply?: (selectedDate?: DateValue) => void;
8
8
  offset?: {
9
9
  months?: number;
10
10
  };
@@ -1,5 +1,6 @@
1
1
  import { Ref } from 'react';
2
2
  import { DatePickerAria } from 'react-aria';
3
+ import { DatePickerTodayIcon, DatePickerTodayIconButtonSize, DatePickerTodayIconPlacement } from './datePicker.types';
3
4
  import { FormFieldHeaderProps } from '../../FormField/FormFieldHeader';
4
5
  import { InputVariantProps } from '../../shared/input.cva';
5
6
  export interface DatePickerInputHandle {
@@ -18,18 +19,20 @@ interface DatePickerInputProps extends InputVariantProps {
18
19
  isDateTime?: boolean;
19
20
  isClearable?: boolean;
20
21
  headerProps?: FormFieldHeaderProps;
21
- todayIcon?: boolean;
22
+ todayIcon?: DatePickerTodayIcon;
23
+ todayIconButtonSize?: DatePickerTodayIconButtonSize;
24
+ todayIconPlacement?: DatePickerTodayIconPlacement;
22
25
  isDirty?: boolean;
23
26
  isRequired?: boolean;
24
27
  disableManualEntry?: boolean;
28
+ autoFixYear?: boolean;
25
29
  placeholder?: string;
26
30
  className?: string;
27
31
  onOpenDropdown?: () => void;
28
32
  dateGranularity?: "day" | "month" | "year";
29
33
  timeZone?: string;
30
- autoFixYear?: boolean;
31
34
  isTimeOptional?: boolean;
32
35
  format?: string;
33
36
  }
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;
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;
35
38
  export {};