@povio/ui 2.2.8-rc → 2.2.9-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 (45) hide show
  1. package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +2 -1
  2. package/dist/components/Breadcrumbs/Breadcrumbs.js +2 -2
  3. package/dist/components/inputs/DateTime/DatePicker/DatePicker.js +3 -60
  4. package/dist/components/inputs/DateTime/DateRangePicker/DateRangePicker.js +3 -89
  5. package/dist/components/inputs/DateTime/DateTimePicker/DateTimePicker.js +3 -60
  6. package/dist/components/inputs/DateTime/TimePicker/TimePicker.js +5 -57
  7. package/dist/components/inputs/DateTime/shared/DatePickerInput.js +1 -0
  8. package/dist/components/inputs/DateTime/shared/TimePickerInput.d.ts +2 -1
  9. package/dist/components/inputs/DateTime/shared/TimePickerInput.js +3 -1
  10. package/dist/components/inputs/File/InputUpload.js +5 -3
  11. package/dist/components/inputs/File/inputUpload.types.d.ts +4 -1
  12. package/dist/components/inputs/File/inputUpload.types.js +9 -0
  13. package/dist/components/inputs/File/shared/FileUploadContentFilled.js +3 -1
  14. package/dist/components/inputs/File/shared/InputUploadContent.d.ts +2 -1
  15. package/dist/components/inputs/File/shared/InputUploadContent.js +4 -3
  16. package/dist/components/inputs/File/shared/InputUploadFilled.d.ts +3 -2
  17. package/dist/components/inputs/File/shared/InputUploadFilled.js +2 -2
  18. package/dist/components/inputs/Input/NumberInput/NumberInput.d.ts +0 -1
  19. package/dist/components/inputs/Input/NumberInput/NumberInput.js +9 -80
  20. package/dist/components/inputs/Input/TextInput/TextInput.d.ts +0 -1
  21. package/dist/components/inputs/Input/TextInput/TextInput.js +9 -83
  22. package/dist/components/inputs/Selection/Autocomplete/Autocomplete.js +4 -63
  23. package/dist/components/inputs/Selection/Select/Select.js +4 -64
  24. package/dist/components/inputs/Selection/shared/SelectBase.d.ts +2 -0
  25. package/dist/components/inputs/Selection/shared/SelectBase.js +2 -1
  26. package/dist/components/inputs/Selection/shared/SelectDesktop.js +3 -1
  27. package/dist/components/inputs/Selection/shared/SelectInput.d.ts +2 -2
  28. package/dist/components/inputs/Selection/shared/SelectInput.js +13 -3
  29. package/dist/components/inputs/Selection/shared/SelectListBoxItem.d.ts +0 -1
  30. package/dist/components/inputs/Selection/shared/SelectListBoxItem.js +8 -4
  31. package/dist/components/inputs/Selection/shared/SelectListBoxItemSelectAll.js +5 -3
  32. package/dist/components/inputs/Selection/shared/SelectListBoxLoadingItem.js +4 -2
  33. package/dist/components/inputs/Selection/shared/SelectMobile.js +5 -2
  34. package/dist/components/inputs/Selection/shared/selectItem.cva.d.ts +6 -0
  35. package/dist/components/inputs/Selection/shared/selectItem.cva.js +21 -0
  36. package/dist/components/inputs/TextEditor/TextEditor.d.ts +1 -0
  37. package/dist/components/inputs/TextEditor/TextEditor.js +7 -3
  38. package/dist/config/uiConfig.context.d.ts +1 -2
  39. package/dist/config/uiConfig.context.js +2 -2
  40. package/dist/config/uiStyle.context.d.ts +4 -0
  41. package/dist/utils/date-time.utils.d.ts +0 -10
  42. package/dist/utils/date-time.utils.js +1 -82
  43. package/package.json +1 -1
  44. package/dist/components/inputs/shared/StaticInput.d.ts +0 -18
  45. package/dist/components/inputs/shared/StaticInput.js +0 -69
