@povio/ui 2.2.9-rc.1 → 2.2.9-rc.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 (69) hide show
  1. package/dist/components/buttons/InlineIconButton/InlineIconButton.d.ts +1 -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 +7 -3
  7. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +19 -5
  8. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +7 -3
  9. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +13 -2
  10. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +7 -3
  11. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +12 -2
  12. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +3 -2
  13. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +13 -3
  14. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +5 -2
  15. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +16 -8
  16. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +4 -1
  17. package/dist/components/inputs/DateTime/shared/datePicker.types.d.ts +3 -0
  18. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.d.ts +7 -0
  19. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.js +13 -0
  20. package/dist/components/inputs/FormField/FormFieldHeader.js +3 -1
  21. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +6 -0
  22. package/dist/components/inputs/FormField/formFieldHeader.cva.js +11 -0
  23. package/dist/components/inputs/Input/TextInput/TextInput.js +2 -0
  24. package/dist/components/inputs/Inputs/InputItem.d.ts +9 -15
  25. package/dist/components/inputs/Inputs/InputItem.js +4 -0
  26. package/dist/components/inputs/RadioGroup/RadioGroup.js +6 -1
  27. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +3 -0
  28. package/dist/components/inputs/RadioGroup/radio.cva.js +2 -1
  29. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +3 -1
  30. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +2 -2
  31. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +3 -18
  32. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +24 -7
  33. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +30 -0
  34. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +14 -0
  35. package/dist/components/inputs/Selection/Select/QuerySelect.js +58 -0
  36. package/dist/components/inputs/Selection/Select/Select.d.ts +4 -2
  37. package/dist/components/inputs/Selection/Select/Select.js +2 -2
  38. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +6 -1
  39. package/dist/components/inputs/Selection/shared/SelectBase.js +3 -2
  40. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  41. package/dist/components/inputs/Selection/shared/SelectDesktop.js +8 -2
  42. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  43. package/dist/components/inputs/Selection/shared/SelectInput.js +11 -1
  44. package/dist/components/inputs/Selection/shared/SelectListBox.d.ts +2 -2
  45. package/dist/components/inputs/Selection/shared/SelectListBox.js +2 -2
  46. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  47. package/dist/components/inputs/Selection/shared/SelectMobile.js +5 -1
  48. package/dist/components/inputs/Selection/shared/querySelect.utils.d.ts +6 -0
  49. package/dist/components/inputs/Selection/shared/querySelect.utils.js +13 -0
  50. package/dist/components/inputs/Selection/shared/select.context.d.ts +3 -2
  51. package/dist/components/inputs/Selection/shared/select.context.js +22 -4
  52. package/dist/components/inputs/Selection/shared/select.types.d.ts +3 -2
  53. package/dist/components/inputs/Selection/shared/selectDesktop.cva.d.ts +3 -0
  54. package/dist/components/inputs/Selection/shared/selectDesktop.cva.js +5 -0
  55. package/dist/components/inputs/Toggle/Toggle.js +6 -1
  56. package/dist/components/inputs/Toggle/toggle.cva.d.ts +3 -0
  57. package/dist/components/inputs/Toggle/toggle.cva.js +2 -1
  58. package/dist/components/inputs/shared/CheckContent.d.ts +2 -1
  59. package/dist/components/inputs/shared/CheckContent.js +3 -4
  60. package/dist/config/uiConfig.context.d.ts +7 -1
  61. package/dist/config/uiConfig.context.js +5 -1
  62. package/dist/config/uiStyle.context.d.ts +13 -2
  63. package/dist/helpers/dynamicInputs.d.ts +5 -5
  64. package/dist/helpers/dynamicInputs.js +3 -0
  65. package/dist/hooks/useQueryAutocomplete.d.ts +26 -0
  66. package/dist/hooks/useQueryAutocomplete.js +43 -0
  67. package/dist/index.d.ts +4 -0
  68. package/dist/index.js +4 -3
  69. package/package.json +1 -1
@@ -9,4 +9,4 @@ export interface InlineIconButtonProps extends Omit<AriaButtonProps, "children">
9
9
  ref?: RefObject<HTMLButtonElement | HTMLAnchorElement | null>;
10
10
  disableTooltip?: boolean;
11
11
  }
