@povio/ui 2.2.9-rc.3 → 2.2.9-rc.31

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 (117) hide show
  1. package/dist/components/buttons/Button/Button.d.ts +2 -1
  2. package/dist/components/buttons/Button/Button.js +41 -32
  3. package/dist/components/buttons/InlineIconButton/InlineIconButton.d.ts +2 -1
  4. package/dist/components/buttons/InlineIconButton/InlineIconButton.js +2 -2
  5. package/dist/components/inputs/Checkbox/Checkbox.js +6 -1
  6. package/dist/components/inputs/Checkbox/checkbox.cva.d.ts +3 -0
  7. package/dist/components/inputs/Checkbox/checkbox.cva.js +2 -1
  8. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +8 -3
  9. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +80 -6
  10. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +7 -2
  11. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +83 -6
  12. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +8 -2
  13. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +83 -7
  14. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +2 -1
  15. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +64 -4
  16. package/dist/components/inputs/DateTime/shared/Calendar.d.ts +5 -2
  17. package/dist/components/inputs/DateTime/shared/Calendar.js +23 -6
  18. package/dist/components/inputs/DateTime/shared/CalendarCell.d.ts +1 -1
  19. package/dist/components/inputs/DateTime/shared/CalendarCell.js +3 -3
  20. package/dist/components/inputs/DateTime/shared/CalendarGrid.d.ts +1 -1
  21. package/dist/components/inputs/DateTime/shared/DateField.js +3 -10
  22. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +6 -2
  23. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +65 -55
  24. package/dist/components/inputs/DateTime/shared/DateSegmentItem.d.ts +14 -0
  25. package/dist/components/inputs/DateTime/shared/DateSegmentItem.js +19 -6
  26. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +4 -2
  27. package/dist/components/inputs/DateTime/shared/datePicker.types.d.ts +4 -0
  28. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.d.ts +7 -0
  29. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.js +13 -0
  30. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.d.ts +6 -0
  31. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.js +21 -0
  32. package/dist/components/inputs/DateTime/shared/dateSegment.utils.d.ts +2 -0
  33. package/dist/components/inputs/DateTime/shared/dateSegment.utils.js +9 -0
  34. package/dist/components/inputs/DateTime/shared/dateSegment.utils.spec.d.ts +1 -0
  35. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.d.ts +35 -0
  36. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.js +80 -0
  37. package/dist/components/inputs/File/FileUpload.js +1 -0
  38. package/dist/components/inputs/File/shared/InputUploadContent.js +1 -0
  39. package/dist/components/inputs/FormField/FormField.d.ts +3 -3
  40. package/dist/components/inputs/FormField/FormFieldHeader.js +3 -1
  41. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +6 -0
  42. package/dist/components/inputs/FormField/formFieldHeader.cva.js +11 -0
  43. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +5 -2
  44. package/dist/components/inputs/Input/NumberInput/NumberInput.js +76 -7
  45. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.d.ts +45 -0
  46. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.js +146 -0
  47. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +35 -0
  48. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +232 -0
  49. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +3 -1
  50. package/dist/components/inputs/Input/TextInput/TextInput.js +79 -7
  51. package/dist/components/inputs/Input/shared/InputContent.js +7 -6
  52. package/dist/components/inputs/Input/shared/numberStatic.utils.d.ts +1 -0
  53. package/dist/components/inputs/Input/shared/numberStatic.utils.js +7 -0
  54. package/dist/components/inputs/Inputs/InputItem.d.ts +15 -18
  55. package/dist/components/inputs/Inputs/InputItem.js +2 -0
  56. package/dist/components/inputs/RadioGroup/RadioGroup.js +17 -9
  57. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +3 -0
  58. package/dist/components/inputs/RadioGroup/radio.cva.js +2 -1
  59. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +6 -2
  60. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +99 -6
  61. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +1 -1
  62. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +15 -10
  63. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +25 -19
  64. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +3 -4
  65. package/dist/components/inputs/Selection/Select/QuerySelect.js +8 -35
  66. package/dist/components/inputs/Selection/Select/Select.d.ts +7 -3
  67. package/dist/components/inputs/Selection/Select/Select.js +112 -4
  68. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +4 -1
  69. package/dist/components/inputs/Selection/shared/SelectBase.js +3 -2
  70. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  71. package/dist/components/inputs/Selection/shared/SelectDesktop.js +8 -4
  72. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  73. package/dist/components/inputs/Selection/shared/SelectInput.js +13 -2
  74. package/dist/components/inputs/Selection/shared/SelectListBox.d.ts +2 -2
  75. package/dist/components/inputs/Selection/shared/SelectListBox.js +3 -3
  76. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  77. package/dist/components/inputs/Selection/shared/SelectMobile.js +5 -3
  78. package/dist/components/inputs/Selection/shared/select.context.d.ts +3 -2
  79. package/dist/components/inputs/Selection/shared/select.context.js +27 -4
  80. package/dist/components/inputs/Selection/shared/select.types.d.ts +3 -2
  81. package/dist/components/inputs/Selection/shared/selectDesktop.cva.d.ts +3 -0
  82. package/dist/components/inputs/Selection/shared/selectDesktop.cva.js +5 -0
  83. package/dist/components/inputs/Selection/shared/staticSelect.utils.d.ts +23 -0
  84. package/dist/components/inputs/Selection/shared/staticSelect.utils.js +37 -0
  85. package/dist/components/inputs/Selection/shared/staticSelect.utils.spec.d.ts +1 -0
  86. package/dist/components/inputs/Skeleton/InputFrame.d.ts +68 -0
  87. package/dist/components/inputs/Skeleton/InputFrame.js +178 -0
  88. package/dist/components/inputs/TextEditor/TextEditor.js +1 -0
  89. package/dist/components/inputs/Toggle/Toggle.js +6 -1
  90. package/dist/components/inputs/Toggle/toggle.cva.d.ts +3 -0
  91. package/dist/components/inputs/Toggle/toggle.cva.js +2 -1
  92. package/dist/components/inputs/shared/CheckContent.d.ts +2 -1
  93. package/dist/components/inputs/shared/CheckContent.js +3 -4
  94. package/dist/components/inputs/shared/InputClear.d.ts +2 -1
  95. package/dist/components/inputs/shared/InputClear.js +13 -1
  96. package/dist/components/inputs/shared/StaticInput.d.ts +38 -0
  97. package/dist/components/inputs/shared/TooltipWrapper.js +5 -1
  98. package/dist/components/inputs/shared/input.cva.d.ts +10 -0
  99. package/dist/components/inputs/shared/input.cva.js +19 -1
  100. package/dist/components/inputs/shared/tooltipWrapper.cva.d.ts +4 -0
  101. package/dist/components/inputs/shared/tooltipWrapper.cva.js +5 -0
  102. package/dist/config/uiConfig.context.d.ts +8 -2
  103. package/dist/config/uiConfig.context.js +12 -1
  104. package/dist/config/uiStyle.context.d.ts +20 -3
  105. package/dist/helpers/dynamicInputs.d.ts +1 -1
  106. package/dist/helpers/dynamicInputs.js +3 -0
  107. package/dist/hooks/useIntersectionObserver.d.ts +1 -1
  108. package/dist/hooks/useIntersectionObserver.js +29 -10
  109. package/dist/hooks/useQueryAutocomplete.d.ts +5 -16
  110. package/dist/hooks/useQueryAutocomplete.js +13 -3
  111. package/dist/index.d.ts +7 -0
  112. package/dist/index.js +4 -2
  113. package/dist/utils/date-time.utils.d.ts +30 -9
  114. package/dist/utils/date-time.utils.js +113 -1
  115. package/dist/utils/query.utils.d.ts +4 -0
  116. package/dist/utils/query.utils.js +8 -0
  117. package/package.json +1 -1
