@povio/ui 2.2.11 → 2.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/components/buttons/InlineIconButton/InlineIconButton.d.ts +2 -1
  2. package/dist/components/buttons/InlineIconButton/InlineIconButton.js +2 -2
  3. package/dist/components/inputs/Checkbox/Checkbox.js +6 -1
  4. package/dist/components/inputs/Checkbox/checkbox.cva.d.ts +3 -0
  5. package/dist/components/inputs/Checkbox/checkbox.cva.js +2 -1
  6. package/dist/components/inputs/DateTime/DatePicker/DatePicker.d.ts +10 -5
  7. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +89 -9
  8. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.d.ts +10 -5
  9. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +95 -7
  10. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.d.ts +11 -5
  11. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +95 -9
  12. package/dist/components/inputs/DateTime/TimePicker/TimePicker.d.ts +5 -3
  13. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +77 -7
  14. package/dist/components/inputs/DateTime/shared/Calendar.d.ts +5 -2
  15. package/dist/components/inputs/DateTime/shared/Calendar.js +49 -8
  16. package/dist/components/inputs/DateTime/shared/CalendarCell.d.ts +1 -1
  17. package/dist/components/inputs/DateTime/shared/CalendarCell.js +3 -3
  18. package/dist/components/inputs/DateTime/shared/CalendarGrid.d.ts +1 -1
  19. package/dist/components/inputs/DateTime/shared/DatePickerInput.d.ts +6 -3
  20. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +78 -61
  21. package/dist/components/inputs/DateTime/shared/DateSegmentItem.d.ts +14 -0
  22. package/dist/components/inputs/DateTime/shared/DateSegmentItem.js +19 -6
  23. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +2 -1
  24. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +11 -4
  25. package/dist/components/inputs/DateTime/shared/datePicker.types.d.ts +4 -0
  26. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.d.ts +7 -0
  27. package/dist/components/inputs/DateTime/shared/datePickerInput.cva.js +13 -0
  28. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.d.ts +6 -0
  29. package/dist/components/inputs/DateTime/shared/datePickerTodayIcon.js +21 -0
  30. package/dist/components/inputs/DateTime/shared/dateSegment.utils.d.ts +2 -0
  31. package/dist/components/inputs/DateTime/shared/dateSegment.utils.spec.d.ts +1 -0
  32. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.d.ts +35 -0
  33. package/dist/components/inputs/DateTime/shared/staticDateTimeSegments.js +80 -0
  34. package/dist/components/inputs/File/FileUpload.js +1 -0
  35. package/dist/components/inputs/File/shared/InputUploadContent.js +1 -0
  36. package/dist/components/inputs/FormField/FormField.d.ts +3 -3
  37. package/dist/components/inputs/FormField/FormFieldHeader.d.ts +2 -2
  38. package/dist/components/inputs/FormField/FormFieldHeader.js +3 -1
  39. package/dist/components/inputs/FormField/FormFieldLabel.d.ts +2 -2
  40. package/dist/components/inputs/FormField/formFieldHeader.cva.d.ts +6 -0
  41. package/dist/components/inputs/FormField/formFieldHeader.cva.js +11 -0
  42. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +5 -2
  43. package/dist/components/inputs/Input/NumberInput/NumberInput.js +81 -7
  44. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.d.ts +45 -0
  45. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeField.js +146 -0
  46. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.d.ts +35 -0
  47. package/dist/components/inputs/Input/NumberRangeInput/NumberRangeInput.js +235 -0
  48. package/dist/components/inputs/Input/TextArea/TextArea.cva.d.ts +4 -0
  49. package/dist/components/inputs/Input/TextArea/TextArea.cva.js +5 -0
  50. package/dist/components/inputs/Input/TextArea/TextArea.js +3 -1
  51. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +3 -1
  52. package/dist/components/inputs/Input/TextInput/TextInput.js +82 -7
  53. package/dist/components/inputs/Input/shared/InputContent.js +7 -6
  54. package/dist/components/inputs/Input/shared/numberStatic.utils.d.ts +1 -0
  55. package/dist/components/inputs/Input/shared/numberStatic.utils.js +7 -0
  56. package/dist/components/inputs/Inputs/InputItem.d.ts +16 -21
  57. package/dist/components/inputs/Inputs/InputItem.js +6 -0
  58. package/dist/components/inputs/RadioGroup/RadioGroup.d.ts +2 -1
  59. package/dist/components/inputs/RadioGroup/RadioGroup.js +106 -25
  60. package/dist/components/inputs/RadioGroup/radio.cva.d.ts +17 -0
  61. package/dist/components/inputs/RadioGroup/radio.cva.js +42 -1
  62. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.d.ts +6 -2
  63. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +102 -7
  64. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.d.ts +3 -18
  65. package/dist/components/inputs/Selection/Autocomplete/QueryAutocomplete.js +33 -8
  66. package/dist/components/inputs/Selection/Autocomplete/queryAutocomplete.types.d.ts +36 -0
  67. package/dist/components/inputs/Selection/Select/QuerySelect.d.ts +14 -0
  68. package/dist/components/inputs/Selection/Select/QuerySelect.js +42 -0
  69. package/dist/components/inputs/Selection/Select/Select.d.ts +7 -3
  70. package/dist/components/inputs/Selection/Select/Select.js +115 -5
  71. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +8 -1
  72. package/dist/components/inputs/Selection/shared/SelectBase.js +4 -2
  73. package/dist/components/inputs/Selection/shared/SelectDesktop.d.ts +1 -1
  74. package/dist/components/inputs/Selection/shared/SelectDesktop.js +11 -3
  75. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  76. package/dist/components/inputs/Selection/shared/SelectInput.js +27 -4
  77. package/dist/components/inputs/Selection/shared/SelectListBox.d.ts +2 -2
  78. package/dist/components/inputs/Selection/shared/SelectListBox.js +3 -3
  79. package/dist/components/inputs/Selection/shared/SelectMobile.d.ts +1 -1
  80. package/dist/components/inputs/Selection/shared/SelectMobile.js +9 -3
  81. package/dist/components/inputs/Selection/shared/querySelect.utils.d.ts +6 -0
  82. package/dist/components/inputs/Selection/shared/querySelect.utils.js +13 -0
  83. package/dist/components/inputs/Selection/shared/select.context.d.ts +3 -2
  84. package/dist/components/inputs/Selection/shared/select.context.js +27 -4
  85. package/dist/components/inputs/Selection/shared/select.types.d.ts +3 -2
  86. package/dist/components/inputs/Selection/shared/selectDesktop.cva.d.ts +3 -0
  87. package/dist/components/inputs/Selection/shared/selectDesktop.cva.js +5 -0
  88. package/dist/components/inputs/Selection/shared/staticSelect.utils.d.ts +23 -0
  89. package/dist/components/inputs/Selection/shared/staticSelect.utils.js +37 -0
  90. package/dist/components/inputs/Selection/shared/staticSelect.utils.spec.d.ts +1 -0
  91. package/dist/components/inputs/Skeleton/InputFrame.d.ts +77 -0
  92. package/dist/components/inputs/Skeleton/InputFrame.js +200 -0
  93. package/dist/components/inputs/TextEditor/TextEditor.d.ts +1 -0
  94. package/dist/components/inputs/TextEditor/TextEditor.js +8 -3
  95. package/dist/components/inputs/Toggle/Toggle.js +6 -1
  96. package/dist/components/inputs/Toggle/toggle.cva.d.ts +3 -0
  97. package/dist/components/inputs/Toggle/toggle.cva.js +2 -1
  98. package/dist/components/inputs/shared/CheckContent.d.ts +2 -1
  99. package/dist/components/inputs/shared/CheckContent.js +3 -4
  100. package/dist/components/inputs/shared/InputClear.d.ts +2 -1
  101. package/dist/components/inputs/shared/InputClear.js +13 -1
  102. package/dist/components/inputs/shared/StaticInput.d.ts +38 -0
  103. package/dist/components/inputs/shared/TooltipWrapper.js +5 -1
  104. package/dist/components/inputs/shared/input.cva.d.ts +10 -0
  105. package/dist/components/inputs/shared/input.cva.js +19 -1
  106. package/dist/components/inputs/shared/tooltipWrapper.cva.d.ts +4 -0
  107. package/dist/components/inputs/shared/tooltipWrapper.cva.js +5 -0
  108. package/dist/components/inputs/shared/useStaticInputHandoff.d.ts +13 -0
  109. package/dist/components/inputs/shared/useStaticInputHandoff.js +47 -0
  110. package/dist/components/overlays/BottomSheet/BottomSheet.js +1 -1
  111. package/dist/components/segment/Segment.js +2 -1
  112. package/dist/components/segment/SegmentItem.d.ts +1 -1
  113. package/dist/components/segment/SegmentItem.js +5 -2
  114. package/dist/components/segment/segment.types.d.ts +1 -0
  115. package/dist/config/router.context.d.ts +3 -4
  116. package/dist/config/router.context.js +1 -3
  117. package/dist/config/uiConfig.context.d.ts +15 -3
  118. package/dist/config/uiConfig.context.js +16 -3
  119. package/dist/config/uiStyle.context.d.ts +27 -4
  120. package/dist/helpers/dynamicInputs.d.ts +5 -5
  121. package/dist/helpers/dynamicInputs.js +3 -0
  122. package/dist/hooks/useFilters.js +27 -23
  123. package/dist/hooks/useIntersectionObserver.d.ts +1 -1
  124. package/dist/hooks/useIntersectionObserver.js +29 -10
  125. package/dist/hooks/usePagination.js +8 -4
  126. package/dist/hooks/useQueryAutocomplete.d.ts +14 -0
  127. package/dist/hooks/useQueryAutocomplete.js +56 -0
  128. package/dist/hooks/useSorting.js +7 -4
  129. package/dist/index.d.ts +7 -0
  130. package/dist/index.js +5 -3
  131. package/dist/tw-ui-plugin.js +2 -0
  132. package/dist/utils/date-time.utils.d.ts +31 -10
  133. package/dist/utils/date-time.utils.js +123 -22
  134. package/dist/utils/query.utils.d.ts +4 -0
  135. package/dist/utils/query.utils.js +8 -0
  136. package/dist/utils/routing.utils.d.ts +1 -0
  137. package/dist/utils/routing.utils.js +14 -0
  138. package/package.json +4 -4