12
- export declare const InlineIconButton: ({ label, ...props }: InlineIconButtonProps) => import("react/jsx-runtime").JSX.Element;
12
+ export declare const InlineIconButton: ({ label, size, ...props }: InlineIconButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,12 +1,12 @@
1
1
  import { Button } from "../Button/Button.js";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/buttons/InlineIconButton/InlineIconButton.tsx
4
- var InlineIconButton = ({ label, ...props }) => {
4
+ var InlineIconButton = ({ label, size = "none", ...props }) => {
5
5
  return /* @__PURE__ */ jsx(Button, {
6
6
  ...props,
7
7
  iconOnly: true,
8
8
  variant: "text",
9
- size: "none",
9
+ size,
10
10
  width: "hug",
11
11
  children: label
12
12
  });
@@ -1,6 +1,6 @@
1
1
  import { UIStyle } from "../../../config/uiStyle.context.js";
2
2
  import { UIConfig } from "../../../config/uiConfig.context.js";
3
- import { checkboxIndicatorClass, checkboxTypography } from "./checkbox.cva.js";
3
+ import { checkboxContentClassName, checkboxIndicatorClass, checkboxTypography } from "./checkbox.cva.js";
4
4
  import { FormFieldError } from "../FormField/FormFieldError.js";
5
5
  import { CheckContent } from "../shared/CheckContent.js";
6
6
  import { CheckboxCheckmark } from "./CheckboxCheckmark.js";
@@ -13,6 +13,7 @@ import { Controller } from "react-hook-form";
13
13
  var CheckboxBase = (props) => {
14
14
  const ui = UIConfig.useConfig();
15
15
  const checkboxTypographyMap = UIStyle.useMapper("checkbox.typography", checkboxTypography);
16
+ const checkboxContentClassNameMap = UIStyle.useMapper("checkbox.contentClassName", checkboxContentClassName);
16
17
  const { className, children, isDisabled, error, variant = ui.checkbox.variant, hideLabel = ui.input.hideLabel, ...rest } = props;
17
18
  const formFieldErrorProps = {
18
19
  error,
@@ -34,6 +35,10 @@ var CheckboxBase = (props) => {
34
35
  variant,
35
36
  ...rest
36
37
  }),
38
+ contentClassName: checkboxContentClassNameMap({
39
+ variant,
40
+ ...rest
41
+ }),
37
42
  children
38
43
  })]
39
44
  }), /* @__PURE__ */ jsx(FormFieldError, { ...formFieldErrorProps })] });
@@ -9,6 +9,9 @@ export declare const checkboxIndicatorClass = "group flex items-center gap-2";
9
9
  export declare const checkboxTypography: (props: {
10
10
  variant?: "default" | null | undefined;
11
11
  }) => TypographyVariantProps | undefined;