@@ -0,0 +1,146 @@
1
+ import { UIConfig } from "../../../../config/uiConfig.context.js";
2
+ import { FormFieldLabel } from "../../FormField/FormFieldLabel.js";
3
+ import { InputClear } from "../../shared/InputClear.js";
4
+ import { FormField } from "../../FormField/FormField.js";
5
+ import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { clsx } from "clsx";
8
+ import { useEffect, useRef } from "react";
9
+ import { Input, useLocale } from "react-aria-components";
10
+ import { useFocusVisible, useNumberField } from "react-aria";
11
+ import { mergeRefs } from "@react-aria/utils";
12
+ import { useNumberFieldState } from "react-stately";
13
+ //#region src/components/inputs/Input/NumberRangeInput/NumberRangeField.tsx
14
+ var NumberRangeValueField = ({ label, value, placeholder, isDisabled, isInvalid, isRequired, formatOptions, hideInnerLabels, autoFocusOnMount, isClearable, className, onChange, onClear, onBlur, ...rest }) => {
15
+ const ui = UIConfig.useConfig();
16
+ const { locale } = useLocale();
17
+ const { isFocusVisible } = useFocusVisible();
18
+ const inputRef = useRef(null);
19
+ const numberFieldRef = useRef(null);
20
+ useEffect(() => {
21
+ if (!autoFocusOnMount || isDisabled) return;
22
+ requestAnimationFrame(() => inputRef.current?.focus());
23
+ }, [autoFocusOnMount, isDisabled]);
24
+ const numberProps = {
25
+ ...rest,
26
+ label,
27
+ value: value ?? NaN,
28
+ placeholder,
29
+ isDisabled,
30
+ isInvalid,
31
+ isRequired,
32
+ onChange,
33
+ onBlur: (e) => onBlur?.({ target: e.target }),
34
+ locale,
35
+ formatOptions: formatOptions ?? ui.numberInput.formatOptions
36
+ };
37
+ const { labelProps, inputProps } = useNumberField(numberProps, useNumberFieldState(numberProps), numberFieldRef);
38
+ return /* @__PURE__ */ jsxs("div", {
39
+ className: "min-w-0 flex-1",
40
+ children: [/* @__PURE__ */ jsx(FormFieldLabel, {
41
+ label,
42
+ labelProps,
43
+ isRequired,
44
+ isDisabled,
45
+ className: clsx(hideInnerLabels && "sr-only")
46
+ }), /* @__PURE__ */ jsxs("div", {
47
+ className: "flex items-center gap-input-gap-trailing-elements",
48
+ children: [/* @__PURE__ */ jsx(Input, {
49
+ ...inputProps,
50
+ ref: mergeRefs(inputRef, numberFieldRef),
51
+ placeholder: inputProps.placeholder,
52
+ className: clsx("w-full min-w-0 bg-transparent outline-none", className),
53
+ onFocus: (e) => {
54
+ inputProps.onFocus?.(e);
55
+ if (isFocusVisible) e.target.select();
56
+ }
57
+ }), isClearable && /* @__PURE__ */ jsx(InputClear, {
58
+ onClear,
59
+ show: value !== null && !isDisabled
60
+ })]
61
+ })]
62
+ });
63
+ };
64
+ var NumberRangeField = ({ ref, as, className, inputClassName, minInputClassName, maxInputClassName, inputBaseClassName, inputSizeClassName, formFieldProps, headerProps, rangeValue, effectiveError, minPlaceholder, maxPlaceholder, minLabel, maxLabel, hideInnerLabels, isDirty, isClearable, autoFocusOnMount, isDisabled, isRequired, isEmpty, isHovered, isFocused, isFocusVisible, focusWithinProps, hoverProps, onRangeSideChange, onRangeSideClear, onBlur, ...numberFieldProps }) => /* @__PURE__ */ jsx(TooltipWrapper, {
65
+ as,
66
+ error: effectiveError,
67
+ triggerTabIndex: as === "inline" ? -1 : void 0,
68
+ children: /* @__PURE__ */ jsx(FormField, {
69
+ ...formFieldProps,
70
+ ref,
71
+ as,
72
+ className: clsx("group w-full", className),
73
+ tabIndex: as === "inline" ? -1 : void 0,
74
+ children: /* @__PURE__ */ jsx("div", {
75
+ className: clsx(inputBaseClassName, "group/date-picker-content relative flex min-w-input-width-min-width items-center justify-between gap-2", inputClassName),
76
+ "data-rac": "",
77
+ "data-hovered": isHovered || void 0,
78
+ "data-disabled": isDisabled || void 0,
79
+ "data-is-disabled": isDisabled || void 0,
80
+ "data-invalid": !!effectiveError || void 0,
81
+ "data-is-empty": isEmpty || void 0,
82
+ "data-focus-within": isFocused || void 0,
83
+ "data-focus-visible": isFocused && isFocusVisible || void 0,
84
+ "data-has-selection": !isEmpty || void 0,
85
+ "data-is-dirty": isDirty || void 0,
86
+ "data-is-required": isRequired || void 0,
87
+ "data-is-filled": !isEmpty || void 0,
88
+ ...focusWithinProps,
89
+ ...hoverProps,
90
+ children: /* @__PURE__ */ jsxs("div", {
91
+ className: clsx("flex w-full items-center gap-input-gap-input-text-to-elements pr-0!", inputSizeClassName),
92
+ children: [
93
+ as && ["filter", "floating"].includes(as) && headerProps && /* @__PURE__ */ jsx(FormFieldLabel, {
94
+ as,
95
+ ...headerProps
96
+ }),
97
+ /* @__PURE__ */ jsx(NumberRangeValueField, {
98
+ ...numberFieldProps,
99
+ label: minLabel,
100
+ placeholder: minPlaceholder,
101
+ value: rangeValue.min,
102
+ onChange: (nextValue) => {
103
+ onRangeSideChange("min", nextValue);
104
+ },
105
+ onBlur,
106
+ isDisabled,
107
+ isInvalid: !!effectiveError,
108
+ isRequired,
109
+ hideInnerLabels,
110
+ autoFocusOnMount,
111
+ isClearable,
112
+ onClear: () => {
113
+ onRangeSideClear("min");
114
+ },
115
+ className: minInputClassName
116
+ }),
117
+ /* @__PURE__ */ jsx("span", {
118
+ className: clsx("pointer-events-none shrink-0 select-none text-label-2 text-text-default-3", isDisabled && "text-interactive-text-secondary-disabled"),
119
+ children: "-"
120
+ }),
121
+ /* @__PURE__ */ jsx(NumberRangeValueField, {
122
+ ...numberFieldProps,
123
+ label: maxLabel,
124
+ placeholder: maxPlaceholder,
125
+ value: rangeValue.max,
126
+ onChange: (nextValue) => {
127
+ onRangeSideChange("max", nextValue);
128
+ },
129
+ onBlur,
130
+ isDisabled,
131
+ isInvalid: !!effectiveError,
132
+ isRequired,
133
+ hideInnerLabels,
134
+ isClearable,
135
+ onClear: () => {
136
+ onRangeSideClear("max");
137
+ },
138
+ className: maxInputClassName
139
+ })
140
+ ]
141
+ })
142
+ })
143
+ })
144
+ });
145
+ //#endregion
146
+ export { NumberRangeField };
@@ -0,0 +1,35 @@
1
+ import { FocusEvent, Ref } from 'react';
2
+ import { NumberFieldProps as AriaNumberFieldProps } from 'react-aria-components';
3
+ import { FieldValues } from 'react-hook-form';
4
+ import { FormFieldProps } from '../../FormField/FormField';
5
+ import { NumberRangeValue } from './NumberRangeField';
6
+ import { ControlProps } from '../../shared/form.types';
7
+ import { InputVariantProps } from '../../shared/input.cva';
8
+ export type { NumberRangeValue } from './NumberRangeField';
9
+ interface NumberRangeInputBaseProps extends FormFieldProps, InputVariantProps, Omit<AriaNumberFieldProps, "className" | "defaultValue" | "label" | "maxValue" | "minValue" | "onBlur" | "onChange" | "value"> {
10
+ ref?: Ref<HTMLDivElement>;
11
+ value?: NumberRangeValue | null;
12
+ minValue?: number | null;
13
+ maxValue?: number | null;
14
+ minPlaceholder?: string;
15
+ maxPlaceholder?: string;
16
+ minLabel?: string;
17
+ maxLabel?: string;
18
+ invalidRangeError?: string;
19
+ inputClassName?: string;
20
+ minInputClassName?: string;
21
+ maxInputClassName?: string;
22
+ hideInnerLabels?: boolean;
23
+ isDirty?: boolean;
24
+ isClearable?: boolean;
25
+ autoFocusOnMount?: boolean;
26
+ onChange?: (value: NumberRangeValue) => void;
27
+ onMinChange?: (value: number | null) => void;
28
+ onMaxChange?: (value: number | null) => void;
29
+ onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
30
+ }
31
+ export type NumberRangeInputProps = NumberRangeInputBaseProps & {
32
+ renderStaticInput?: boolean;
33
+ };
34
+ export type ControlledNumberRangeInputProps<TFieldValues extends FieldValues> = ControlProps<NumberRangeInputProps, TFieldValues>;
35
+ export declare const NumberRangeInput: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledNumberRangeInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,232 @@
1
+ import { UIStyle } from "../../../../config/uiStyle.context.js";
2
+ import { UIConfig } from "../../../../config/uiConfig.context.js";
3
+ import { InputClear } from "../../shared/InputClear.js";
4
+ import { inputBase, inputSize } from "../../shared/input.cva.js";
5
+ import { InputFrame } from "../../Skeleton/InputFrame.js";
6
+ import { getStaticNumberDisplayValue } from "../shared/numberStatic.utils.js";
7
+ import { NumberRangeField } from "./NumberRangeField.js";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ import { clsx } from "clsx";
10
+ import { useEffect, useState } from "react";
11
+ import { useLocale } from "react-aria-components";
12
+ import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
13
+ import { Controller, useWatch } from "react-hook-form";
14
+ //#region src/components/inputs/Input/NumberRangeInput/NumberRangeInput.tsx
15
+ var EMPTY_RANGE = {
16
+ min: null,
17
+ max: null
18
+ };
19
+ var normalizeRangeValue = (value, minValue, maxValue) => {
20
+ if (value) return value;
21
+ return {
22
+ min: minValue ?? null,
23
+ max: maxValue ?? null
24
+ };
25
+ };
26
+ var NumberRangeInputBase = (props) => {
27
+ const ui = UIConfig.useConfig();
28
+ const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
29
+ const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
30
+ const { ref, label, tooltipText, helperText, isRequired, rightContent, isDisabled, headerClassName, errorClassName, isHeaderHidden, error, className, inputClassName, minInputClassName, maxInputClassName, value, minValue, maxValue, minPlaceholder = "Min", maxPlaceholder = "Max", minLabel = "Minimum", maxLabel = "Maximum", invalidRangeError = "Minimum cannot be greater than maximum", hideInnerLabels = true, isDirty, autoFocusOnMount, onChange, onMinChange, onMaxChange, onBlur, isClearable: isClearableProps, as: asProp, variant: variantProps, size: sizeProps, hideLabel: hideLabelProps, ...rest } = props;
31
+ const isClearable = isClearableProps ?? ui.input.isClearable;
32
+ const as = asProp ?? ui.input.as;
33
+ const variant = variantProps ?? ui.input.variant;
34
+ const size = sizeProps ?? ui.input.size;
35
+ const hideLabel = hideLabelProps ?? ui.input.hideLabel;
36
+ const rangeValue = normalizeRangeValue(value, minValue, maxValue);
37
+ const isEmpty = rangeValue.min === null && rangeValue.max === null;
38
+ const rangeError = rangeValue.min !== null && rangeValue.max !== null && rangeValue.min > rangeValue.max ? invalidRangeError : void 0;
39
+ const effectiveError = error || rangeError;
40
+ const { hoverProps, isHovered } = useHover({ isDisabled });
41
+ const { isFocusVisible } = useFocusVisible();
42
+ const [isFocused, setIsFocused] = useState(false);
43
+ const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setIsFocused });
44
+ const formFieldProps = {
45
+ error: effectiveError,
46
+ label,
47
+ tooltipText,
48
+ helperText,
49
+ isRequired,
50
+ rightContent,
51
+ isHeaderHidden: isHeaderHidden || as === "inline" || as === "filter" || as === "floating",
52
+ hideLabel,
53
+ isDisabled,
54
+ headerClassName,
55
+ errorClassName
56
+ };
57
+ const headerProps = {
58
+ label,
59
+ tooltipText,
60
+ helperText,
61
+ isRequired,
62
+ rightContent,
63
+ isHeaderHidden: hideLabel || isHeaderHidden,
64
+ isDisabled,
65
+ className: headerClassName
66
+ };
67
+ const updateRange = (side, nextValue) => {
68
+ const nextRange = {
69
+ ...rangeValue,
70
+ [side]: nextValue
71
+ };
72
+ onChange?.(nextRange);
73
+ if (side === "min") onMinChange?.(nextValue);
74
+ else onMaxChange?.(nextValue);
75
+ };
76
+ const clearRangeSide = (side) => {
77
+ updateRange(side, null);
78
+ onBlur?.({ target: { value: "" } });
79
+ };
80
+ return /* @__PURE__ */ jsx(NumberRangeField, {
81
+ ...rest,
82
+ ref,
83
+ as,
84
+ className,
85
+ inputClassName,
86
+ minInputClassName,
87
+ maxInputClassName,
88
+ inputBaseClassName: inputBaseCva({
89
+ variant,
90
+ as
91
+ }),
92
+ inputSizeClassName: inputSizeCva({
93
+ size,
94
+ as
95
+ }),
96
+ formFieldProps,
97
+ headerProps,
98
+ rangeValue,
99
+ effectiveError,
100
+ minPlaceholder,
101
+ maxPlaceholder,
102
+ minLabel,
103
+ maxLabel,
104
+ hideInnerLabels,
105
+ isDirty,
106
+ isClearable,
107
+ autoFocusOnMount,
108
+ isDisabled,
109
+ isRequired,
110
+ isEmpty,
111
+ isHovered,
112
+ isFocused,
113
+ isFocusVisible,
114
+ focusWithinProps,
115
+ hoverProps,
116
+ onRangeSideChange: updateRange,
117
+ onRangeSideClear: clearRangeSide,
118
+ onBlur
119
+ });
120
+ };
121
+ var NumberRangeInput = ({ renderStaticInput, ...props }) => {
122
+ const ui = UIConfig.useConfig();
123
+ const { locale } = useLocale();
124
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
125
+ const [shouldFocus, setShouldFocus] = useState(false);
126
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
127
+ control: props.formControl.control,
128
+ name: props.formControl.name
129
+ }) : props.value;
130
+ let isFormControlDisabled = false;
131
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
132
+ useEffect(() => {
133
+ if (!renderInput || !shouldFocus) return;
134
+ setShouldFocus(false);
135
+ }, [renderInput, shouldFocus]);
136
+ if (!renderInput) {
137
+ const staticValue = normalizeRangeValue(watchedValue, props.minValue, props.maxValue);
138
+ const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
139
+ const formatter = new Intl.NumberFormat(locale, formatOptions);
140
+ const minDisplay = getStaticNumberDisplayValue(staticValue.min, formatter);
141
+ const maxDisplay = getStaticNumberDisplayValue(staticValue.max, formatter);
142
+ const hasValue = minDisplay !== null || maxDisplay !== null;
143
+ const rangeError = staticValue.min !== null && staticValue.max !== null && staticValue.min > staticValue.max ? props.invalidRangeError ?? "Minimum cannot be greater than maximum" : void 0;
144
+ const effectiveError = props.error || rangeError;
145
+ const as = props.as ?? ui.input.as;
146
+ let isDisabled = !!props.isDisabled;
147
+ if (isFormControlDisabled) isDisabled = true;
148
+ const isClearable = props.isClearable ?? ui.input.isClearable;
149
+ const dataAttributes = {
150
+ dataIsEmpty: !hasValue,
151
+ dataIsFilled: hasValue,
152
+ dataIsDirty: props.isDirty,
153
+ dataIsRequired: props.isRequired,
154
+ dataIsDisabled: isDisabled,
155
+ dataDisabled: isDisabled,
156
+ dataInvalid: !!effectiveError,
157
+ dataHasSelection: hasValue
158
+ };
159
+ return /* @__PURE__ */ jsx(InputFrame, {
160
+ ...props,
161
+ error: effectiveError,
162
+ isDisabled,
163
+ className: clsx("group w-full", as === "inline" && "h-full", props.className),
164
+ inputClassName: props.inputClassName,
165
+ contentWrapperClassName: "flex w-full items-center gap-input-gap-input-text-to-elements",
166
+ dataAttributes,
167
+ renderStatic: true,
168
+ onStaticInteract: (focus) => {
169
+ setShouldFocus(focus);
170
+ setRenderInput(true);
171
+ },
172
+ isClearable: false,
173
+ children: (dataAttributeProps) => /* @__PURE__ */ jsxs(Fragment, { children: [
174
+ /* @__PURE__ */ jsx("input", {
175
+ readOnly: true,
176
+ disabled: isDisabled,
177
+ tabIndex: -1,
178
+ value: minDisplay ?? "",
179
+ placeholder: props.minPlaceholder ?? "Min",
180
+ className: clsx("w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.minInputClassName),
181
+ ...dataAttributeProps,
182
+ "data-rac": true
183
+ }),
184
+ isClearable && /* @__PURE__ */ jsx(InputClear, {
185
+ onClear: () => {},
186
+ renderStatic: true
187
+ }),
188
+ /* @__PURE__ */ jsx("span", {
189
+ className: "pointer-events-none shrink-0 select-none text-label-2 text-text-default-3",
190
+ children: "-"
191
+ }),
192
+ /* @__PURE__ */ jsx("input", {
193
+ readOnly: true,
194
+ disabled: isDisabled,
195
+ tabIndex: -1,
196
+ value: maxDisplay ?? "",
197
+ placeholder: props.maxPlaceholder ?? "Max",
198
+ className: clsx("w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.maxInputClassName),
199
+ ...dataAttributeProps,
200
+ "data-rac": true
201
+ }),
202
+ isClearable && /* @__PURE__ */ jsx(InputClear, {
203
+ onClear: () => {},
204
+ renderStatic: true
205
+ })
206
+ ] })
207
+ });
208
+ }
209
+ if ("formControl" in props && props.formControl) {
210
+ const { formControl, ref, ...innerProps } = props;
211
+ return /* @__PURE__ */ jsx(Controller, {
212
+ control: formControl.control,
213
+ name: formControl.name,
214
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(NumberRangeInputBase, {
215
+ ...innerProps,
216
+ ref,
217
+ value: field.value ?? EMPTY_RANGE,
218
+ onChange: field.onChange,
219
+ onBlur: field.onBlur,
220
+ isDisabled: field.disabled || props.isDisabled,
221
+ error: props.error ?? error?.message,
222
+ autoFocusOnMount: shouldFocus
223
+ })
224
+ });
225
+ }
226
+ return /* @__PURE__ */ jsx(NumberRangeInputBase, {
227
+ ...props,
228
+ autoFocusOnMount: shouldFocus
229
+ });
230
+ };
231
+ //#endregion
232
+ export { NumberRangeInput };
@@ -13,9 +13,11 @@ interface TextInputBaseProps extends FormFieldProps, InputVariantProps, Omit<Inp
13
13
  type?: AllowedHTMLInputTypeAttribute;
14
14
  todayIcon?: boolean;
15
15
  isDirty?: boolean;
16
+ autoFocusOnMount?: boolean;
16
17
  }
