@povio/ui 2.2.9-rc.4 → 2.2.9-rc.41

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 (124) 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 +81 -6
  10. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +7 -2
  11. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +83 -5
  12. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +8 -2
  13. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +84 -7
  14. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +2 -1
  15. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +60 -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.d.ts +2 -2
  41. package/dist/components/inputs/FormField/FormFieldHeader.js +3 -1
  42. package/dist/components/inputs/FormField/FormFieldLabel.d.ts +2 -2
  43. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +6 -0
  44. package/dist/components/inputs/FormField/formFieldHeader.cva.js +11 -0
  45. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +5 -2
  46. package/dist/components/inputs/Input/NumberInput/NumberInput.js +78 -7
  47. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.d.ts +45 -0
  48. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.js +146 -0
  49. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +35 -0
  50. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +233 -0
  51. package/dist/components/inputs/Input/TextArea/TextArea.cva.d.ts +4 -0
  52. package/dist/components/inputs/Input/TextArea/TextArea.cva.js +5 -0
  53. package/dist/components/inputs/Input/TextArea/TextArea.js +3 -1
  54. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +3 -1
  55. package/dist/components/inputs/Input/TextInput/TextInput.js +77 -7
  56. package/dist/components/inputs/Input/shared/InputContent.js +7 -6
  57. package/dist/components/inputs/Input/shared/numberStatic.utils.d.ts +1 -0
  58. package/dist/components/inputs/Input/shared/numberStatic.utils.js +7 -0
  59. package/dist/components/inputs/Inputs/InputItem.d.ts +12 -9
  60. package/dist/components/inputs/Inputs/InputItem.js +2 -0
  61. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +2 -1
  62. package/dist/components/inputs/RadioGroup/RadioGroup.js +106 -25
  63. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +17 -0
  64. package/dist/components/inputs/RadioGroup/radio.cva.js +42 -1
  65. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +6 -2
  66. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +95 -6
  67. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +1 -1
  68. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +20 -11
  69. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +25 -19
  70. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +3 -3
  71. package/dist/components/inputs/Selection/Select/QuerySelect.js +22 -36
  72. package/dist/components/inputs/Selection/Select/Select.d.ts +7 -3
  73. package/dist/components/inputs/Selection/Select/Select.js +108 -4
  74. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +4 -1
  75. package/dist/components/inputs/Selection/shared/SelectBase.js +3 -2
  76. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  77. package/dist/components/inputs/Selection/shared/SelectDesktop.js +8 -4
  78. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  79. package/dist/components/inputs/Selection/shared/SelectInput.js +13 -2
  80. package/dist/components/inputs/Selection/shared/SelectListBox.d.ts +2 -2
  81. package/dist/components/inputs/Selection/shared/SelectListBox.js +3 -3
  82. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  83. package/dist/components/inputs/Selection/shared/SelectMobile.js +5 -3
  84. package/dist/components/inputs/Selection/shared/select.context.d.ts +3 -2
  85. package/dist/components/inputs/Selection/shared/select.context.js +27 -4
  86. package/dist/components/inputs/Selection/shared/select.types.d.ts +3 -2
  87. package/dist/components/inputs/Selection/shared/selectDesktop.cva.d.ts +3 -0
  88. package/dist/components/inputs/Selection/shared/selectDesktop.cva.js +5 -0
  89. package/dist/components/inputs/Selection/shared/staticSelect.utils.d.ts +23 -0
  90. package/dist/components/inputs/Selection/shared/staticSelect.utils.js +37 -0
  91. package/dist/components/inputs/Selection/shared/staticSelect.utils.spec.d.ts +1 -0
  92. package/dist/components/inputs/Skeleton/InputFrame.d.ts +77 -0
  93. package/dist/components/inputs/Skeleton/InputFrame.js +200 -0
  94. package/dist/components/inputs/TextEditor/TextEditor.js +1 -0
  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/uiConfig.context.d.ts +8 -2
  111. package/dist/config/uiConfig.context.js +12 -1
  112. package/dist/config/uiStyle.context.d.ts +27 -4
  113. package/dist/hooks/useIntersectionObserver.d.ts +1 -1
  114. package/dist/hooks/useIntersectionObserver.js +29 -10
  115. package/dist/hooks/useQueryAutocomplete.d.ts +5 -16
  116. package/dist/hooks/useQueryAutocomplete.js +20 -5
  117. package/dist/index.d.ts +5 -0
  118. package/dist/index.js +3 -2
  119. package/dist/tw-ui-plugin.js +2 -0
  120. package/dist/utils/date-time.utils.d.ts +30 -9
  121. package/dist/utils/date-time.utils.js +113 -1
  122. package/dist/utils/query.utils.d.ts +4 -0
  123. package/dist/utils/query.utils.js +8 -0
  124. 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,233 @@
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 { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
7
+ import { getStaticNumberDisplayValue } from "../shared/numberStatic.utils.js";
8
+ import { NumberRangeField } from "./NumberRangeField.js";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { clsx } from "clsx";
11
+ import { useRef, useState } from "react";
12
+ import { useLocale } from "react-aria-components";
13
+ import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
14
+ import { Controller, useWatch } from "react-hook-form";
15
+ //#region src/components/inputs/Input/NumberRangeInput/NumberRangeInput.tsx
16
+ var EMPTY_RANGE = {
17
+ min: null,
18
+ max: null
19
+ };
20
+ var normalizeRangeValue = (value, minValue, maxValue) => {
21
+ if (value) return value;
22
+ return {
23
+ min: minValue ?? null,
24
+ max: maxValue ?? null
25
+ };
26
+ };
27
+ var NumberRangeInputBase = (props) => {
28
+ const ui = UIConfig.useConfig();
29
+ const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
30
+ const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
31
+ 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;
32
+ const isClearable = isClearableProps ?? ui.input.isClearable;
33
+ const as = asProp ?? ui.input.as;
34
+ const variant = variantProps ?? ui.input.variant;
35
+ const size = sizeProps ?? ui.input.size;
36
+ const hideLabel = hideLabelProps ?? ui.input.hideLabel;
37
+ const rangeValue = normalizeRangeValue(value, minValue, maxValue);
38
+ const isEmpty = rangeValue.min === null && rangeValue.max === null;
39
+ const rangeError = rangeValue.min !== null && rangeValue.max !== null && rangeValue.min > rangeValue.max ? invalidRangeError : void 0;
40
+ const effectiveError = error || rangeError;
41
+ const { hoverProps, isHovered } = useHover({ isDisabled });
42
+ const { isFocusVisible } = useFocusVisible();
43
+ const [isFocused, setIsFocused] = useState(false);
44
+ const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setIsFocused });
45
+ const formFieldProps = {
46
+ error: effectiveError,
47
+ label,
48
+ tooltipText,
49
+ helperText,
50
+ isRequired,
51
+ rightContent,
52
+ isHeaderHidden: isHeaderHidden || as === "inline" || as === "filter" || as === "floating",
53
+ hideLabel,
54
+ isDisabled,
55
+ headerClassName,
56
+ errorClassName
57
+ };
58
+ const headerProps = {
59
+ label,
60
+ tooltipText,
61
+ helperText,
62
+ isRequired,
63
+ rightContent,
64
+ isHeaderHidden: hideLabel || isHeaderHidden,
65
+ isDisabled,
66
+ className: headerClassName
67
+ };
68
+ const updateRange = (side, nextValue) => {
69
+ const nextRange = {
70
+ ...rangeValue,
71
+ [side]: nextValue
72
+ };
73
+ onChange?.(nextRange);
74
+ if (side === "min") onMinChange?.(nextValue);
75
+ else onMaxChange?.(nextValue);
76
+ };
77
+ const clearRangeSide = (side) => {
78
+ updateRange(side, null);
79
+ onBlur?.({ target: { value: "" } });
80
+ };
81
+ return /* @__PURE__ */ jsx(NumberRangeField, {
82
+ ...rest,
83
+ ref,
84
+ as,
85
+ className,
86
+ inputClassName,
87
+ minInputClassName,
88
+ maxInputClassName,
89
+ inputBaseClassName: inputBaseCva({
90
+ variant,
91
+ as
92
+ }),
93
+ inputSizeClassName: inputSizeCva({
94
+ size,
95
+ as
96
+ }),
97
+ formFieldProps,
98
+ headerProps,
99
+ rangeValue,
100
+ effectiveError,
101
+ minPlaceholder,
102
+ maxPlaceholder,
103
+ minLabel,
104
+ maxLabel,
105
+ hideInnerLabels,
106
+ isDirty,
107
+ isClearable,
108
+ autoFocusOnMount,
109
+ isDisabled,
110
+ isRequired,
111
+ isEmpty,
112
+ isHovered,
113
+ isFocused,
114
+ isFocusVisible,
115
+ focusWithinProps,
116
+ hoverProps,
117
+ onRangeSideChange: updateRange,
118
+ onRangeSideClear: clearRangeSide,
119
+ onBlur
120
+ });
121
+ };
122
+ var NumberRangeInput = ({ renderStaticInput, ...props }) => {
123
+ const ui = UIConfig.useConfig();
124
+ const { locale } = useLocale();
125
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
126
+ const { shouldFocus, renderRealInput } = useStaticInputHandoff({
127
+ inputRef: useRef(null),
128
+ renderInput,
129
+ setRenderInput
130
+ });
131
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
132
+ control: props.formControl.control,
133
+ name: props.formControl.name
134
+ }) : props.value;
135
+ let isFormControlDisabled = false;
136
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
137
+ if (!renderInput) {
138
+ const staticValue = normalizeRangeValue(watchedValue, props.minValue, props.maxValue);
139
+ const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
140
+ const formatter = new Intl.NumberFormat(locale, formatOptions);
141
+ const minDisplay = getStaticNumberDisplayValue(staticValue.min, formatter);
142
+ const maxDisplay = getStaticNumberDisplayValue(staticValue.max, formatter);
143
+ const hasValue = minDisplay !== null || maxDisplay !== null;
144
+ const rangeError = staticValue.min !== null && staticValue.max !== null && staticValue.min > staticValue.max ? props.invalidRangeError ?? "Minimum cannot be greater than maximum" : void 0;
145
+ const effectiveError = props.error || rangeError;
146
+ const as = props.as ?? ui.input.as;
147
+ let isDisabled = !!props.isDisabled;
148
+ if (isFormControlDisabled) isDisabled = true;
149
+ const isClearable = props.isClearable ?? ui.input.isClearable;
150
+ const dataAttributes = {
151
+ dataIsEmpty: !hasValue,
152
+ dataIsFilled: hasValue,
153
+ dataIsDirty: props.isDirty,
154
+ dataIsRequired: props.isRequired,
155
+ dataIsDisabled: isDisabled,
156
+ dataDisabled: isDisabled,
157
+ dataInvalid: !!effectiveError,
158
+ dataHasSelection: hasValue
159
+ };
160
+ return /* @__PURE__ */ jsx(InputFrame, {
161
+ ...props,
162
+ error: effectiveError,
163
+ isDisabled,
164
+ className: clsx("group w-full", as === "inline" && "h-full", props.className),
165
+ inputClassName: props.inputClassName,
166
+ contentWrapperClassName: "flex w-full items-center gap-input-gap-input-text-to-elements",
167
+ dataAttributes,
168
+ renderStatic: true,
169
+ onStaticInteract: renderRealInput,
170
+ isClearable: false,
171
+ labelPlacement: "content-row",
172
+ children: ({ id, ...dataAttributeProps }) => /* @__PURE__ */ jsxs(Fragment, { children: [
173
+ /* @__PURE__ */ jsx("input", {
174
+ id,
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
+ id: `${id}-max`,
194
+ readOnly: true,
195
+ disabled: isDisabled,
196
+ tabIndex: -1,
197
+ value: maxDisplay ?? "",
198
+ placeholder: props.maxPlaceholder ?? "Max",
199
+ className: clsx("w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.maxInputClassName),
200
+ ...dataAttributeProps,
201
+ "data-rac": true
202
+ }),
203
+ isClearable && /* @__PURE__ */ jsx(InputClear, {
204
+ onClear: () => {},
205
+ renderStatic: true
206
+ })
207
+ ] })
208
+ });
209
+ }
210
+ if ("formControl" in props && props.formControl) {
211
+ const { formControl, ref, ...innerProps } = props;
212
+ return /* @__PURE__ */ jsx(Controller, {
213
+ control: formControl.control,
214
+ name: formControl.name,
215
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(NumberRangeInputBase, {
216
+ ...innerProps,
217
+ ref,
218
+ value: field.value ?? EMPTY_RANGE,
219
+ onChange: field.onChange,
220
+ onBlur: field.onBlur,
221
+ isDisabled: field.disabled || props.isDisabled,
222
+ error: props.error ?? error?.message,
223
+ autoFocusOnMount: shouldFocus
224
+ })
225
+ });
226
+ }
227
+ return /* @__PURE__ */ jsx(NumberRangeInputBase, {
228
+ ...props,
229
+ autoFocusOnMount: shouldFocus
230
+ });
231
+ };
232
+ //#endregion
233
+ export { NumberRangeInput };
@@ -0,0 +1,4 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ export declare const textAreaWrapper: (props?: import('class-variance-authority/types').ClassProp | undefined) => string;
3
+ export interface TextAreaWrapperVariantProps extends VariantProps<typeof textAreaWrapper> {
4
+ }
@@ -0,0 +1,5 @@
1
+ import { cva } from "class-variance-authority";
2
+ //#region src/components/inputs/Input/TextArea/TextArea.cva.ts
3
+ var textAreaWrapper = cva("group/text-area relative h-full");
4
+ //#endregion
5
+ export { textAreaWrapper };
@@ -5,6 +5,7 @@ import { InputClear } from "../../shared/InputClear.js";
5
5
  import { inputSide, inputSize, useInputCva } from "../../shared/input.cva.js";