12
+ export declare const checkboxContentClassName: (props: {
13
+ variant?: "default" | null | undefined;
14
+ }) => string | undefined;
12
15
  export declare const checkboxIcon: (props?: ({
13
16
  iconVariant?: "selected" | "indeterminate" | null | undefined;
14
17
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
@@ -39,6 +39,7 @@ var checkboxTypography = compoundMapper({ default: {
39
39
  sizeMobile: "label-1",
40
40
  variant: "default"
41
41
  } });
42
+ var checkboxContentClassName = compoundMapper({ default: "text-text-default-2" });
42
43
  var checkboxIcon = cva(["absolute hidden size-3"], {
43
44
  variants: { iconVariant: {
44
45
  selected: ["group-selected:block"],
@@ -47,4 +48,4 @@ var checkboxIcon = cva(["absolute hidden size-3"], {
47
48
  defaultVariants: { iconVariant: "selected" }
48
49
  });
49
50
  //#endregion
50
- export { checkbox, checkboxIcon, checkboxIndicatorClass, checkboxTypography };
51
+ export { checkbox, checkboxContentClassName, checkboxIcon, checkboxIndicatorClass, checkboxTypography };
@@ -1,21 +1,25 @@
1
1
  import { CalendarDate, DateValue } from '@internationalized/date';
2
- import { Ref } from 'react';
2
+ import { Ref, FocusEvent } from 'react';
3
3
  import { FieldValues } from 'react-hook-form';
4
4
  import { DatePickerStateOptions } from 'react-stately';
5
5
  import { DatePickerInputHandle } from '../shared/DatePickerInput';
6
+ import { DatePickerTodayIcon, DatePickerTodayIconButtonSize } from '../shared/datePicker.types';
6
7
  import { FormFieldProps } from '../../FormField/FormField';
7
8
  import { ControlProps } from '../../shared/form.types';
8
9
  import { InputVariantProps } from '../../shared/input.cva';
9
- interface DatePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DatePickerStateOptions<CalendarDate>, "granularity" | "shouldCloseOnSelect" | "label"> {
10
+ interface DatePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DatePickerStateOptions<CalendarDate>, "granularity" | "shouldCloseOnSelect" | "label" | "onBlur"> {
10
11
  ref?: Ref<DatePickerInputHandle & HTMLDivElement>;
11
12
  disableDropdown?: boolean;
12
13
  isClearable?: boolean;
13
14
  className?: string;
14
- todayIcon?: boolean;
15
+ todayIcon?: DatePickerTodayIcon;
16
+ todayIconButtonSize?: DatePickerTodayIconButtonSize;
15
17
  isDirty?: boolean;
16
18
  disableManualEntry?: boolean;
19
+ autoFixYear?: boolean;
17
20
  placeholder?: string;
18
21
  inputClassName?: string;
22
+ onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
19
23
  }
20
24
  export interface DatePickerProps extends Omit<DatePickerBaseProps, "value" | "onChange" | "minValue" | "maxValue"> {
21
25
  value?: string | null;
@@ -5,6 +5,7 @@ import { DateTimeDialog } from "../shared/DateTimeDialog.js";
5
5
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
6
6
  import { FormField } from "../../FormField/FormField.js";
7
7
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
8
9
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  import { clsx } from "clsx";
@@ -12,13 +13,14 @@ import { useImperativeHandle, useMemo, useRef } from "react";
12
13
  import { useDatePicker, useLocale } from "react-aria";
13
14
  import { mergeRefs } from "@react-aria/utils";
14
15
  import { Controller } from "react-hook-form";
15
- import { createCalendar, getLocalTimeZone, toCalendarDate, today } from "@internationalized/date";
16
+ import { CalendarDate, createCalendar, getLocalTimeZone, toCalendarDate, today } from "@internationalized/date";
16
17
  import { DateTime } from "luxon";
17
18
  import { useCalendarState, useDatePickerState } from "react-stately";
18
19
  //#region src/components/inputs/DateTime/DatePicker/DatePicker.tsx
20
+ var PLACEHOLDER_VALUE = new CalendarDate(2024, 1, 1);
19
21
  var DatePickerBase = (props) => {
20
22
  const ui = UIConfig.useConfig();
21
- const { ref, label, tooltipText, helperText, isRequired, rightContent, isDirty, isDisabled, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, className, placeholder, inputClassName, as = ui.input.as, hideLabel = ui.input.hideLabel, variant = ui.input.variant, size = ui.input.size, isClearable = ui.input.isClearable, todayIcon = ui.dateInput.todayIcon, shouldForceLeadingZeros = ui.dateInput.shouldForceLeadingZeros, disableManualEntry = ui.dateInput.disableManualEntry, ...rest } = props;
23
+ const { ref, label, tooltipText, helperText, isRequired, rightContent, isDirty, isDisabled, headerClassName, errorClassName, isHeaderHidden, error, onChange, onBlur, value, disableDropdown, className, placeholder, inputClassName, as = ui.input.as, hideLabel = ui.input.hideLabel, variant = ui.input.variant, 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;
22
24
  const formFieldProps = {
23
25
  error,
24
26
  label,
@@ -39,6 +41,10 @@ var DatePickerBase = (props) => {
39
41
  useImperativeHandle(ref, () => ({ clear: () => {
40
42
  datePickerInputRef.current?.clear();
41
43
  } }));
44
+ const handleBlur = (val) => {
45
+ onBlur?.({ target: { value: val } });
46
+ };
47
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
42
48
  const dialogState = useDatePickerState({
43
49
  ...rest,
44
50
  defaultValue: value || rest.defaultValue,
@@ -57,6 +63,7 @@ var DatePickerBase = (props) => {
57
63
  onChange?.(val);
58
64
  dialogState.setValue(val);
59
65
  calendarState.setFocusedDate(val || today(getLocalTimeZone()));
66
+ debouncedBlur(val);
60
67
  },
61
68
  shouldCloseOnSelect: false
62
69
  });
@@ -88,8 +95,10 @@ var DatePickerBase = (props) => {
88
95
  labelProps
89
96
  };
90
97
  const onApply = () => {
91
- state.setValue(dialogState.value);
98
+ const newValue = dialogState.value;
99
+ state.setValue(newValue);
92
100
  state.toggle();
101
+ handleBlur(newValue);
93
102
  };
94
103
  const onTodayPress = () => {
95
104
  dialogState.setValue(today(getLocalTimeZone()));
@@ -114,11 +123,15 @@ var DatePickerBase = (props) => {
114
123
  ref: mergeRefs(ref, datePickerInputRef),
115
124
  as,
116
125
  groupProps,
117
- fieldProps,
126
+ fieldProps: {
127
+ ...fieldProps,
128
+ placeholderValue: PLACEHOLDER_VALUE
129
+ },
118
130
  buttonProps,
119
131
  isDirty,
120
132
  isDisabled,
121
133
  disableManualEntry,
134
+ autoFixYear,
122
135
  isInvalid: !!error,
123
136
  disableDropdown,
124
137
  variant,
@@ -126,10 +139,11 @@ var DatePickerBase = (props) => {
126
139
  isClearable,
127
140
  headerProps,
128
141
  todayIcon,
142
+ todayIconButtonSize,
129
143
  onOpenDropdown: () => state.toggle(),
130
144
  placeholder,
131
145
  className: inputClassName
132
- }), (!disableDropdown || disableManualEntry) && /* @__PURE__ */ jsx(DateTimeDialog, {
146
+ }), (!disableDropdown || disableManualEntry) && state.isOpen && /* @__PURE__ */ jsx(DateTimeDialog, {
133
147
  footer: /* @__PURE__ */ jsx(DateTimeDialogFooter, {
134
148
  isDisabled,
135
149
  isValid: !dialogState.isInvalid && !!dialogState.value,
@@ -1,23 +1,27 @@
1
1
  import { CalendarDate } from '@internationalized/date';
2
- import { Ref } from 'react';
2
+ import { FocusEvent, Ref } from 'react';
3
3
  import { DateValue } from 'react-aria';
4
4
  import { FieldValues } from 'react-hook-form';
5
5
  import { DateRangePickerStateOptions } from 'react-stately';
6
6
  import { DatePickerInputHandle } from '../shared/DatePickerInput';
7
+ import { DatePickerTodayIcon, DatePickerTodayIconButtonSize } from '../shared/datePicker.types';
7
8
  import { FormFieldProps } from '../../FormField/FormField';
8
9
  import { ControlProps } from '../../shared/form.types';
9
10
  import { InputVariantProps } from '../../shared/input.cva';
10
- interface DateRangePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DateRangePickerStateOptions<CalendarDate>, "granularity" | "shouldCloseOnSelect" | "label"> {
11
+ interface DateRangePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DateRangePickerStateOptions<CalendarDate>, "granularity" | "shouldCloseOnSelect" | "label" | "onBlur"> {
11
12
  ref?: Ref<DatePickerInputHandle & HTMLDivElement>;
12
13
  disableDropdown?: boolean;
13
14
  isClearable?: boolean;
14
15
  hideSidebar?: boolean;
15
16
  className?: string;
16
- todayIcon?: boolean;
17
+ todayIcon?: DatePickerTodayIcon;
18
+ todayIconButtonSize?: DatePickerTodayIconButtonSize;
17
19
  isDirty?: boolean;
18
20
  disableManualEntry?: boolean;
21
+ autoFixYear?: boolean;
19
22
  placeholder?: string;
20
23
  inputClassName?: string;
24
+ onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
21
25
  }
22
26
  export interface DateRangePickerProps extends Omit<DateRangePickerBaseProps, "value" | "onChange" | "minValue" | "maxValue"> {
23
27
  value?: {
@@ -6,6 +6,7 @@ import { DateTimeDialog } from "../shared/DateTimeDialog.js";
6
6
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
7
7
  import { FormField } from "../../FormField/FormField.js";
8
8
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
9
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
9
10
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
10
11
  import { RangeCalendar } from "../shared/RangeCalendar.js";
11
12
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -23,7 +24,7 @@ import { useDateRangePickerState, useRangeCalendarState } from "react-stately";
23
24
  var DateRangePickerBase = (props) => {
24
25
  const ui = UIConfig.useConfig();
25
26
  const { t } = useTranslation();
26
- const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, value, disableDropdown, className, hideSidebar, 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, ...rest } = props;
27
+ const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, onChange, onBlur, value, disableDropdown, className, hideSidebar, 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;
27
28
  const [validationRangeError, setValidationRangeError] = useState();
28
29
  const datePickerInputRef = useRef(null);
29
30
  const dateRangePickerRef = useMemo(() => ({ get current() {
@@ -43,6 +44,7 @@ var DateRangePickerBase = (props) => {
43
44
  if (isValidRange(newValue)) return;
44
45
  onChange?.(newValue);
45
46
  handleCalendarStatesChange(newValue);
47
+ debouncedBlur(newValue);
46
48
  },
47
49
  shouldCloseOnSelect: false
48
50
  });
@@ -60,6 +62,10 @@ var DateRangePickerBase = (props) => {
60
62
  useImperativeHandle(ref, () => ({ clear: () => {
61
63
  datePickerInputRef.current?.clear();
62
64
  } }));
65
+ const handleBlur = (newValue) => {
66
+ onBlur?.({ target: { value: newValue } });
67
+ };
68
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
63
69
  const formFieldProps = {
64
70
  error: error || validationRangeError,
65
71
  label,
@@ -321,7 +327,10 @@ var DateRangePickerBase = (props) => {
321
327
  start: rangeSelection.start,
322
328
  end: rangeSelection.end
323
329
  } : dialogState.value;
324
- if (valueToApply) state.setValue(valueToApply);
330
+ if (valueToApply) {
331
+ state.setValue(valueToApply);
332
+ handleBlur(valueToApply);
333
+ }
325
334
  state.toggle();
326
335
  };
327
336
  const onTodayPress = () => {
@@ -475,8 +484,10 @@ var DateRangePickerBase = (props) => {
475
484
  isClearable,
476
485
  headerProps,
477
486
  todayIcon,
487
+ todayIconButtonSize,
478
488
  isDirty,
479
489
  disableManualEntry,
490
+ autoFixYear,
480
491
  placeholder,
481
492
  className: inputClassName,
482
493
  onOpenDropdown: () => state.toggle()
@@ -1,21 +1,25 @@
1
- import { Ref } from 'react';
1
+ import { FocusEvent, Ref } from 'react';
2
2
  import { DateValue } from 'react-aria';
3
3
  import { FieldValues } from 'react-hook-form';
4
4
  import { DatePickerStateOptions } from 'react-stately';
5
5
  import { DatePickerInputHandle } from '../shared/DatePickerInput';
6
+ import { DatePickerTodayIcon, DatePickerTodayIconButtonSize } from '../shared/datePicker.types';
6
7
  import { FormFieldProps } from '../../FormField/FormField';
7
8
  import { ControlProps } from '../../shared/form.types';
8
9
  import { InputVariantProps } from '../../shared/input.cva';
9
- interface DateTimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DatePickerStateOptions<DateValue>, "granularity" | "shouldCloseOnSelect" | "label"> {
10
+ interface DateTimePickerBaseProps extends FormFieldProps, InputVariantProps, Omit<DatePickerStateOptions<DateValue>, "granularity" | "shouldCloseOnSelect" | "label" | "onBlur"> {
10
11
  ref?: Ref<DatePickerInputHandle & HTMLDivElement>;
11
12
  disableDropdown?: boolean;
12
13
  isTimeOptional?: boolean;
13
14
  isClearable?: boolean;
14
- todayIcon?: boolean;
15
+ todayIcon?: DatePickerTodayIcon;
16
+ todayIconButtonSize?: DatePickerTodayIconButtonSize;
15
17
  isDirty?: boolean;
16
18
  disableManualEntry?: boolean;
19
+ autoFixYear?: boolean;
17
20
  placeholder?: string;
18
21
  inputClassName?: string;
22
+ onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
19
23
  }
20
24
  export interface DateTimePickerProps extends Omit<DateTimePickerBaseProps, "value" | "onChange"> {
21
25
  value?: string | null;
@@ -5,6 +5,7 @@ import { DateTimeDialog } from "../shared/DateTimeDialog.js";
5
5
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
6
6
  import { FormField } from "../../FormField/FormField.js";
7
7
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
8
9
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
10
11
  import { useEffect, useImperativeHandle, useMemo, useRef } from "react";
@@ -16,7 +17,7 @@ import { useCalendarState, useDatePickerState } from "react-stately";
16
17
  //#region src/components/inputs/DateTime/DateTimePicker/DateTimePicker.tsx
17
18
  var DateTimePickerBase = (props) => {
18
19
  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, ...rest } = props;
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;
20
21
  const formFieldProps = {
21
22
  error,
22
23
  label,
@@ -37,6 +38,10 @@ var DateTimePickerBase = (props) => {
37
38
  useImperativeHandle(ref, () => ({ clear: () => {
38
39
  datePickerInputRef.current?.clear();
39
40
  } }));
41
+ const handleBlur = (val) => {
42
+ onBlur?.({ target: { value: val } });
43
+ };
44
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
40
45
  const dialogState = useDatePickerState({
41
46
  ...rest,
42
47
  defaultValue: value || rest.defaultValue,
@@ -56,6 +61,7 @@ var DateTimePickerBase = (props) => {
56
61
  onChange?.(val);
57
62
  dialogState.setValue(val);
58
63
  calendarState.setFocusedDate(val || today(getLocalTimeZone()));
64
+ debouncedBlur(val);
59
65
  },
60
66
  shouldCloseOnSelect: false,
61
67
  granularity: "minute",
@@ -91,8 +97,10 @@ var DateTimePickerBase = (props) => {
91
97
  labelProps
92
98
  };
93
99
  const onApply = () => {
94
- state.setValue(dialogState.value);
100
+ const newValue = dialogState.value;
101
+ state.setValue(newValue);
95
102
  state.toggle();
103
+ handleBlur(newValue);
96
104
  };
97
105
  const onTodayPress = () => {
98
106
  dialogState.setValue(toCalendarDateTime(now(getLocalTimeZone())));
@@ -145,8 +153,10 @@ var DateTimePickerBase = (props) => {
145
153
  isClearable,
146
154
  headerProps,
147
155
  todayIcon,
156
+ todayIconButtonSize,
148
157
  isRequired,
149
158
  disableManualEntry,
159
+ autoFixYear,
150
160
  placeholder,
151
161
  onOpenDropdown: () => state.toggle(),
152
162
  className: inputClassName
@@ -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,6 +13,7 @@ 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;
@@ -4,6 +4,7 @@ import { DateTimeDialog } from "../shared/DateTimeDialog.js";
4
4
  import { DateTimeDialogFooter } from "../shared/DateTimeDialogFooter.js";
5
5
  import { FormField } from "../../FormField/FormField.js";
6
6
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
7
+ import { useDebounceCallback } from "../../../../hooks/useDebounceCallback.js";
7
8
  import { DateTimeUtils } from "../../../../utils/date-time.utils.js";
8
9
  import { TimePickerInput } from "../shared/TimePickerInput.js";
9
10
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -18,7 +19,7 @@ import { useTimeFieldState } from "react-stately";
18
19
  //#region src/components/inputs/DateTime/TimePicker/TimePicker.tsx
19
20
  var TimePickerBase = (props) => {
20
21
  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;
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;
22
23
  const formFieldProps = {
23
24
  error,
24
25
  label,
@@ -40,11 +41,18 @@ var TimePickerBase = (props) => {
40
41
  defaultValue: value || rest.defaultValue,
41
42
  locale
42
43
  });
44
+ const handleBlur = (val) => {
45
+ onBlur?.({ target: { value: val } });
46
+ };
47
+ const { callback: debouncedBlur } = useDebounceCallback(handleBlur, { delay: 500 });
43
48
  const state = useTimeFieldState({
44
49
  ...rest,
45
50
  isDisabled,
46
51
  value,
47
- onChange,
52
+ onChange: (val) => {
53
+ onChange?.(val);
54
+ debouncedBlur(val);
55
+ },
48
56
  locale
49
57
  });
50
58
  useEffect(() => {
@@ -72,8 +80,10 @@ var TimePickerBase = (props) => {
72
80
  labelProps
73
81
  };
74
82
  const onApply = () => {
75
- state.setValue(dialogState.value);
83
+ const newValue = dialogState.value;
84
+ state.setValue(newValue);
76
85
  setIsOpen(false);
86
+ handleBlur(newValue);
77
87
  };
78
88
  const onOpenChange = (open) => {
79
89
  setIsOpen(open);
@@ -1,5 +1,6 @@
1
1
  import { Ref } from 'react';
2
2
  import { DatePickerAria } from 'react-aria';
3
+ import { DatePickerTodayIcon, DatePickerTodayIconButtonSize } from './datePicker.types';
3
4
  import { FormFieldHeaderProps } from '../../FormField/FormFieldHeader';
4
5
  import { InputVariantProps } from '../../shared/input.cva';
5
6
  export interface DatePickerInputHandle {
@@ -18,13 +19,15 @@ 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;
22
24
  isDirty?: boolean;
23
25
  isRequired?: boolean;
24
26
  disableManualEntry?: boolean;
27
+ autoFixYear?: boolean;
25
28
  placeholder?: string;
26
29
  className?: string;
27
30
  onOpenDropdown?: () => void;
28
31
  }
29
- 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, ...props }: DatePickerInputProps) => import("react/jsx-runtime").JSX.Element;
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;
30
33
  export {};
@@ -2,10 +2,10 @@ import { CalendarIcon } from "../../../../assets/icons/Calendar.js";
2
2
  import { DateTimeIcon } from "../../../../assets/icons/DateTime.js";
3
3
  import { UIStyle } from "../../../../config/uiStyle.context.js";
4
4
  import { Typography } from "../../../text/Typography/Typography.js";
5
- import { IconButton } from "../../../buttons/IconButton/IconButton.js";
6
5
  import { InlineIconButton } from "../../../buttons/InlineIconButton/InlineIconButton.js";
7
6
  import { TodayIcon } from "../../../../assets/icons/Today.js";
8
7
  import { DateField } from "./DateField.js";
8
+ import { datePickerInputContentRow } from "./datePickerInput.cva.js";
9
9
  import { FormFieldLabel } from "../../FormField/FormFieldLabel.js";
10
10
  import { InputClear } from "../../shared/InputClear.js";
11
11
  import { inputBase, inputSize } from "../../shared/input.cva.js";
@@ -16,15 +16,16 @@ import { Button } from "react-aria-components";
16
16
  import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
17
17
  import { getLocalTimeZone, now, toCalendarDateTime, today } from "@internationalized/date";
18
18
  //#region src/components/inputs/DateTime/shared/DatePickerInput.tsx
19
- var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, isDirty, isRequired, disableManualEntry, placeholder, className, onOpenDropdown, ...props }) => {
19
+ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonProps, isDisabled, isInvalid, disableDropdown, variant, size, isDateTime, isClearable, headerProps, todayIcon, todayIconButtonSize = "none", isDirty, isRequired, disableManualEntry, autoFixYear = false, placeholder, className, onOpenDropdown, ...props }) => {
20
20
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
21
21
  const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
22
+ const datePickerInputContentRowCva = UIStyle.useCva("datePickerInput.contentRowCva", datePickerInputContentRow);
22
23
  const [canClear, setCanClear] = useState(false);
23
24
  const { hoverProps, isHovered } = useHover({ isDisabled });
24
25
  const [isFocused, setIsFocused] = useState(false);
25
26
  const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: (isFocusWithin) => {
26
27
  setIsFocused(isFocusWithin);
27
- if (!isFocusWithin) {
28
+ if (!isFocusWithin && autoFixYear) {
28
29
  dateFieldRef.current?.autoFixYear();
29
30
  endDateFieldRef.current?.autoFixYear();
30
31
  }
@@ -41,6 +42,7 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
41
42
  if (endFieldProps) endFieldProps.onChange?.(null);
42
43
  setCanClear(false);
43
44
  fieldProps.onBlur?.(null);
45
+ endFieldProps?.onBlur?.(null);
44
46
  },
45
47
  getContainer: () => containerRef.current
46
48
  }));
@@ -51,7 +53,10 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
51
53
  dateFieldRef.current?.clearField();
52
54
  fieldProps.onChange?.(null);
53
55
  endDateFieldRef.current?.clearField();
56
+ endFieldProps?.onChange?.(null);
54
57
  setCanClear(false);
58
+ fieldProps.onBlur?.(null);
59
+ endFieldProps?.onBlur?.(null);
55
60
  };
56
61
  const onToday = () => {
57
62
  if (isDateTime) {
@@ -62,8 +67,11 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
62
67
  fieldProps.onChange?.(today(getLocalTimeZone()));
63
68
  if (endFieldProps) endFieldProps.onChange?.(today(getLocalTimeZone()));
64
69
  }
70
+ fieldProps.onBlur?.(null);
71
+ endFieldProps?.onBlur?.(null);
65
72
  };
66
73
  const hidePlaceholder = as === "floating" && !fieldProps.value && !isFocused;
74
+ const todayIconComponent = todayIcon === true ? TodayIcon : todayIcon || null;
67
75
  return /* @__PURE__ */ jsxs("div", {
68
76
  ref: containerRef,
69
77
  className: clsx(inputBaseCva({
@@ -95,19 +103,19 @@ var DatePickerInput = ({ ref, as, groupProps, fieldProps, endFieldProps, buttonP
95
103
  as,
96
104
  ...headerProps
97
105
  }), /* @__PURE__ */ jsxs("div", {
98
- className: "flex items-center gap-input-gap-input-text-to-elements",
106
+ className: datePickerInputContentRowCva({ size }),
99
107
  children: [
100
108
  disableManualEntry && /* @__PURE__ */ jsx(Button, {
101
109
  onPress: onOpenDropdown,
102
110
  className: "absolute inset-0 z-0",
103
111
  isDisabled
104
112
  }),
105
- todayIcon && /* @__PURE__ */ jsx(IconButton, {
113
+ todayIconComponent && /* @__PURE__ */ jsx(InlineIconButton, {
106
114
  label: "",
107
- icon: TodayIcon,
108
- size: "none",
115
+ icon: todayIconComponent,
116
+ size: todayIconButtonSize,
109
117
  onPress: onToday,
110
- className: "relative z-1"
118
+ className: "relative z-1 !border-none"
111
119
  }),
112
120
  disableManualEntry && placeholder && !fieldProps.value ? /* @__PURE__ */ jsx(Typography, {
113
121
  size: "label-1",
@@ -74,7 +74,10 @@ var TimePickerInput = ({ ref, as, fieldProps, state, isDisabled, isDirty, isRequ
74
74
  as
75
75
  }), "flex items-center gap-input-gap-trailing-elements py-0! pl-0!"),
76
76
  children: [isClearable && /* @__PURE__ */ jsx(InputClear, {
77
- onClear: () => state.setValue(null),
77
+ onClear: () => {
78
+ state.setValue(null);
79
+ fieldProps.onBlur?.(null);
80
+ },
78
81
  show: canClear
79
82
  }), (!disableDropdown || disableManualEntry) && /* @__PURE__ */ jsx(InlineIconButton, {
80
83
  label: "",
@@ -0,0 +1,3 @@
1
+ import { IconButtonProps } from '../../../buttons/IconButton/IconButton';
2
+ export type DatePickerTodayIcon = boolean | IconButtonProps["icon"];
3
+ export type DatePickerTodayIconButtonSize = IconButtonProps["size"];
@@ -0,0 +1,7 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import { InputSizeProps } from '../../shared/input.cva';
3
+ export declare const datePickerInputContentRow: (props?: ({
4
+ size?: "small" | "default" | "extra-small" | "large" | null | undefined;
5
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
6
+ export interface DatePickerInputContentRowProps extends VariantProps<typeof datePickerInputContentRow>, InputSizeProps {
7
+ }
@@ -0,0 +1,13 @@
1
+ import { cva } from "class-variance-authority";
2
+ //#region src/components/inputs/DateTime/shared/datePickerInput.cva.ts
3
+ var datePickerInputContentRow = cva("flex items-center gap-input-gap-input-text-to-elements", {
4
+ variants: { size: {
5
+ "extra-small": "",
6
+ small: "",
7
+ default: "",
8
+ large: ""
9
+ } },
10
+ defaultVariants: { size: "default" }
11
+ });
12
+ //#endregion
13
+ export { datePickerInputContentRow };
@@ -1,14 +1,16 @@
1
1
  import { InfoIcon } from "../../../assets/icons/Info.js";
2
+ import { UIStyle } from "../../../config/uiStyle.context.js";
2
3
  import { Typography } from "../../text/Typography/Typography.js";
3
4
  import { Tooltip as Tooltip$1 } from "../../overlays/Tooltip/Tooltip.js";
4
5
  import { FormFieldLabel } from "./FormFieldLabel.js";
6
+ import { formFieldHeader } from "./formFieldHeader.cva.js";
5
7
  import { jsx, jsxs } from "react/jsx-runtime";
6
8
  import { clsx } from "clsx";
7
9
  import { Focusable } from "react-aria-components";
8
10
  //#region src/components/inputs/FormField/FormFieldHeader.tsx
9
11
  var FormFieldHeader = ({ label, tooltipText, helperText, isRequired, rightContent, isHeaderHidden, isDisabled, className, labelProps }) => {
10
12
  return /* @__PURE__ */ jsxs("div", {
11
- className: clsx(isHeaderHidden ? "sr-only" : "mb-1", className),
13
+ className: clsx(UIStyle.useCva("formField.headerCva", formFieldHeader)({ visible: !isHeaderHidden }), className),
12
14
  children: [/* @__PURE__ */ jsxs("div", {
13
15
  className: "flex items-start justify-between",
14
16
  children: [/* @__PURE__ */ jsxs("div", {
@@ -0,0 +1,6 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ export declare const formFieldHeader: (props?: ({
3
+ visible?: boolean | null | undefined;
4
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
5
+ export interface FormFieldHeaderVariantProps extends VariantProps<typeof formFieldHeader> {
6
+ }
@@ -0,0 +1,11 @@
1
+ import { cva } from "class-variance-authority";
2
+ //#region src/components/inputs/FormField/formFieldHeader.cva.ts
3
+ var formFieldHeader = cva("", {
4
+ variants: { visible: {
5
+ true: "mb-1",
6
+ false: "sr-only"
7
+ } },
8
+ defaultVariants: { visible: true }
9
+ });
10
+ //#endregion
11
+ export { formFieldHeader };