17
18
  export interface TextInputProps extends TextInputBaseProps {
19
+ renderStaticInput?: boolean;
18
20
  }
19
21
  export type ControlledTextInputProps<TFieldValues extends FieldValues> = ControlProps<TextInputProps, TFieldValues>;
20
- export declare const TextInput: <TFieldValues extends FieldValues>(props: ControlledTextInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const TextInput: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledTextInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
21
23
  export {};
@@ -3,20 +3,21 @@ import { UIConfig } from "../../../../config/uiConfig.context.js";
3
3
  import { inputBase } from "../../shared/input.cva.js";
4
4
  import { FormField } from "../../FormField/FormField.js";
5
5
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
6
+ import { InputFrame } from "../../Skeleton/InputFrame.js";
6
7
  import { InputContent } from "../shared/InputContent.js";
7
8
  import { jsx } from "react/jsx-runtime";
8
9
  import { clsx } from "clsx";
9
- import { useRef } from "react";
10
+ import { useEffect, useRef, useState } from "react";
10
11
  import { Input } from "react-aria-components";
11
12
  import { useFocusVisible, useTextField } from "react-aria";
12
13
  import { mergeRefs } from "@react-aria/utils";
13
- import { Controller } from "react-hook-form";
14
+ import { Controller, useWatch } from "react-hook-form";
14
15
  //#region src/components/inputs/Input/TextInput/TextInput.tsx
15
16
  var TextInputBase = (props) => {
16
17
  const ui = UIConfig.useConfig();
17
18
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
18
19
  const inputRef = useRef(null);
19
- const { ref, inputClassName, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, className, unit, isLoading, action, leadingIcon, trailingIcon, value, onChange, onBlur, as = ui.input.as, hideLabel = ui.input.hideLabel, variant = ui.input.variant, size = ui.input.size, isClearable = ui.input.isClearable, ...rest } = props;
20
+ const { ref, inputClassName, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, className, unit, isLoading, action, leadingIcon, trailingIcon, value, onChange, onBlur, as = ui.input.as, hideLabel = ui.input.hideLabel, variant = ui.input.variant, size = ui.input.size, isClearable = ui.input.isClearable, autoFocusOnMount, ...rest } = props;
20
21
  const textFieldRef = useRef(null);
21
22
  const { isFocusVisible } = useFocusVisible();
22
23
  const { labelProps, inputProps } = useTextField({
@@ -29,6 +30,10 @@ var TextInputBase = (props) => {
29
30
  onChange,
30
31
  onBlur
31
32
  }, textFieldRef);
33
+ useEffect(() => {
34
+ if (!autoFocusOnMount || isDisabled) return;
35
+ requestAnimationFrame(() => inputRef.current?.focus());
36
+ }, [autoFocusOnMount, isDisabled]);
32
37
  const formFieldProps = {
33
38
  error,
34
39
  label,
@@ -84,6 +89,8 @@ var TextInputBase = (props) => {
84
89
  ...rest
85
90
  }), inputClassName),
86
91
  onClick: () => inputRef.current?.focus(),
92
+ "data-is-empty": value === "" || value === null || value === void 0 || void 0,
93
+ "data-is-required": isRequired || void 0,
87
94
  children: /* @__PURE__ */ jsx(InputContent, {
88
95
  ...inputContentProps,
89
96
  headerProps,
@@ -109,7 +116,67 @@ var TextInputBase = (props) => {
109
116
  })
110
117
  });
111
118
  };