@@ -1,7 +1,8 @@
1
- interface InputUploadFilledProps {
1
+ import { InputSizeProps } from '../../shared/input.cva';
2
+ interface InputUploadFilledProps extends Pick<InputSizeProps, "size"> {
2
3
  files: File[];
3
4
  onRemove: () => void;
4
5
  isDisabled?: boolean;
5
6
  }
6
- export declare const InputUploadFilled: ({ files, onRemove, isDisabled }: InputUploadFilledProps) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const InputUploadFilled: ({ files, onRemove, isDisabled, size }: InputUploadFilledProps) => import("react/jsx-runtime").JSX.Element;
7
8
  export {};
@@ -6,9 +6,9 @@ import { inputSize } from "../../shared/input.cva.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { clsx } from "clsx";
8
8
  //#region src/components/inputs/File/shared/InputUploadFilled.tsx
9
- var InputUploadFilled = ({ files, onRemove, isDisabled }) => {
9
+ var InputUploadFilled = ({ files, onRemove, isDisabled, size }) => {
10
10
  return /* @__PURE__ */ jsxs("div", {
11
- className: clsx("flex items-center rounded-input-rounding-default border border-input-outlined-outline-idle border-solid bg-input-outlined-idle", UIStyle.useCva("input.sizeCva", inputSize)({ size: "default" })),
11
+ className: clsx("flex items-center rounded-input-rounding-default border border-input-outlined-outline-idle border-solid bg-input-outlined-idle", UIStyle.useCva("input.sizeCva", inputSize)({ size })),
12
12
  children: [/* @__PURE__ */ jsx(Typography, {
13
13
  variant: "default",
14
14
  size: "label-1",
@@ -13,7 +13,6 @@ 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;
17
16
  }
18
17
  export type NumberInputProps = NumberInputBaseProps;
19
18
  export type ControlledNumberInputProps<TFieldValues extends FieldValues> = ControlProps<NumberInputProps, TFieldValues>;
@@ -1,25 +1,23 @@
1
1
  import { UIStyle } from "../../../../config/uiStyle.context.js";
2
- import { Loader } from "../../../status/Loader/Loader.js";
3
2
  import { UIConfig } from "../../../../config/uiConfig.context.js";
4
3
  import { inputBase } from "../../shared/input.cva.js";
5
4
  import { FormField } from "../../FormField/FormField.js";
6
- import { StaticInput } from "../../shared/StaticInput.js";
7
5
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
6
  import { InputContent } from "../shared/InputContent.js";
9
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { jsx } from "react/jsx-runtime";
10
8
  import { clsx } from "clsx";
11
- import { isValidElement, useCallback, useEffect, useRef, useState } from "react";
9
+ import { useCallback, useRef } from "react";
12
10
  import { Input, useLocale } from "react-aria-components";
13
11
  import { useFocusVisible, useNumberField } from "react-aria";
14
12
  import { mergeRefs } from "@react-aria/utils";
15
- import { Controller, useWatch } from "react-hook-form";
13
+ import { Controller } from "react-hook-form";
16
14
  import { useNumberFieldState } from "react-stately";
17
15
  //#region src/components/inputs/Input/NumberInput/NumberInput.tsx
18
16
  var NumberInputBase = (props) => {
19
17
  const ui = UIConfig.useConfig();
20
18
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
21
19
  const inputRef = useRef(null);
22
- 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;
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
21
  const numberFieldRef = useRef(null);
24
22
  const { isFocusVisible } = useFocusVisible();
25
23
  const { locale } = useLocale();
@@ -36,10 +34,6 @@ var NumberInputBase = (props) => {
36
34
  formatOptions
37
35
  };
38
36
  const { labelProps, inputProps } = useNumberField(numberProps, useNumberFieldState(numberProps), numberFieldRef);
39
- useEffect(() => {
40
- if (!autoFocusOnMount || isDisabled) return;
41
- requestAnimationFrame(() => inputRef.current?.focus());
42
- }, [autoFocusOnMount, isDisabled]);
43
37
  const formFieldProps = {
44
38
  error,
45
39
  label,
@@ -107,7 +101,8 @@ var NumberInputBase = (props) => {
107
101
  "data-is-dirty": isDirty || void 0,
108
102
  "data-is-required": isRequired || void 0,
109
103
  "data-is-empty": value === null || value === void 0 || void 0,
110
- placeholder: as === "floating" ? "" : inputProps.placeholder,
104
+ "data-is-filled": !("" + value === "" || value === null || value === void 0) || void 0,
105
+ placeholder: as === "floating" ? "\xA0" : inputProps.placeholder,
111
106
  className: "w-full outline-none",
112
107
  onFocus: (e) => {
113
108
  inputProps.onFocus?.(e);
@@ -119,68 +114,7 @@ var NumberInputBase = (props) => {
119
114
  })
120
115
  });
121
116
  };
122
- var renderIconVisual = (icon) => {
123
- if (!icon) return null;
124
- if (isValidElement(icon)) return icon;
125
- return /* @__PURE__ */ jsx(icon, { className: "size-6 text-interactive-text-secondary-idle" });
126
- };
127
117
  var NumberInput = (props) => {
128
- const ui = UIConfig.useConfig();
129
- const [renderInput, setRenderInput] = useState(!ui.renderStaticInput);
130
- const [shouldFocus, setShouldFocus] = useState(false);
131
- const inputRef = useRef(null);
132
- const watchedValue = "formControl" in props && props.formControl ? useWatch({
133
- control: props.formControl.control,
134
- name: props.formControl.name
135
- }) : props.value;
136
- let isFormControlDisabled = false;
137
- if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
138
- useEffect(() => {
139
- if (!renderInput || !shouldFocus) return;
140
- requestAnimationFrame(() => inputRef.current?.focus());
141
- setShouldFocus(false);
142
- }, [renderInput, shouldFocus]);
143
- if (!renderInput) {
144
- const staticValue = watchedValue ?? props.value ?? props.defaultValue;
145
- const displayValue = staticValue == null ? "" : `${staticValue}`;
146
- const hasValue = displayValue !== "";
147
- const as = props.as ?? ui.input.as;
148
- const size = props.size ?? ui.input.size;
149
- const variant = props.variant ?? ui.input.variant;
150
- const hideLabel = props.hideLabel ?? ui.input.hideLabel;
151
- const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
152
- let isDisabled = !!props.isDisabled;
153
- if (isFormControlDisabled) isDisabled = true;
154
- const trailingVisual = !!props.unit || !!props.isLoading || !!props.action && !props.isLoading || !!props.trailingIcon && !props.isLoading && !props.action ? /* @__PURE__ */ jsxs(Fragment, { children: [
155
- props.unit && /* @__PURE__ */ jsx("span", {
156
- className: "text-label-2 text-text-default-3",
157
- children: props.unit
158
- }),
159
- props.isLoading && /* @__PURE__ */ jsx(Loader, {}),
160
- !props.isLoading && props.action && renderIconVisual(props.action.icon),
161
- !props.isLoading && !props.action && props.trailingIcon && renderIconVisual(props.trailingIcon)
162
- ] }) : void 0;
163
- return /* @__PURE__ */ jsx(StaticInput, {
164
- ...props,
165
- onInteract: (focus) => {
166
- setShouldFocus(focus);
167
- setRenderInput(true);
168
- },
169
- as,
170
- size,
171
- variant,
172
- hideLabel,
173
- isHeaderHidden,
174
- isDisabled,
175
- className: clsx("group w-full", as === "inline" && "h-full", props.className),
176
- inputClassName: props.inputClassName,
177
- placeholder: as === "floating" ? "" : props.placeholder,
178
- displayValue,
179
- isEmpty: !hasValue,
180
- leadingVisual: renderIconVisual(props.leadingIcon),
181
- trailingVisual
182
- });
183
- }
184
118
  if ("formControl" in props && props.formControl) {
185
119
  const { formControl, ref, ...innerProps } = props;
186
120
  return /* @__PURE__ */ jsx(Controller, {
@@ -188,22 +122,17 @@ var NumberInput = (props) => {
188
122
  name: formControl.name,
189
123
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(NumberInputBase, {
190
124
  ...innerProps,
191
- ref: mergeRefs(ref, field.ref, inputRef),
125
+ ref: mergeRefs(ref, field.ref),
192
126
  value: field.value,
193
127
  onChange: field.onChange,
194
128
  onBlur: field.onBlur,
195
129
  isDirty,
196
130
  isDisabled: field.disabled || props.isDisabled,
197
- error: props.error ?? error?.message,
198
- autoFocusOnMount: shouldFocus
131
+ error: props.error ?? error?.message
199
132
  }, field.value === null || field.value === void 0 ? "empty" : "filled")
200
133
  });
201
134
  }
202
- return /* @__PURE__ */ jsx(NumberInputBase, {
203
- ...props,
204
- ref: mergeRefs(props.ref, inputRef),
205
- autoFocusOnMount: shouldFocus
206
- }, props.value === null || props.value === void 0 ? "empty" : "filled");
135
+ return /* @__PURE__ */ jsx(NumberInputBase, { ...props }, props.value === null || props.value === void 0 ? "empty" : "filled");
207
136
  };
208
137
  //#endregion
209
138
  export { NumberInput };
@@ -13,7 +13,6 @@ interface TextInputBaseProps extends FormFieldProps, InputVariantProps, Omit<Inp
13
13
  type?: AllowedHTMLInputTypeAttribute;
14
14
  todayIcon?: boolean;
15
15
  isDirty?: boolean;
16
- autoFocusOnMount?: boolean;
17
16
  }
18
17
  export interface TextInputProps extends TextInputBaseProps {
19
18
  }
@@ -1,24 +1,22 @@
1
1
  import { UIStyle } from "../../../../config/uiStyle.context.js";
2
- import { Loader } from "../../../status/Loader/Loader.js";
3
2
  import { UIConfig } from "../../../../config/uiConfig.context.js";
4
3
  import { inputBase } from "../../shared/input.cva.js";
5
4
  import { FormField } from "../../FormField/FormField.js";
6
- import { StaticInput } from "../../shared/StaticInput.js";
7
5
  import { TooltipWrapper } from "../../shared/TooltipWrapper.js";
8
6
  import { InputContent } from "../shared/InputContent.js";
9
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { jsx } from "react/jsx-runtime";
10
8
  import { clsx } from "clsx";
11
- import { isValidElement, useEffect, useRef, useState } from "react";
9
+ import { useRef } from "react";
12
10
  import { Input } from "react-aria-components";
13
11
  import { useFocusVisible, useTextField } from "react-aria";
14
12
  import { mergeRefs } from "@react-aria/utils";
15
- import { Controller, useWatch } from "react-hook-form";
13
+ import { Controller } from "react-hook-form";
16
14
  //#region src/components/inputs/Input/TextInput/TextInput.tsx
17
15
  var TextInputBase = (props) => {
18
16
  const ui = UIConfig.useConfig();
19
17
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
20
18
  const inputRef = useRef(null);
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;
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;
22
20
  const textFieldRef = useRef(null);
23
21
  const { isFocusVisible } = useFocusVisible();
24
22
  const { labelProps, inputProps } = useTextField({
@@ -31,10 +29,6 @@ var TextInputBase = (props) => {
31
29
  onChange,
32
30
  onBlur
33
31
  }, textFieldRef);
34
- useEffect(() => {
35
- if (!autoFocusOnMount || isDisabled) return;
36
- requestAnimationFrame(() => inputRef.current?.focus());
37
- }, [autoFocusOnMount, isDisabled]);
38
32
  const formFieldProps = {
39
33
  error,
40
34
  label,
@@ -97,10 +91,11 @@ var TextInputBase = (props) => {
97
91
  ...inputProps,
98
92
  ref: mergeRefs(ref, inputRef),
99
93
  "data-is-empty": value === "" || value === null || value === void 0 || void 0,
94
+ "data-is-filled": !(value === "" || value === null || value === void 0) || void 0,
100
95
  "data-is-dirty": isDirty || void 0,
101
96
  "data-is-required": isRequired || void 0,
102
97
  "data-is-disabled": isDisabled || void 0,
103
- placeholder: as === "floating" ? "" : inputProps.placeholder,
98
+ placeholder: as === "floating" ? "\xA0" : inputProps.placeholder,
104
99
  className: "w-full outline-none",
105
100
  onFocus: (e) => {
106
101
  inputProps.onFocus?.(e);
@@ -112,71 +107,7 @@ var TextInputBase = (props) => {
112
107
  })
113
108
  });
114
109
  };
115
- var renderIconVisual = (icon) => {
116
- if (!icon) return null;
117
- if (isValidElement(icon)) return icon;
118
- return /* @__PURE__ */ jsx(icon, { className: "size-6 text-interactive-text-secondary-idle" });
119
- };
120
110
  var TextInput = (props) => {
121
- const ui = UIConfig.useConfig();
122
- const [renderInput, setRenderInput] = useState(!ui.renderStaticInput);
123
- const [shouldFocus, setShouldFocus] = useState(false);
124
- const inputRef = useRef(null);
125
- const watchedValue = "formControl" in props && props.formControl ? useWatch({
126
- control: props.formControl.control,
127
- name: props.formControl.name
128
- }) : props.value;
129
- let isFormControlDisabled = false;
130
- if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
131
- const staticValue = watchedValue ?? props.value ?? props.defaultValue ?? "";
132
- const inputType = props.type;
133
- if (!renderInput && inputType === "password" && `${staticValue}`.length > 0) setRenderInput(true);
134
- useEffect(() => {
135
- if (!renderInput || !shouldFocus) return;
136
- requestAnimationFrame(() => inputRef.current?.focus());
137
- setShouldFocus(false);
138
- }, [renderInput, shouldFocus]);
139
- if (!renderInput) {
140
- const as = props.as ?? ui.input.as;
141
- const size = props.size ?? ui.input.size;
142
- const variant = props.variant ?? ui.input.variant;
143
- const hideLabel = props.hideLabel ?? ui.input.hideLabel;
144
- const isHeaderHidden = props.isHeaderHidden || as === "inline" || as === "filter" || as === "floating";
145
- let isDisabled = !!props.isDisabled;
146
- if (isFormControlDisabled) isDisabled = true;
147
- const maskedPasswordValue = inputType === "password" && `${staticValue}`.length > 0 ? "•".repeat(`${staticValue}`.length) : staticValue;
148
- const displayValue = maskedPasswordValue == null ? "" : `${maskedPasswordValue}`;
149
- const hasValue = displayValue !== "";
150
- const trailingVisual = !!props.unit || !!props.isLoading || !!props.action && !props.isLoading || !!props.trailingIcon && !props.isLoading && !props.action ? /* @__PURE__ */ jsxs(Fragment, { children: [
151
- props.unit && /* @__PURE__ */ jsx("span", {
152
- className: "text-label-2 text-text-default-3",
153
- children: props.unit
154
- }),
155
- props.isLoading && /* @__PURE__ */ jsx(Loader, {}),
156
- !props.isLoading && props.action && renderIconVisual(props.action.icon),
157
- !props.isLoading && !props.action && props.trailingIcon && renderIconVisual(props.trailingIcon)
158
- ] }) : void 0;
159
- return /* @__PURE__ */ jsx(StaticInput, {
160
- ...props,
161
- onInteract: (focus) => {
162
- setShouldFocus(focus);
163
- setRenderInput(true);
164
- },
165
- as,
166
- size,
167
- variant,
168
- hideLabel,
169
- isHeaderHidden,
170
- isDisabled,
171
- className: clsx("group w-full", as === "inline" && "h-full", props.className),
172
- inputClassName: props.inputClassName,
173
- placeholder: as === "floating" ? "" : props.placeholder,
174
- displayValue,
175
- isEmpty: !hasValue,
176
- leadingVisual: renderIconVisual(props.leadingIcon),
177
- trailingVisual
178
- });
179
- }
180
111
  if ("formControl" in props && props.formControl) {
181
112
  const { formControl, ref, ...innerProps } = props;
182
113
  return /* @__PURE__ */ jsx(Controller, {
@@ -184,22 +115,17 @@ var TextInput = (props) => {
184
115
  name: formControl.name,
185
116
  render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(TextInputBase, {
186
117
  ...innerProps,
187
- ref: mergeRefs(ref, field.ref, inputRef),
118
+ ref: mergeRefs(ref, field.ref),
188
119
  value: field.value,
189
120
  onChange: field.onChange,
190
121
  onBlur: field.onBlur,
191
122
  isDirty,
192
123
  isDisabled: field.disabled || props.isDisabled,
193
- error: props.error ?? error?.message,
194
- autoFocusOnMount: shouldFocus
124
+ error: props.error ?? error?.message
195
125
  })
196
126
  });
197
127
  }
198
- return /* @__PURE__ */ jsx(TextInputBase, {
199
- ...props,
200
- ref: mergeRefs(props.ref, inputRef),
201
- autoFocusOnMount: shouldFocus
202
- });
128
+ return /* @__PURE__ */ jsx(TextInputBase, { ...props });
203
129
  };
204
130
  //#endregion
205
131
  export { TextInput };
@@ -1,24 +1,21 @@
1
- import { ArrowDropDownIcon } from "../../../../assets/icons/ArrowDropDown.js";
2
- import { UIConfig } from "../../../../config/uiConfig.context.js";
3
- import { StaticInput } from "../../shared/StaticInput.js";
4
1
  import { SelectBase } from "../shared/SelectBase.js";
5
2
  import { jsx } from "react/jsx-runtime";
6
- import { isValidElement, useEffect, useRef, useState } from "react";
7
3
  import { mergeRefs } from "@react-aria/utils";
8
- import { Controller, useWatch } from "react-hook-form";
4
+ import { Controller } from "react-hook-form";
9
5
  //#region src/components/inputs/Selection/Autocomplete/Autocomplete.tsx
10
- var _Autocomplete = (props) => {
6
+ var Autocomplete = (props) => {
11
7
  if ("formControl" in props && props.formControl) {
12
8
  const { formControl, ref, ...innerProps } = props;
13
9
  return /* @__PURE__ */ jsx(Controller, {
14
10
  control: formControl.control,
15
11
  name: formControl.name,
16
- render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(SelectBase, {
12
+ render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(SelectBase, {
17
13
  ...innerProps,
18
14
  ref: mergeRefs(ref, field.ref),
19
15
  value: field.value,
20
16
  onChange: field.onChange,
21
17
  onBlur: field.onBlur,
18
+ isDirty,
22
19
  isDisabled: field.disabled || props.isDisabled,
23
20
  error: props.error ?? error?.message,
24
21
  isSearchable: true
@@ -30,61 +27,5 @@ var _Autocomplete = (props) => {
30
27
  isSearchable: true
31
28
  });
32
29
  };
33
- var Autocomplete = (props) => {
34
- const ui = UIConfig.useConfig();
35
- const [renderInput, setRenderInput] = useState(!ui.renderStaticInput);
36
- const [shouldFocus, setShouldFocus] = useState(false);
37
- const rootRef = useRef(null);
38
- const currentValue = ("formControl" in props && props.formControl ? useWatch({
39
- control: props.formControl.control,
40
- name: props.formControl.name
41
- }) : props.value) ?? props.value;
42
- let isFormControlDisabled = false;
43
- if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
44
- useEffect(() => {
45
- if (!renderInput || !shouldFocus) return;
46
- requestAnimationFrame(() => {
47
- (rootRef.current?.querySelector("input, [data-type='select-trigger'], button, [tabindex]"))?.focus();
48
- });
49
- setShouldFocus(false);
50
- }, [renderInput, shouldFocus]);
51
- if (!renderInput) {
52
- const getItemLabel = (id) => {
53
- const item = props.items.find((innerItem) => innerItem.id === id);
54
- if (!item) return "";
55
- if (props.showSelectionContent && item.content) return isValidElement(item.content) ? item.label : item.content;
56
- return item.label;
57
- };
58
- const mode = props.selectionMode ?? ui.select.selectionMode;
59
- let displayValue = "";
60
- if (mode === "multiple") {
61
- if (Array.isArray(currentValue) && currentValue.length > 0) displayValue = currentValue.map((id) => getItemLabel(id)).filter(Boolean).join(", ");
62
- } else if (currentValue != null) displayValue = getItemLabel(currentValue);
63
- const as = props.as ?? ui.input.as;
64
- let isDisabled = !!props.isDisabled;
65
- if (isFormControlDisabled) isDisabled = true;
66
- return /* @__PURE__ */ jsx(StaticInput, {
67
- ...props,
68
- onInteract: (focus) => {
69
- setShouldFocus(focus);
70
- setRenderInput(true);
71
- },
72
- as,
73
- size: props.size ?? ui.input.size,
74
- variant: props.variant ?? ui.input.variant,
75
- isHeaderHidden: props.isHeaderHidden || as === "inline",
76
- hideLabel: props.hideLabel ?? ui.input.hideLabel,
77
- isDisabled,
78
- placeholder: as === "floating" ? "" : props.placeholder,
79
- displayValue,
80
- isEmpty: !displayValue,
81
- trailingVisual: /* @__PURE__ */ jsx(ArrowDropDownIcon, { className: "size-6 shrink-0 text-interactive-text-secondary-idle" })
82
- });
83
- }
84
- return /* @__PURE__ */ jsx(_Autocomplete, {
85
- ...props,
86
- ref: mergeRefs(props.ref, rootRef)
87
- });
88
- };
89
30
  //#endregion
90
31
  export { Autocomplete };
@@ -1,24 +1,21 @@
1
- import { ArrowDropDownIcon } from "../../../../assets/icons/ArrowDropDown.js";
2
- import { UIConfig } from "../../../../config/uiConfig.context.js";
3
- import { StaticInput } from "../../shared/StaticInput.js";
4
1
  import { SelectBase } from "../shared/SelectBase.js";
5
2
  import { jsx } from "react/jsx-runtime";
6
- import { isValidElement, useEffect, useRef, useState } from "react";
7
3
  import { mergeRefs } from "@react-aria/utils";
8
- import { Controller, useWatch } from "react-hook-form";
4
+ import { Controller } from "react-hook-form";
9
5
  //#region src/components/inputs/Selection/Select/Select.tsx
10
- var _Select = (props) => {
6
+ var Select = (props) => {
11
7
  if ("formControl" in props && props.formControl) {
12
8
  const { formControl, ref, ...innerProps } = props;
13
9
  return /* @__PURE__ */ jsx(Controller, {
14
10
  control: formControl.control,
15
11
  name: formControl.name,
16
- render: ({ field, fieldState: { error } }) => /* @__PURE__ */ jsx(SelectBase, {
12
+ render: ({ field, fieldState: { error, isDirty } }) => /* @__PURE__ */ jsx(SelectBase, {
17
13
  ...innerProps,
18
14
  ref: mergeRefs(ref, field.ref),
19
15
  value: field.value,
20
16
  onChange: field.onChange,
21
17
  onBlur: field.onBlur,
18
+ isDirty,
22
19
  isDisabled: field.disabled || props.isDisabled,
23
20
  error: props.error ?? error?.message
24
21
  })
@@ -26,62 +23,5 @@ var _Select = (props) => {
26
23
  }
27
24
  return /* @__PURE__ */ jsx(SelectBase, { ...props });
28
25
  };
29
- var Select = (props) => {
30
- const ui = UIConfig.useConfig();
31
- const [renderInput, setRenderInput] = useState(!ui.renderStaticInput);
32
- const [shouldFocus, setShouldFocus] = useState(false);
33
- const rootRef = useRef(null);
34
- const currentValue = ("formControl" in props && props.formControl ? useWatch({
35
- control: props.formControl.control,
36
- name: props.formControl.name
37
- }) : props.value) ?? props.value;
38
- let isFormControlDisabled = false;
39
- if ("formControl" in props && props.formControl) isFormControlDisabled = !!props.formControl.control._options?.disabled;
40
- if (!renderInput && props.selectionMode !== "multiple" && !!props.showSelectionContent && currentValue != null) setRenderInput(true);
41
- useEffect(() => {
42
- if (!renderInput || !shouldFocus) return;
43
- requestAnimationFrame(() => {
44
- (rootRef.current?.querySelector("[data-type='select-trigger'], input, button, [tabindex]"))?.focus();
45
- });
46
- setShouldFocus(false);
47
- }, [renderInput, shouldFocus]);
48
- if (!renderInput) {
49
- const getItemLabel = (id) => {
50
- const item = props.items.find((innerItem) => innerItem.id === id);
51
- if (!item) return "";
52
- if (props.showSelectionContent && item.content) return isValidElement(item.content) ? item.label : item.content;
53
- return item.label;
54
- };
55
- const mode = props.selectionMode ?? ui.select.selectionMode;
56
- let displayValue = "";
57
- if (mode === "multiple") {
58
- if (Array.isArray(currentValue) && currentValue.length > 0) displayValue = currentValue.map((id) => getItemLabel(id)).filter(Boolean).join(", ");
59
- } else if (currentValue != null) displayValue = getItemLabel(currentValue);
60
- const as = props.as ?? ui.input.as;
61
- let isDisabled = !!props.isDisabled;
62
- if (isFormControlDisabled) isDisabled = true;
63
- return /* @__PURE__ */ jsx(StaticInput, {
64
- ...props,
65
- onInteract: (focus) => {
66
- setShouldFocus(focus);
67
- setRenderInput(true);
68
- },
69
- as,
70
- size: props.size ?? ui.input.size,
71
- variant: props.variant ?? ui.input.variant,
72
- isHeaderHidden: props.isHeaderHidden || as === "inline",
73
- hideLabel: props.hideLabel ?? ui.input.hideLabel,
74
- isDisabled,
75
- placeholder: as === "floating" ? "" : props.placeholder,
76
- displayValue,
77
- isEmpty: !displayValue,
78
- trailingVisual: /* @__PURE__ */ jsx(ArrowDropDownIcon, { className: "size-6 shrink-0 text-interactive-text-secondary-idle" })
79
- });
80
- }
81
- return /* @__PURE__ */ jsx(_Select, {
82
- ...props,
83
- ref: mergeRefs(props.ref, rootRef)
84
- });
85
- };
86
26
  //#endregion
87
27
  export { Select };
@@ -7,6 +7,7 @@ import { InputVariantProps } from '../../shared/input.cva';
7
7
  export type SelectBaseProps<TKey extends Key = Key, TInitialSelectItem = DefaultInitialSelectItem<TKey>> = FormFieldProps & GroupedSelectProps<TKey, TInitialSelectItem> & SelectNewItemProps & SelectAsyncProps & SelectVirtualizationProps & InputVariantProps & Pick<AriaButtonProps, "onBlur"> & {
8
8
  ref?: Ref<HTMLDivElement>;
9
9
  className?: string;
10
+ isDirty?: boolean;
10
11
  placeholder?: string;
11
12
  hideDropdownIcon?: boolean;
12
13
  hideSearchIcon?: boolean;
@@ -20,6 +21,7 @@ export type SelectBaseProps<TKey extends Key = Key, TInitialSelectItem = Default
20
21
  customTrigger?: ReactElement;
21
22
  selectedTagsType?: "tags" | "list";
22
23
  collapseAfter?: number;
24
+ fireBlurOnChange?: boolean;
23
25
  onInputChange?: (value: string) => void;
24
26
  onSearchChange?: (value: string) => void;
25
27
  mapInitialToSelectItem?: (item: TInitialSelectItem) => SelectItem<TKey>;
@@ -19,7 +19,8 @@ var SelectBase = (dProps) => {
19
19
  selectedTagsType: dProps.selectedTagsType ?? ui.select.selectedTagsType,
20
20
  ignoreTriggerWidth: dProps.virtualizerOptions || dProps.items.length > 100 ? false : dProps.ignoreTriggerWidth ?? false,
21
21
  collapseAfter: dProps.collapseAfter ?? ui.select.collapseAfter,
22
- hideSearchIcon: dProps.hideSearchIcon ?? ui.select.hideSearchIcon
22
+ hideSearchIcon: dProps.hideSearchIcon ?? ui.select.hideSearchIcon,
23
+ fireBlurOnChange: dProps.fireBlurOnChange ?? ui.select.fireBlurOnChange
23
24
  };
24
25
  const isDesktop = useBreakpoint("md");
25
26
  return /* @__PURE__ */ jsx(SelectContext.Provider, {
@@ -14,7 +14,7 @@ import { useLabel, usePreventScroll } from "react-aria";
14
14
  import { mergeRefs } from "@react-aria/utils";
15
15
  //#region src/components/inputs/Selection/shared/SelectDesktop.tsx
16
16
  var SelectDesktop = ({ ref, error, ignoreTriggerWidth, showSelectionContent, inputClassName, containerClassName, customTrigger, onBlur, ...props }) => {
17
- const { label, tooltipText, helperText, isRequired, rightContent, isHeaderHidden, headerClassName, errorClassName, placeholder, variant, isDisabled, className, hideLabel, hideDropdownIcon, isSearchable, isClearable, isLoading, as, size, collapseAfter, selectedTagsType } = props;
17
+ const { label, tooltipText, helperText, isDirty, isRequired, rightContent, isHeaderHidden, headerClassName, errorClassName, placeholder, variant, isDisabled, className, hideLabel, hideDropdownIcon, isSearchable, isClearable, isLoading, as, size, collapseAfter, selectedTagsType } = props;
18
18
  const popoverCva = UIStyle.useCva("popover.cva", popover);
19
19
  const formFieldProps = {
20
20
  error,
@@ -137,6 +137,8 @@ var SelectDesktop = ({ ref, error, ignoreTriggerWidth, showSelectionContent, inp
137
137
  inputClassName,
138
138
  collapseAfter,
139
139
  selectedTagsType,
140
+ isRequired,
141
+ isDirty,
140
142
  onBlur,
141
143
  onCloseComboBox: (state) => {
142
144
  if (isSearchable) closeComboBoxRef.current = state;
@@ -4,12 +4,12 @@ import { FormFieldHeaderProps } from '../../FormField/FormFieldHeader';
4
4
  import { SelectBaseProps } from './SelectBase';
5
5
  import { SelectItem } from './select.types';
6
6
  import { InputVariantProps } from '../../shared/input.cva';
7
- interface SelectInputProps extends InputVariantProps, Pick<SelectBaseProps, "ref" | "placeholder" | "isDisabled" | "hideDropdownIcon" | "isSearchable" | "isClearable" | "onBlur" | "showSelectionContent" | "inputClassName" | "selectedTagsType" | "collapseAfter"> {
7
+ interface SelectInputProps extends InputVariantProps, Pick<SelectBaseProps, "ref" | "placeholder" | "isDisabled" | "hideDropdownIcon" | "isSearchable" | "isClearable" | "onBlur" | "showSelectionContent" | "inputClassName" | "selectedTagsType" | "collapseAfter" | "isRequired" | "isDirty" | "fireBlurOnChange"> {
8
8
  isInvalid?: boolean;
9
9
  className?: string;
10
10
  fieldProps?: AriaFieldProps;
11
11
  headerProps?: FormFieldHeaderProps;
12
12
  onCloseComboBox?: (state: ComboBoxState<SelectItem> | null) => void;
13
13
  }
14
- export declare const SelectInput: ({ ref, placeholder, variant, as, size, isDisabled, isInvalid, className, hideDropdownIcon, isSearchable, isClearable, showSelectionContent, inputClassName, fieldProps, headerProps, selectedTagsType, collapseAfter, onCloseComboBox, onBlur, ...props }: SelectInputProps) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const SelectInput: ({ ref, placeholder, variant, as, size, isDisabled, isInvalid, className, hideDropdownIcon, isSearchable, isClearable, showSelectionContent, inputClassName, fieldProps, headerProps, selectedTagsType, collapseAfter, isRequired, isDirty, onCloseComboBox, onBlur, fireBlurOnChange, ...props }: SelectInputProps) => import("react/jsx-runtime").JSX.Element;
15
15
  export {};
@@ -14,7 +14,7 @@ import { Button, ComboBoxStateContext, Input } from "react-aria-components";
14
14
  import { useFocusVisible, useFocusWithin, useHover } from "react-aria";
15
15
  import { useTranslation } from "react-i18next";
16
16
  //#region src/components/inputs/Selection/shared/SelectInput.tsx
17
- var SelectInput = ({ ref, placeholder, variant, as, size, isDisabled, isInvalid, className, hideDropdownIcon, isSearchable, isClearable, showSelectionContent, inputClassName, fieldProps, headerProps, selectedTagsType, collapseAfter, onCloseComboBox, onBlur, ...props }) => {
17
+ var SelectInput = ({ ref, placeholder, variant, as, size, isDisabled, isInvalid, className, hideDropdownIcon, isSearchable, isClearable, showSelectionContent, inputClassName, fieldProps, headerProps, selectedTagsType, collapseAfter, isRequired, isDirty, onCloseComboBox, onBlur, fireBlurOnChange, ...props }) => {
18
18
  const inputSizeCva = UIStyle.useCva("input.sizeCva", inputSize);
19
19
  const inputBaseCva = UIStyle.useCva("input.baseCva", inputBase);
20
20
  const { t } = useTranslation("ui");
@@ -44,9 +44,13 @@ var SelectInput = ({ ref, placeholder, variant, as, size, isDisabled, isInvalid,
44
44
  if (e.key === "Enter" && !isMultiple && !isLoading && listItems.length === 1 && !listItems[0].isDisabled) {
45
45
  e.preventDefault();
46
46
  onChange(listItems[0].id);
47
+ if (fireBlurOnChange) onBlur?.({});
47
48
  onCloseComboBox?.(state);
48
49
  }
49
- if (e.key === "Backspace" && isMultiple && fieldState.inputValue === "" && Array.isArray(fieldState.value) && fieldState.value.length > 0) onChange(fieldState.value.slice(0, -1));
50
+ if (e.key === "Backspace" && isMultiple && fieldState.inputValue === "" && Array.isArray(fieldState.value) && fieldState.value.length > 0) {
51
+ onChange(fieldState.value.slice(0, -1));
52
+ if (fireBlurOnChange) onBlur?.({});
53
+ }
50
54
  };
51
55
  const onClick = () => {
52
56
  if (isDisabled) return;
@@ -75,6 +79,9 @@ var SelectInput = ({ ref, placeholder, variant, as, size, isDisabled, isInvalid,
75
79
  "data-has-search": fieldState.searchValue !== "" || void 0,
76
80
  "data-invalid": isInvalid || void 0,
77
81
  "data-is-empty": isEmpty || void 0,
82
+ "data-is-filled": !isEmpty || void 0,
83
+ "data-is-required": isRequired || void 0,
84
+ "data-is-dirty": isDirty || void 0,
78
85
  "data-select-input": "",
79
86
  ...hoverProps,
80
87
  ...focusWithinProps,
@@ -125,7 +132,10 @@ var SelectInput = ({ ref, placeholder, variant, as, size, isDisabled, isInvalid,
125
132
  ]
126
133
  }),
127
134
  isClearable && /* @__PURE__ */ jsx(InputClear, {
128
- onClear,
135
+ onClear: () => {
136
+ onClear();
137
+ if (fireBlurOnChange) onBlur?.({});
138
+ },
129
139
  show: showClearButton
130
140
  }),
131
141
  !hideDropdownIcon && /* @__PURE__ */ jsx(Button, {
@@ -4,5 +4,4 @@ interface SelectListBoxItemProps extends Pick<SelectBaseProps, "isSearchable" |
4
4
  isNewItem?: boolean;
5
5
  }
6
6
  export declare const SelectListBoxItem: ({ isSearchable, isNewItem, newItemRender, id, label, content, isDisabled, }: SelectListBoxItemProps) => import("react/jsx-runtime").JSX.Element;
7
- export declare const selectListBoxItemClass: string;
8
7
  export {};