@@ -13,8 +13,11 @@ interface NumberInputBaseProps extends FormFieldProps, InputVariantProps, Omit<I
13
13
  value?: number | null;
14
14
  onChange?: (value: number | null) => void;
15
15
  onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
16
+ autoFocusOnMount?: boolean;
16
17
  }
17
- export type NumberInputProps = NumberInputBaseProps;
18
+ export type NumberInputProps = NumberInputBaseProps & {
19
+ renderStaticInput?: boolean;
20
+ };
18
21
  export type ControlledNumberInputProps<TFieldValues extends FieldValues> = ControlProps<NumberInputProps, TFieldValues>;
19
- export declare const NumberInput: <TFieldValues extends FieldValues>(props: ControlledNumberInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
22
+ export declare const NumberInput: <TFieldValues extends FieldValues>({ renderStaticInput, ...props }: ControlledNumberInputProps<TFieldValues>) => import("react/jsx-runtime").JSX.Element;
20
23
  export {};
@@ -3,21 +3,24 @@ 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";
9
+ import { getStaticNumberDisplayValue } from "../shared/numberStatic.utils.js";
7
10
  import { jsx } from "react/jsx-runtime";
8
11
  import { clsx } from "clsx";
9
- import { useCallback, useRef } from "react";
12
+ import { useCallback, useEffect, useRef, useState } from "react";
10
13
  import { Input, useLocale } from "react-aria-components";
11
14
  import { useFocusVisible, useNumberField } from "react-aria";
12
15
  import { mergeRefs } from "@react-aria/utils";
13
- import { Controller } from "react-hook-form";
16
+ import { Controller, useWatch } from "react-hook-form";
14
17
  import { useNumberFieldState } from "react-stately";
15
18
  //#region src/components/inputs/Input/NumberInput/NumberInput.tsx
16
19
  var NumberInputBase = (props) => {
17
20
  const ui = UIConfig.useConfig();
18
21
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
19
22
  const inputRef = useRef(null);
20
- const { ref, inputClassName, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, className, unit, isLoading, action, leadingIcon, trailingIcon, value, onChange, onBlur, formatOptions = ui.numberInput.formatOptions, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, hideLabel = ui.input.hideLabel, isClearable = ui.input.isClearable, ...rest } = props;
23
+ const { ref, inputClassName, label, tooltipText, helperText, isRequired, rightContent, isDisabled, isDirty, headerClassName, errorClassName, isHeaderHidden, error, className, unit, isLoading, action, leadingIcon, trailingIcon, value, onChange, onBlur, formatOptions = ui.numberInput.formatOptions, variant = ui.input.variant, as = ui.input.as, size = ui.input.size, hideLabel = ui.input.hideLabel, isClearable = ui.input.isClearable, autoFocusOnMount, ...rest } = props;
21
24
  const numberFieldRef = useRef(null);
22
25
  const { isFocusVisible } = useFocusVisible();
23
26
  const { locale } = useLocale();
@@ -34,6 +37,10 @@ var NumberInputBase = (props) => {
34
37
  formatOptions
35
38
  };
36
39
  const { labelProps, inputProps } = useNumberField(numberProps, useNumberFieldState(numberProps), numberFieldRef);
40
+ useEffect(() => {
41
+ if (!autoFocusOnMount || isDisabled) return;
42
+ requestAnimationFrame(() => inputRef.current?.focus());
43
+ }, [autoFocusOnMount, isDisabled]);
37
44
  const formFieldProps = {
38
45
  error,
39
46
  label,
@@ -90,6 +97,8 @@ var NumberInputBase = (props) => {
90
97
  ...rest
91
98
  }), inputClassName),
92
99
  onClick: () => inputRef.current?.focus(),
100
+ "data-is-empty": value === null || value === void 0 || void 0,
101
+ "data-is-required": isRequired || void 0,
93
102
  children: /* @__PURE__ */ jsx(InputContent, {
94
103
  ...inputContentProps,
95
104
  headerProps,
@@ -101,6 +110,7 @@ var NumberInputBase = (props) => {
101
110
  "data-is-dirty": isDirty || void 0,
102
111
  "data-is-required": isRequired || void 0,
103
112
  "data-is-empty": value === null || value === void 0 || void 0,
113
+ "data-is-filled": !("" + value === "" || value === null || value === void 0) || void 0,
104
114
  placeholder: as === "floating" ? "\xA0" : inputProps.placeholder,
105
115
  className: "w-full outline-none",
106
116
  onFocus: (e) => {
@@ -113,7 +123,66 @@ var NumberInputBase = (props) => {
113
123
  })
114
124
  });
115
125
  };
116
- var NumberInput = (props) => {
126
+ var NumberInput = ({ renderStaticInput, ...props }) => {
127
+ const ui = UIConfig.useConfig();
128
+ const { locale } = useLocale();
129
+ const [renderInput, setRenderInput] = useState(!(renderStaticInput ?? ui.renderStaticInput));
130
+ const inputRef = useRef(null);
131
+ const { shouldFocus, renderRealInput, replayStaticInputChange } = useStaticInputHandoff({
132
+ inputRef,
133
+ renderInput,
134
+ setRenderInput
135
+ });
136
+ const watchedValue = "formControl" in props && props.formControl ? useWatch({
137
+ control: props.formControl.control,
138
+ name: props.formControl.name
139
+ }) : props.value;
140
+ let isFormControlDisabled = false;
141
+ if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
142
+ if (!renderInput) {
143
+ const staticValue = watchedValue ?? props.value ?? props.defaultValue;
144
+ const formatOptions = props.formatOptions ?? ui.numberInput.formatOptions;
145
+ const displayValue = getStaticNumberDisplayValue(staticValue, new Intl.NumberFormat(locale, formatOptions)) ?? "";
146
+ const hasValue = displayValue !== "";
147
+ const as = props.as ?? ui.input.as;
148
+ let isDisabled = !!props.isDisabled;
149
+ if (isFormControlDisabled) isDisabled = true;
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: !!props.error,
158
+ dataHasSelection: hasValue
159
+ };
160
+ return /* @__PURE__ */ jsx(InputFrame, {
161
+ ...props,
162
+ isDisabled,
163
+ className: clsx("group w-full", as === "inline" && "h-full", props.className),
164
+ dataAttributes,
165
+ renderStatic: true,
166
+ onStaticInteract: renderRealInput,
167
+ inputClassName: props.inputClassName,
168
+ contentClassName: "pr-0!",
169
+ trailingClassName: "py-0! pl-0!",
170
+ wrapContentAndTrailing: true,
171
+ children: (dataAttributeProps) => /* @__PURE__ */ jsx("input", {
172
+ type: "text",
173
+ ref: inputRef,
174
+ disabled: isDisabled,
175
+ inputMode: "numeric",
176
+ tabIndex: -1,
177
+ value: displayValue,
178
+ placeholder: as === "floating" ? "" : props.placeholder,
179
+ className: "w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled",
180
+ onChange: (event) => replayStaticInputChange(event.target.value),
181
+ ...dataAttributeProps,
182
+ "data-rac": true
183
+ })
184
+ });
185
+ }
117
186
  if ("formControl" in props && props.formControl) {
118
187
  const { formControl, ref, ...innerProps } = props;
119
188
  return /* @__PURE__ */ jsx(Controller, {
@@ -121,17 +190,22 @@ var NumberInput = (props) => {
121
190
  name: formControl.name,
122
191
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(NumberInputBase, {
123
192
  ...innerProps,
124
- ref: mergeRefs(ref, field.ref),
193
+ ref: mergeRefs(ref, field.ref, inputRef),
125
194
  value: field.value,
126
195
  onChange: field.onChange,
127
196
  onBlur: field.onBlur,
128
197
  isDirty,
129
198
  isDisabled: field.disabled || props.isDisabled,
130
- error: props.error ?? error?.message
199
+ error: props.error ?? error?.message,
200
+ autoFocusOnMount: shouldFocus
131
201
  }, field.value === null || field.value === void 0 ? "empty" : "filled")
132
202
  });
133
203
  }
134
- return /* @__PURE__ */ jsx(NumberInputBase, { ...props }, props.value === null || props.value === void 0 ? "empty" : "filled");
204
+ return /* @__PURE__ */ jsx(NumberInputBase, {
205
+ ...props,
206
+ ref: mergeRefs(props.ref, inputRef),
207
+ autoFocusOnMount: shouldFocus
208
+ }, props.value === null || props.value === void 0 ? "empty" : "filled");
135
209
  };
136
210
  //#endregion
137
211
  export { NumberInput };
@@ -0,0 +1,45 @@
1
+ import { FocusEvent, HTMLAttributes, Ref } from 'react';
2
+ import { NumberFieldProps as AriaNumberFieldProps } from 'react-aria-components';
3
+ import { FormFieldProps } from '../../FormField/FormField';
4
+ import { FormFieldHeaderProps } from '../../FormField/FormFieldHeader';
5
+ import { InputVariantProps } from '../../shared/input.cva';
6
+ export interface NumberRangeValue {
7
+ min: number | null;
8
+ max: number | null;
9
+ }
10
+ type NumberRangeFieldInputProps = Omit<AriaNumberFieldProps, "className" | "defaultValue" | "label" | "maxValue" | "minValue" | "onBlur" | "onChange" | "value">;
11
+ export interface NumberRangeFieldProps extends NumberRangeFieldInputProps {
12
+ ref?: Ref<HTMLDivElement>;
13
+ as: InputVariantProps["as"];
14
+ className?: string;
15
+ inputClassName?: string;
16
+ minInputClassName?: string;
17
+ maxInputClassName?: string;
18
+ inputBaseClassName: string;
19
+ inputSizeClassName: string;
20
+ formFieldProps: FormFieldProps;
21
+ headerProps: FormFieldHeaderProps;
22
+ rangeValue: NumberRangeValue;
23
+ effectiveError?: string;
24
+ minPlaceholder: string;
25
+ maxPlaceholder: string;
26
+ minLabel: string;
27
+ maxLabel: string;
28
+ hideInnerLabels?: boolean;
29
+ isDirty?: boolean;
30
+ isClearable?: boolean;
31
+ autoFocusOnMount?: boolean;
32
+ isDisabled?: boolean;
33
+ isRequired?: boolean;
34
+ isEmpty: boolean;
35
+ isHovered: boolean;
36
+ isFocused: boolean;
37
+ isFocusVisible: boolean;
38
+ focusWithinProps: HTMLAttributes<HTMLElement>;
39
+ hoverProps: HTMLAttributes<HTMLElement>;
40
+ onRangeSideChange: (side: keyof NumberRangeValue, nextValue: number | null) => void;
41
+ onRangeSideClear: (side: keyof NumberRangeValue) => void;
42
+ onBlur?: (e: FocusEvent<HTMLInputElement>) => void;
43
+ }
44
+ export declare const 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 }: NumberRangeFieldProps) => import("react/jsx-runtime").JSX.Element;
45
+ export {};
@@ -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,235 @@
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
+ contentClassName: "pr-0!",
167
+ trailingClassName: "py-0! pl-0!",
168
+ contentWrapperClassName: "flex w-full items-center gap-input-gap-input-text-to-elements",
169
+ dataAttributes,
170
+ renderStatic: true,
171
+ onStaticInteract: renderRealInput,
172
+ isClearable: false,
173
+ labelPlacement: "content-row",
174
+ children: ({ id, ...dataAttributeProps }) => /* @__PURE__ */ jsxs(Fragment, { children: [
175
+ /* @__PURE__ */ jsx("input", {
176
+ id,
177
+ readOnly: true,
178
+ disabled: isDisabled,
179
+ tabIndex: -1,
180
+ value: minDisplay ?? "",
181
+ placeholder: props.minPlaceholder ?? "Min",
182
+ className: clsx("w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.minInputClassName),
183
+ ...dataAttributeProps,
184
+ "data-rac": true
185
+ }),
186
+ isClearable && /* @__PURE__ */ jsx(InputClear, {
187
+ onClear: () => {},
188
+ renderStatic: true
189
+ }),
190
+ /* @__PURE__ */ jsx("span", {
191
+ className: "pointer-events-none shrink-0 select-none text-label-2 text-text-default-3",
192
+ children: "-"
193
+ }),
194
+ /* @__PURE__ */ jsx("input", {
195
+ id: `${id}-max`,
196
+ readOnly: true,
197
+ disabled: isDisabled,
198
+ tabIndex: -1,
199
+ value: maxDisplay ?? "",
200
+ placeholder: props.maxPlaceholder ?? "Max",
201
+ className: clsx("w-full bg-transparent outline-none placeholder:text-text-default-3 disabled:text-interactive-text-secondary-disabled", props.maxInputClassName),
202
+ ...dataAttributeProps,
203
+ "data-rac": true
204
+ }),
205
+ isClearable && /* @__PURE__ */ jsx(InputClear, {
206
+ onClear: () => {},
207
+ renderStatic: true
208
+ })
209
+ ] })
210
+ });
211
+ }
212
+ if ("formControl" in props && props.formControl) {
213
+ const { formControl, ref, ...innerProps } = props;
214
+ return /* @__PURE__ */ jsx(Controller, {
215
+ control: formControl.control,
216
+ name: formControl.name,
217
+ render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(NumberRangeInputBase, {
218
+ ...innerProps,
219
+ ref,
220
+ value: field.value ?? EMPTY_RANGE,
221
+ onChange: field.onChange,
222
+ onBlur: field.onBlur,
223
+ isDisabled: field.disabled || props.isDisabled,
224
+ error: props.error ?? error?.message,
225
+ autoFocusOnMount: shouldFocus
226
+ })
227
+ });
228
+ }
229
+ return /* @__PURE__ */ jsx(NumberRangeInputBase, {
230
+ ...props,
231
+ autoFocusOnMount: shouldFocus
232
+ });
233
+ };
234
+ //#endregion
235
+ 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, {