112
- var TextInput = (props) => {
119
+ var TextInput = ({ renderStaticInput, ...props }) => {
120
+ const ui = UIConfig.useConfig();
121
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
122
+ const [shouldFocus, setShouldFocus] = useState(false);
123
+ const inputRef = useRef(null);
124
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
125
+ control: props.formControl.control,
126
+ name: props.formControl.name
127
+ }) : props.value;
128
+ let isFormControlDisabled = false;
129
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
130
+ const staticValue = watchedValue ?? props.value ?? props.defaultValue ?? "";
131
+ const inputType = props.type;
132
+ if (!renderInput && inputType === "password" && `${staticValue}`.length > 0) setRenderInput(true);
133
+ useEffect(() => {
134
+ if (!renderInput || !shouldFocus) return;
135
+ requestAnimationFrame(() => inputRef.current?.focus());
136
+ setShouldFocus(false);
137
+ }, [renderInput, shouldFocus]);
138
+ if (!renderInput) {
139
+ const as = props.as ?? ui.input.as;
140
+ let isDisabled = !!props.isDisabled;
141
+ if (isFormControlDisabled) isDisabled = true;
142
+ const maskedPasswordValue = inputType === "password" && `${staticValue}`.length > 0 ? "•".repeat(`${staticValue}`.length) : staticValue;
143
+ const displayValue = maskedPasswordValue == null ? "" : `${maskedPasswordValue}`;
144
+ const hasValue = displayValue !== "";
145
+ const dataAttributes = {
146
+ dataIsEmpty: !hasValue,
147
+ dataIsFilled: hasValue,
148
+ dataIsDirty: props.isDirty,
149
+ dataIsRequired: props.isRequired,
150
+ dataIsDisabled: isDisabled,
151
+ dataDisabled: isDisabled,
152
+ dataInvalid: !!props.error,
153
+ dataHasSelection: hasValue
154
+ };
155
+ return /* @__PURE__ */ jsx(InputFrame, {
156
+ ...props,
157
+ isDisabled,
158
+ className: clsx("group w-full", as === "inline" && "h-full", props.className),
159
+ dataAttributes,
160
+ renderStatic: true,
161
+ onStaticInteract: (focus) => {
162
+ setShouldFocus(focus);
163
+ setRenderInput(true);
164
+ },
165
+ inputClassName: props.inputClassName,
166
+ children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
167
+ ref: inputRef,
168
+ type: inputType === "hidden" ? "password" : inputType,
169
+ readOnly: true,
170
+ disabled: isDisabled,
171
+ tabIndex: -1,
172
+ value: displayValue,
173
+ placeholder: as === "floating" ? "" : props.placeholder,
174
+ className: "w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled",
175
+ ...dataAttributeProps,
176
+ "data-rac": true
177
+ })
178
+ });
179
+ }
113
180
  if ("formControl" in props && props.formControl) {
114
181
  const { formControl, ref, ...innerProps } = props;
115
182
  return /* @__PURE__ */ jsx(Controller, {
@@ -117,17 +184,22 @@ var TextInput = (props) => {
117
184
  name: formControl.name,
118
185
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TextInputBase, {
119
186
  ...innerProps,
120
- ref: mergeRefs(ref, field.ref),
187
+ ref: mergeRefs(ref, field.ref, inputRef),
121
188
  value: field.value,
122
189
  onChange: field.onChange,
123
190
  onBlur: field.onBlur,
124
191
  isDirty,
125
192
  isDisabled: field.disabled || props.isDisabled,
126
- error: props.error ?? error?.message
193
+ error: props.error ?? error?.message,
194
+ autoFocusOnMount: shouldFocus
127
195
  })
128
196
  });
129
197
  }