6
6
  import { FormField } from "../../FormField/FormField.js";
7
7
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
+ import { textAreaWrapper } from "./TextArea.cva.js";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  import { clsx } from "clsx";
10
11
  import { useRef } from "react";
@@ -18,6 +19,7 @@ var TextAreaBase = (props) => {
18
19
  const inputCva = useInputCva();
19
20
  const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
20
21
  const inputSideCva = UIStyle.useCva("input.sideCva", inputSide);
22
+ const textAreaWrapperCva = UIStyle.useCva("textArea.wrapperCva", textAreaWrapper);
21
23
  const { ref, className, inputClassName, error, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, value, onChange, onBlur, as = ui.input.as, hideLabel = ui.input.hideLabel, variant = ui.input.variant, isClearable = ui.input.isClearable, ...rest } = props;
22
24
  const textFieldRef = useRef(null);
23
25
  const { labelProps, inputProps } = useTextField({
@@ -66,7 +68,7 @@ var TextAreaBase = (props) => {
66
68
  className: clsx("w-full", className),
67
69
  tabIndex: as === "inline" ? -1 : void 0,
68
70
  children: /* @__PURE__ */ jsxs("div", {
69
- className: "group/text-area relative h-full",
71
+ className: textAreaWrapperCva({}),
70
72
  "data-text-area": true,
71
73
  children: [
72
74
  as === "floating" && headerProps && /* @__PURE__ */ jsx(FormFieldLabel, {
@@ -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,22 @@ 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";
7
+ import { useStaticInputHandoff } from "../../shared/useStaticInputHandoff.js";
6
8
  import { InputContent } from "../shared/InputContent.js";
7
9
  import { jsx } from "react/jsx-runtime";
8
10
  import { clsx } from "clsx";
9
- import { useRef } from "react";
11
+ import { useEffect, useRef, useState } from "react";
10
12
  import { Input } from "react-aria-components";
11
13
  import { useFocusVisible, useTextField } from "react-aria";
12
14
  import { mergeRefs } from "@react-aria/utils";
13
- import { Controller } from "react-hook-form";
15
+ import { Controller, useWatch } from "react-hook-form";
14
16
  //#region src/components/inputs/Input/TextInput/TextInput.tsx
15
17
  var TextInputBase = (props) => {
16
18
  const ui = UIConfig.useConfig();
17
19
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
18
20
  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;
21
+ 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
22
  const textFieldRef = useRef(null);
21
23
  const { isFocusVisible } = useFocusVisible();
22
24
  const { labelProps, inputProps } = useTextField({
@@ -29,6 +31,10 @@ var TextInputBase = (props) => {
29
31
  onChange,
30
32
  onBlur
31
33
  }, textFieldRef);
34
+ useEffect(() => {
35
+ if (!autoFocusOnMount || isDisabled) return;
36
+ requestAnimationFrame(() => inputRef.current?.focus());
37
+ }, [autoFocusOnMount, isDisabled]);
32
38
  const formFieldProps = {
33
39
  error,
34
40
  label,
@@ -84,6 +90,8 @@ var TextInputBase = (props) => {
84
90
  ...rest
85
91
  }), inputClassName),
86
92
  onClick: () => inputRef.current?.focus(),
93
+ "data-is-empty": value === "" || value === null || value === void 0 || void 0,
94
+ "data-is-required": isRequired || void 0,
87
95
  children: /* @__PURE__ */ jsx(InputContent, {
88
96
  ...inputContentProps,
89
97
  headerProps,
@@ -109,7 +117,64 @@ var TextInputBase = (props) => {
109
117
  })
110
118
  });
111
119
  };
112
- var TextInput = (props) => {
120
+ var TextInput = ({ renderStaticInput, ...props }) => {
121
+ const ui = UIConfig.useConfig();
122
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
123
+ const inputRef = useRef(null);
124
+ const { shouldFocus, renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
125
+ inputRef,
126
+ renderInput,
127
+ setRenderInput
128
+ });
129
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
130
+ control: props.formControl.control,
131
+ name: props.formControl.name
132
+ }) : props.value;
133
+ let isFormControlDisabled = false;
134
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
135
+ const staticValue = watchedValue ?? props.value ?? props.defaultValue ?? "";
136
+ const inputType = props.type;
137
+ if (!renderInput && inputType === "password" && `${staticValue}`.length > 0) setRenderInput(true);
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: renderRealInput,
162
+ inputClassName: props.inputClassName,
163
+ wrapContentAndTrailing: true,
164
+ children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
165
+ ref: inputRef,
166
+ type: inputType === "hidden" ? "password" : inputType,
167
+ disabled: isDisabled,
168
+ tabIndex: -1,
169
+ value: displayValue,
170
+ placeholder: as === "floating" ? "" : props.placeholder,
171
+ className: "w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled",
172
+ onChange: (event) => replayStaticInputChange(event.target.value),
173
+ ...dataAttributeProps,
174
+ "data-rac": true
175
+ })
176
+ });
177
+ }
113
178
  if ("formControl" in props && props.formControl) {
114
179
  const { formControl, ref, ...innerProps } = props;
115
180
  return /* @__PURE__ */ jsx(Controller, {
@@ -117,17 +182,22 @@ var TextInput = (props) => {
117
182
  name: formControl.name,
118
183
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TextInputBase, {
119
184
  ...innerProps,
120
- ref: mergeRefs(ref, field.ref),
185
+ ref: mergeRefs(ref, field.ref, inputRef),
121
186
  value: field.value,
122
187
  onChange: field.onChange,
123
188
  onBlur: field.onBlur,
124
189
  isDirty,
125
190
  isDisabled: field.disabled || props.isDisabled,
126
- error: props.error ?? error?.message
191
+ error: props.error ?? error?.message,
192
+ autoFocusOnMount: shouldFocus
127
193
  })
128
194
  });
129
195
  }
130
- return /* @__PURE__ */ jsx(TextInputBase, { ...props });
196
+ return /* @__PURE__ */ jsx(TextInputBase, {
197
+ ...props,
198
+ ref: mergeRefs(props.ref, inputRef),
199
+ autoFocusOnMount: shouldFocus
200
+ });
131
201
  };
132
202
  //#endregion
133
203
  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 };