130
- return /* @__PURE__ */ jsx(TextInputBase, { ...props });
198
+ return /* @__PURE__ */ jsx(TextInputBase, {
199
+ ...props,
200
+ ref: mergeRefs(props.ref, inputRef),
201
+ autoFocusOnMount: shouldFocus
202
+ });
131
203
  };
132
204
  //#endregion
133
205
  export { TextInput };
@@ -4,7 +4,7 @@ import { Loader } from "../../../status/Loader/Loader.js";
4
4
  import { InlineIconButton } from "../../../buttons/InlineIconButton/InlineIconButton.js";
5
5
  import { FormFieldLabel } from "../../FormField/FormFieldLabel.js";
6
6
  import { InputClear } from "../../shared/InputClear.js";
7
- import { inputSize } from "../../shared/input.cva.js";
7
+ import { inputContentWrapper, inputSize } from "../../shared/input.cva.js";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { clsx } from "clsx";
10
10
  import { isValidElement } from "react";
@@ -12,21 +12,22 @@ import { isValidElement } from "react";
12
12
  var InputContent = ({ leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, unit, isLoading, isDisabled, action, isClearable, value, onChange, onBlur, children, headerProps, as, size }) => {
13
13
  const typographyCva = UIStyle.useCva("typography.cva", typography);
14
14
  const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
15
+ const inputContentWrapperCva = UIStyle.useCva("input.contentWrapperCva", inputContentWrapper);
15
16
  const isLeadingIconElement = LeadingIcon && isValidElement(LeadingIcon);
16
17
  const isTrailingIconElement = TrailingIcon && isValidElement(TrailingIcon);
17
18
  const showClear = value != null && value !== "" && !isDisabled;
18
19
  return /* @__PURE__ */ jsxs("div", {
19
20
  className: "flex w-full items-center gap-input-gap-input-text-to-elements",
20
21
  children: [/* @__PURE__ */ jsxs("div", {
21
- className: clsx(inputSizeCva({
22
+ className: clsx("group/input-content flex w-full items-center gap-input-gap-input-text-to-elements pr-0!", as === "inline" && "h-full", inputSizeCva({
22
23
  size,
23
24
  as
24
- }), "group/input-content flex w-full items-center gap-input-gap-input-text-to-elements pr-0!", as === "inline" && "h-full"),
25
+ })),
25
26
  children: [LeadingIcon && /* @__PURE__ */ jsx("div", {
26
27
  className: clsx(!isLeadingIconElement && "pointer-events-none"),
27
28
  children: isLeadingIconElement ? LeadingIcon : /* @__PURE__ */ jsx(LeadingIcon, { className: "size-6 text-interactive-text-secondary-idle" })
28
29
  }), /* @__PURE__ */ jsxs("div", {
29
- className: clsx("flex w-full", as === "floating" && "flex-col", as === "filter" && "gap-input-gap-input-text-to-elements"),
30
+ className: inputContentWrapperCva({ as }),
30
31
  children: [as && ["filter", "floating"].includes(as) && headerProps && /* @__PURE__ */ jsx(FormFieldLabel, {
31
32
  as,
32
33
  size,
@@ -34,10 +35,10 @@ var InputContent = ({ leadingIcon: LeadingIcon, trailingIcon: TrailingIcon, unit
34
35
  }), children]
35
36
  })]
36
37
  }), /* @__PURE__ */ jsxs("div", {
37
- className: clsx(inputSizeCva({
38
+ className: clsx("flex items-center gap-input-gap-trailing-elements py-0! pl-0!", inputSizeCva({
38
39
  size,
39
40
  as
40
- }), "flex items-center gap-input-gap-trailing-elements py-0! pl-0!", !isTrailingIconElement && !action && !(isClearable && showClear) && "pointer-events-none"),
41
+ }), !isTrailingIconElement && !action && !(isClearable && showClear) && "pointer-events-none"),
41
42
  children: [
42
43
  isClearable && /* @__PURE__ */ jsx(InputClear, {
43
44
  onClear: () => {
@@ -0,0 +1 @@
1
+ export declare const getStaticNumberDisplayValue: (value: unknown, formatter: Intl.NumberFormat) => string | null;
@@ -0,0 +1,7 @@
1
+ //#region src/components/inputs/Input/shared/numberStatic.utils.ts
2
+ var getStaticNumberDisplayValue = (value, formatter) => {
3
+ if (typeof value !== "number" || !Number.isFinite(value)) return null;
4
+ return formatter.format(value);
5
+ };
6
+ //#endregion
7
+ export { getStaticNumberDisplayValue };