@trackunit/react-form-components 1.8.121 → 1.8.123

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 (31) hide show
  1. package/index.cjs.js +873 -576
  2. package/index.esm.js +863 -572
  3. package/package.json +9 -8
  4. package/src/components/BaseInput/BaseInput.d.ts +1 -5
  5. package/src/components/BaseSelect/BaseSelect.d.ts +2 -5
  6. package/src/components/BaseSelect/BaseSelect.variants.d.ts +26 -16
  7. package/src/components/BaseSelect/CreatableSelect.d.ts +15 -10
  8. package/src/components/BaseSelect/custom-components/CounterTag.d.ts +15 -0
  9. package/src/components/BaseSelect/custom-components/MultiValue.d.ts +18 -0
  10. package/src/components/BaseSelect/{SelectMenuItem → custom-components/SelectMenuItem}/SelectMenuItem.d.ts +3 -3
  11. package/src/components/BaseSelect/index.d.ts +2 -1
  12. package/src/components/BaseSelect/useCreatableSelect.d.ts +10 -0
  13. package/src/components/BaseSelect/useCustomComponents.d.ts +26 -23
  14. package/src/components/BaseSelect/useMultiMeasure.d.ts +27 -0
  15. package/src/components/BaseSelect/useMultiValueOverflow.d.ts +21 -0
  16. package/src/components/BaseSelect/useSelect.d.ts +22 -39
  17. package/src/components/DropZone/DropZone.d.ts +1 -1
  18. package/src/components/FormGroup/FormGroup.d.ts +2 -2
  19. package/src/components/MultiSelectField/FormFieldSelectAdapterMulti.d.ts +21 -18
  20. package/src/components/MultiSelectField/MultiSelectField.d.ts +9 -4
  21. package/src/components/PhoneField/PhoneBaseInput/PhoneBaseInput.d.ts +2 -2
  22. package/src/components/SelectField/CreatableSelectField.d.ts +5 -3
  23. package/src/components/SelectField/FormFieldSelectAdapter.d.ts +14 -10
  24. package/src/components/SelectField/SelectField.d.ts +6 -9
  25. package/src/components/UrlField/UrlBaseInput/UrlBaseInput.d.ts +2 -1
  26. package/src/components/storybook-utils/sharedArgTypes.d.ts +0 -54
  27. package/src/translation.d.ts +2 -2
  28. package/src/types.d.ts +1 -1
  29. package/src/components/BaseSelect/TagWithWidth.d.ts +0 -16
  30. package/src/components/BaseSelect/TagsContainer.d.ts +0 -51
  31. package/src/components/BaseSelect/useCustomStyles.d.ts +0 -20
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-form-components",
3
- "version": "1.8.121",
3
+ "version": "1.8.123",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
@@ -8,20 +8,21 @@
8
8
  },
9
9
  "dependencies": {
10
10
  "react": "19.0.0",
11
- "react-select": "^5.10.0",
11
+ "react-select": "^5.10.2",
12
12
  "usehooks-ts": "^3.1.0",
13
13
  "libphonenumber-js": "^1.12.22",
14
14
  "zod": "^3.23.8",
15
15
  "react-hook-form": "7.62.0",
16
16
  "tailwind-merge": "^2.0.0",
17
- "@trackunit/css-class-variance-utilities": "1.7.78",
18
- "@trackunit/react-components": "1.10.53",
19
- "@trackunit/ui-icons": "1.7.79",
20
- "@trackunit/shared-utils": "1.9.78",
21
- "@trackunit/ui-design-tokens": "1.7.78",
22
- "@trackunit/i18n-library-translation": "1.7.96",
17
+ "@trackunit/css-class-variance-utilities": "1.7.80",
18
+ "@trackunit/react-components": "1.10.55",
19
+ "@trackunit/ui-icons": "1.7.81",
20
+ "@trackunit/shared-utils": "1.9.80",
21
+ "@trackunit/ui-design-tokens": "1.7.80",
22
+ "@trackunit/i18n-library-translation": "1.7.98",
23
23
  "string-ts": "^2.0.0",
24
24
  "@js-temporal/polyfill": "^0.5.1",
25
+ "es-toolkit": "^1.39.10",
25
26
  "@storybook/react-webpack5": "9.1.13"
26
27
  },
27
28
  "module": "./index.esm.js",
@@ -38,10 +38,6 @@ export interface BaseInputProps extends FilteredInputProps, CommonProps {
38
38
  * The Placeholder text for the input.
39
39
  */
40
40
  placeholder?: string;
41
- /**
42
- * Flag to disable direct interaction with the input.
43
- */
44
- nonInteractive?: boolean;
45
41
  /**
46
42
  * Custom css classes for the inner Input element.
47
43
  */
@@ -76,7 +72,7 @@ export interface BaseInputProps extends FilteredInputProps, CommonProps {
76
72
  * This is a base used by our other input components such as TextBaseInput, NumberBaseInput, PasswordBaseInput, etc.
77
73
  */
78
74
  export declare const BaseInput: {
79
- ({ className, isInvalid, "data-testid": dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize, nonInteractive, inputClassName, placeholder, isWarning, type, genericAction, style, ref, required, ...rest }: BaseInputProps): ReactElement;
75
+ ({ className, isInvalid, "data-testid": dataTestId, prefix, suffix, addonBefore, addonAfter, actions, fieldSize, inputClassName, placeholder, isWarning, type, genericAction, style, ref, required, readOnly, disabled, ...rest }: BaseInputProps): ReactElement;
80
76
  displayName: string;
81
77
  };
82
78
  export {};
@@ -7,12 +7,9 @@ export interface SelectOption<TValue extends string> {
7
7
  isDisabled?: boolean;
8
8
  }
9
9
  /**
10
- * Selects are input components used to choose a value from a set.
10
+ * BaseSelect are input components used to choose a value from a set.
11
11
  *
12
12
  * @param {SelectProps} props - The props for the Select component
13
13
  * @returns {ReactElement} Select component
14
14
  */
15
- export declare const BaseSelect: {
16
- <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(props: SelectProps<Option, IsAsync, IsMulti, Group>): ReactElement;
17
- displayName: string;
18
- };
15
+ export declare const BaseSelect: <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: SelectProps<TOption, TIsAsync, TIsMulti, TGroup>) => ReactElement;
@@ -1,23 +1,33 @@
1
- export declare const cvaSelect: (props?: ({
1
+ /**
2
+ * The container for the select component — with state styling
3
+ * !This is _the_ place in select styles to manage the aperance of the text and background
4
+ */
5
+ export declare const cvaSelectContainer: (props?: ({
2
6
  fieldSize?: "small" | "medium" | "large" | null | undefined;
3
- invalid?: boolean | null | undefined;
4
7
  disabled?: boolean | null | undefined;
5
- } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
6
- export declare const cvaSelectControl: (props?: ({
7
- isDisabled?: boolean | null | undefined;
8
- prefix?: boolean | null | undefined;
9
8
  invalid?: boolean | null | undefined;
9
+ focused?: boolean | null | undefined;
10
+ readOnly?: boolean | null | undefined;
11
+ defaultVariants?: "fieldSize" | "disabled" | "invalid" | "focused" | "readOnly" | null | undefined;
10
12
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
11
- export declare const cvaSelectIcon: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
12
- export declare const cvaSelectPrefixSuffix: (props?: ({
13
- kind?: "prefix" | "suffix" | null | undefined;
14
- } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
15
- export declare const cvaSelectXIcon: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
16
- export declare const cvaSelectMenuList: (props?: ({
13
+ export declare const cvaSelectControl: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
14
+ export declare const cvaSelectLoadingMessage: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
15
+ export declare const cvaSelectNoOptionsMessage: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
16
+ export declare const cvaSelectDropdownIconContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
17
+ export declare const cvaSelectPrefixSuffix: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
18
+ export declare const cvaSelectClearIndicator: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
19
+ export declare const cvaSelectDropdownIndicator: (props?: ({
17
20
  menuIsOpen?: boolean | null | undefined;
18
21
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
19
- export declare const cvaSelectDynamicTagContainer: (props?: ({
20
- visible?: boolean | null | undefined;
22
+ export declare const cvaSelectValueContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
23
+ export declare const cvaSelectSingleValue: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
24
+ export declare const cvaSelectMenu: (props?: ({
25
+ placement?: "bottom" | "top" | null | undefined;
26
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
27
+ export declare const cvaSelectMenuList: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
28
+ export declare const cvaSelectPlaceholder: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
29
+ export declare const cvaSelectIndicatorsContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
30
+ export declare const cvaSelectMultiValue: (props?: ({
31
+ hidden?: boolean | null | undefined;
32
+ invisible?: boolean | null | undefined;
21
33
  } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
22
- export declare const cvaSelectCounter: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
23
- export declare const cvaSelectMenu: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -1,21 +1,26 @@
1
+ import { ReactElement } from "react";
1
2
  import { GroupBase } from "react-select";
3
+ import { CreatableProps as ReactCreatableProps } from "react-select/creatable";
2
4
  import { SelectProps } from "./useSelect";
3
5
  export interface CreatableSelectOption<TValue extends string | number> {
4
6
  label: string;
5
7
  value: TValue;
6
8
  isDisabled?: boolean;
7
9
  }
8
- export type CreatableSelectProps = {
9
- allowCreateWhileLoading?: boolean;
10
- onCreateOption?: (inputValue: string) => void;
11
- };
10
+ export type CreatableSelectExtraProps<TOption, TIsMulti extends boolean, TGroup extends GroupBase<TOption> = GroupBase<TOption>> = Pick<ReactCreatableProps<TOption, TIsMulti, TGroup>, "allowCreateWhileLoading" | "onCreateOption">;
11
+ export interface CreatableSelectProps<TOption, TIsAsync extends boolean, TIsMulti extends boolean, TGroup extends GroupBase<TOption> = GroupBase<TOption>> extends SelectProps<TOption, TIsAsync, TIsMulti, TGroup>, CreatableSelectExtraProps<TOption, TIsMulti, TGroup> {
12
+ }
12
13
  /**
13
14
  * CreatableSelects are input components used to choose a value from a set.
14
15
  *
15
- * @param {CreatableSelectProps} props - The props for the CreatableSelect component
16
- * @returns {ReactElement} CreatableSelect component
16
+ /**
17
+ * CreatableSelect is a component that allows users to select from existing options or create new ones.
18
+ *
19
+ * @template TOption - The option type.
20
+ * @template TIsAsync - Indicates whether the component is asynchronous.
21
+ * @template TIsMulti - Indicates whether multiple selections are allowed.
22
+ * @template TGroup - The group base type for options.
23
+ * @param {CreatableSelectProps} props - The props to configure the CreatableSelect component.
24
+ * @returns {ReactElement} A ReactElement rendering the CreatableSelect.
17
25
  */
18
- export declare const CreatableSelect: {
19
- <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>(props: SelectProps<Option, IsAsync, IsMulti, Group> & CreatableSelectProps): import("react/jsx-runtime").JSX.Element;
20
- displayName: string;
21
- };
26
+ export declare const CreatableSelect: <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: CreatableSelectProps<TOption, TIsAsync, TIsMulti, TGroup>) => ReactElement;
@@ -0,0 +1,15 @@
1
+ import { CommonProps } from "@trackunit/react-components";
2
+ import { ReactElement, RefCallback } from "react";
3
+ import { FormComponentSizes } from "../../../types";
4
+ interface CounterTagProps extends CommonProps {
5
+ fieldSize: FormComponentSizes;
6
+ hiddenCount: number;
7
+ totalCount: number;
8
+ ref: RefCallback<HTMLDivElement>;
9
+ }
10
+ /**
11
+ * Internal component for displaying a counter badge showing hidden multi-select values.
12
+ * Used for measurement and display when tags overflow the container.
13
+ */
14
+ export declare const CounterTag: ({ fieldSize, hiddenCount, totalCount, ref, className, "data-testid": dataTestId, }: CounterTagProps) => ReactElement | null;
15
+ export {};
@@ -0,0 +1,18 @@
1
+ import { CommonProps } from "@trackunit/react-components";
2
+ import { MouseEventHandler, ReactElement, ReactNode } from "react";
3
+ import { FormComponentSizes } from "../../../types";
4
+ type MultiValueProps<TOption> = {
5
+ data: TOption;
6
+ children: ReactNode;
7
+ onClose: MouseEventHandler<HTMLDivElement> | undefined;
8
+ disabled: boolean;
9
+ fieldSize: FormComponentSizes;
10
+ getOptionPrefix?: (option: TOption) => ReactNode;
11
+ ref: (el: HTMLDivElement | null) => void;
12
+ } & CommonProps;
13
+ /**
14
+ * Internal component for rendering multi-select values with measurement support.
15
+ * Uses the measurement state to determine if the value should be displayed or hidden based on available width.
16
+ */
17
+ export declare const MultiValue: <TOption>({ data, children, onClose, className, disabled, fieldSize, getOptionPrefix, ref, "data-testid": dataTestId, }: MultiValueProps<TOption>) => ReactElement | null;
18
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
2
  import { MouseEventHandler, ReactElement, ReactNode } from "react";
3
- import { FormComponentSizes } from "../../../types";
3
+ import { FormComponentSizes } from "../../../../types";
4
4
  interface SelectMenuItemProps extends CommonProps {
5
5
  /**
6
6
  * A string to render as an item label.
@@ -52,12 +52,12 @@ export interface SingleSelectMenuItemProps extends SelectMenuItemProps {
52
52
  * @param {SelectMenuItemProps} props - The props for the SingleSelectMenuItem
53
53
  * @returns {ReactElement} SingleSelectMenuItem
54
54
  */
55
- export declare const SingleSelectMenuItem: ({ label, icon, onClick, selected, focused, "data-testid": dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }: SingleSelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
55
+ export declare const SingleSelectMenuItem: ({ label, icon, onClick, selected, focused, disabled, "data-testid": dataTestId, optionLabelDescription, optionPrefix, fieldSize, }: SingleSelectMenuItemProps) => ReactElement;
56
56
  /**
57
57
  * A multi select menu item is a basic wrapper around Menu item designed to be used as a multi value render in Select list
58
58
  *
59
59
  * @param {SelectMenuItemProps} props - The props for the MultiSelectMenuItem
60
60
  * @returns {ReactElement} multi select menu item
61
61
  */
62
- export declare const MultiSelectMenuItem: ({ label, onClick, selected, focused, "data-testid": dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }: SelectMenuItemProps) => import("react/jsx-runtime").JSX.Element;
62
+ export declare const MultiSelectMenuItem: ({ label, onClick, selected, focused, "data-testid": dataTestId, disabled, optionLabelDescription, optionPrefix, fieldSize, }: SelectMenuItemProps) => ReactElement;
63
63
  export {};
@@ -2,6 +2,7 @@ import ValueType from "react-select";
2
2
  export * from "./BaseSelect";
3
3
  export * from "./BaseSelect.variants";
4
4
  export * from "./CreatableSelect";
5
- export * from "./SelectMenuItem/SelectMenuItem";
5
+ export * from "./useCreatableSelect";
6
6
  export * from "./useCustomComponents";
7
+ export * from "./useSelect";
7
8
  export { ValueType };
@@ -0,0 +1,10 @@
1
+ import { GroupBase } from "react-select";
2
+ import { CreatableProps as ReactCreatableProps } from "react-select/creatable";
3
+ import { CreatableSelectProps } from "./CreatableSelect";
4
+ /**
5
+ * A hook used by creatable selects that extends useSelect with creatable-specific functionality
6
+ *
7
+ * @param props - The props for the CreatableSelect component
8
+ * @returns {ReactCreatableProps} Props for react-select creatable component
9
+ */
10
+ export declare const useCreatableSelect: <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: CreatableSelectProps<TOption, TIsAsync, TIsMulti, TGroup>) => ReactCreatableProps<TOption, TIsMulti, TGroup>;
@@ -1,32 +1,35 @@
1
+ /**
2
+ * Disabling react/prop-types as this hook has a lot of guards against runtime errors.
3
+ * Maybe we can try to refactor this in the future?
4
+ */
5
+ import { CommonProps } from "@trackunit/react-components";
1
6
  import { ReactNode } from "react";
2
7
  import { GroupBase } from "react-select";
3
8
  import { SelectComponents } from "react-select/dist/declarations/src/components";
4
9
  import { FormComponentSizes } from "../../types";
10
+ import { LockedForReasons } from "../BaseInput/InputLockReasonTooltip";
11
+ interface CustomComponentsProps<TOption> extends CommonProps {
12
+ disabled: boolean | LockedForReasons;
13
+ className?: string;
14
+ readOnly: boolean | LockedForReasons;
15
+ "data-testid": string;
16
+ prefix?: ReactNode;
17
+ hasError?: boolean;
18
+ fieldSize?: FormComponentSizes;
19
+ getOptionLabelDescription?: (option: TOption) => string | undefined;
20
+ getOptionPrefix?: (option: TOption) => ReactNode;
21
+ isMulti: boolean;
22
+ autoComplete?: "off" | "on" | "no";
23
+ }
5
24
  /**
6
25
  * A hook to retrieve components override object.
7
26
  * This complex object includes all the compositional components that are used in react-select. If you wish to overwrite a component, pass in an object with the appropriate namespace.
8
27
  *
9
- * @template IsMulti
10
- * @template Group
11
- * @param {Partial<SelectComponents<Option, IsMulti, Group>> | undefined} componentsProps a custom component prop that you can to override defaults
12
- * @param {boolean} disabled decide to override disabled variant
13
- * @param {boolean} menuIsOpen menu is open state
14
- * @param {string} dataTestId a test id
15
- * @param {number} maxSelectedDisplayCount a number of max display count
16
- * @param {boolean} hasError decide to override hasError variant
17
- * @param {ReactNode} prefix a prefix element
18
- * @returns {Partial<SelectComponents<Option, boolean, GroupBase<Option>>> | undefined} components object to override react-select default components
28
+ * @template TOption
29
+ * @template TIsMulti
30
+ * @template TGroup
31
+ * @param {CustomComponentsProps<TOption>} props - The custom components props
32
+ * @returns {Partial<SelectComponents<TOption, TIsMulti, TGroup>>} components object to override react-select default components
19
33
  */
20
- export declare const useCustomComponents: <Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ componentsProps, disabled, readOnly, setMenuIsEnabled, "data-testid": dataTestId, maxSelectedDisplayCount, prefix, hasError, fieldSize, getOptionLabelDescription, getOptionPrefix, }: {
21
- componentsProps: Partial<SelectComponents<Option, IsMulti, Group>> | undefined;
22
- disabled: boolean;
23
- readOnly: boolean;
24
- setMenuIsEnabled: (menuIsEnabled: boolean) => void;
25
- "data-testid": string;
26
- maxSelectedDisplayCount: number | undefined;
27
- prefix?: ReactNode;
28
- hasError?: boolean;
29
- fieldSize?: FormComponentSizes;
30
- getOptionLabelDescription?: (option: Option) => string | undefined;
31
- getOptionPrefix?: (option: Option) => ReactNode;
32
- }) => Partial<SelectComponents<Option, IsMulti, Group>>;
34
+ export declare const useCustomComponents: <TOption, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>({ disabled, readOnly, "data-testid": dataTestId, prefix, hasError, fieldSize, getOptionLabelDescription, getOptionPrefix, className, isMulti, autoComplete, }: CustomComponentsProps<TOption>) => Partial<SelectComponents<TOption, TIsMulti, TGroup>>;
35
+ export {};
@@ -0,0 +1,27 @@
1
+ import { Geometry } from "@trackunit/react-components";
2
+ type UseMultiMeasureOptions = {
3
+ skip?: boolean;
4
+ onChange?: (geometries: Map<number, Geometry>) => void;
5
+ };
6
+ type UseMultiMeasureResult = {
7
+ geometries: Map<number, Geometry>;
8
+ getRef: (index: number) => (el: HTMLElement | null) => void;
9
+ };
10
+ /**
11
+ * Custom hook to measure the geometry of multiple elements indexed by number.
12
+ * Similar to useMeasure but handles multiple elements efficiently with a single ResizeObserver.
13
+ *
14
+ * @param {UseMultiMeasureOptions} options - Configuration options
15
+ * @returns {UseMultiMeasureResult} An object containing `geometries` Map and `getRef` function to create refs
16
+ * @example
17
+ * ```tsx
18
+ * const { geometries, getRef } = useMultiMeasure({
19
+ * onChange: (geometries) => console.log('Geometries changed', geometries)
20
+ * });
21
+ * return items.map((item, index) => (
22
+ * <div key={index} ref={getRef(index)}>Item {index}</div>
23
+ * ));
24
+ * ```
25
+ */
26
+ export declare const useMultiMeasure: ({ skip, onChange }?: UseMultiMeasureOptions) => UseMultiMeasureResult;
27
+ export {};
@@ -0,0 +1,21 @@
1
+ import { RefCallback } from "react";
2
+ type UseMultiValueOverflowResult = {
3
+ setValueContainerRef: RefCallback<HTMLDivElement>;
4
+ setCounterRef: RefCallback<HTMLDivElement>;
5
+ setFakeCounterRef: RefCallback<HTMLDivElement>;
6
+ setGeometryRef: (index: number) => (el: HTMLDivElement | null) => void;
7
+ setMenuRef: RefCallback<HTMLDivElement>;
8
+ getVisibleCount: () => number;
9
+ getTotalCount: () => number;
10
+ getCounterWidth: () => boolean;
11
+ getIsComplete: () => boolean;
12
+ };
13
+ type UseMultiValueOverflowProps = {
14
+ skip?: boolean;
15
+ };
16
+ /**
17
+ * Hook to manage multi-value overflow detection and rendering.
18
+ * Measures which values fit in the container and determines when to show a counter.
19
+ */
20
+ export declare const useMultiValueOverflow: ({ skip }: UseMultiValueOverflowProps) => UseMultiValueOverflowResult;
21
+ export {};
@@ -1,16 +1,15 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
2
  import { MappedOmit } from "@trackunit/shared-utils";
3
3
  import { ReactNode } from "react";
4
- import { GroupBase, MenuPlacement, OptionsOrGroups, Props, StylesConfig } from "react-select";
5
- import { SelectComponents } from "react-select/dist/declarations/src/components";
4
+ import { GroupBase, OptionsOrGroups, Props as ReactSelectProps } from "react-select";
6
5
  import { FormComponentSizes } from "../../types";
7
6
  import { LockedForReasons } from "../BaseInput/InputLockReasonTooltip";
8
- export interface AsyncSelect<Option, Group extends GroupBase<Option> = GroupBase<Option>> {
9
- loadOptions: (input: string) => void | Promise<OptionsOrGroups<Option, Group>>;
10
- defaultOptions?: OptionsOrGroups<Option, Group>;
7
+ export interface AsyncSelect<TOption, TGroup extends GroupBase<TOption> = GroupBase<TOption>> {
8
+ loadOptions: (input: string) => void | Promise<OptionsOrGroups<TOption, TGroup>>;
9
+ defaultOptions?: OptionsOrGroups<TOption, TGroup>;
11
10
  cacheOptions: boolean;
12
11
  }
13
- export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean, GroupType extends GroupBase<Option>> = CommonProps & MappedOmit<Props<Option, IsMulti, GroupType>, "isDisabled"> & {
12
+ export type SelectProps<TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>> = CommonProps & MappedOmit<ReactSelectProps<TOption, TIsMulti, TGroup>, "isDisabled" | "styles" | "unstyled" | "components" | "menuIsOpen" | "classNames" | "maxMenuHeight" | "minMenuHeight" | "theme"> & {
14
13
  /**
15
14
  * An React element to render before the text in the select.
16
15
  * This is typically used to render an icon.
@@ -36,7 +35,7 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
36
35
  *
37
36
  * @memberof SelectProps
38
37
  */
39
- readOnly?: boolean;
38
+ readOnly?: boolean | LockedForReasons;
40
39
  /**
41
40
  * An field id
42
41
  *
@@ -49,7 +48,7 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
49
48
  *
50
49
  * @memberof SelectProps
51
50
  */
52
- async?: AsyncSelect<Option, GroupType>;
51
+ async?: TIsAsync extends true ? AsyncSelect<TOption, TGroup> : undefined;
53
52
  /**
54
53
  * A label to be used as a aria-label
55
54
  * This is typically used for accessibility
@@ -57,12 +56,6 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
57
56
  * @memberof SelectProps
58
57
  */
59
58
  label?: string;
60
- /**
61
- * A number of pixels to limit maximal length of the select menu list
62
- *
63
- * @memberof SelectProps
64
- */
65
- maxMenuHeight?: number;
66
59
  /**
67
60
  * A boolean prop to set select into invalid mode
68
61
  * typically used when selected value is not compliant with field requirement
@@ -78,18 +71,19 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
78
71
  */
79
72
  isLoading?: boolean;
80
73
  /**
81
- * A number value to limit amount of visible tags for selected options
74
+ * A custom handler for menu open event
75
+ * use if you want to trigger custom logic or fetch data
82
76
  *
83
77
  * @memberof SelectProps
84
78
  */
85
- maxSelectedDisplayCount?: number;
79
+ onMenuOpen?: () => void;
86
80
  /**
87
- * A custom handler for menu open event
88
- * use if you want to trigger custom logic or fetch data
81
+ * A custom handler for menu close event
82
+ * use if you want to trigger custom logic
89
83
  *
90
84
  * @memberof SelectProps
91
85
  */
92
- onMenuOpen?: () => void;
86
+ onMenuClose?: () => void;
93
87
  /**
94
88
  * A flag to allow user to clear value once selected
95
89
  * default value is true
@@ -103,12 +97,6 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
103
97
  * @memberof SelectProps
104
98
  */
105
99
  isSearchable?: boolean;
106
- /**
107
- * A flag to set select into async mode
108
- *
109
- * @memberof SelectProps
110
- */
111
- isAsync?: IsAsync;
112
100
  /**
113
101
  * A handler for menu close event
114
102
  * use if you want to trigger custom logic
@@ -121,34 +109,29 @@ export type SelectProps<Option, IsAsync extends boolean, IsMulti extends boolean
121
109
  *
122
110
  * @memberof SelectProps
123
111
  */
124
- getOptionLabelDescription?: (option: Option) => string | undefined;
112
+ getOptionLabelDescription?: (option: TOption) => string | undefined;
125
113
  /**
126
114
  * This callback returns
127
115
  *
128
116
  * @memberof SelectProps
129
117
  */
130
- getOptionPrefix?: (option: Option) => ReactNode;
118
+ getOptionPrefix?: (option: TOption) => ReactNode;
131
119
  /**
132
120
  * The size of the select component.
133
121
  * Large = 40px, Medium = 32px, Small = 28px.
134
122
  * Default is Medium.
135
123
  */
136
124
  fieldSize?: FormComponentSizes;
125
+ /**
126
+ * The autocomplete attribute value for the input element.
127
+ * Use "off" or "no" to disable browser autocomplete.
128
+ */
129
+ autoComplete?: "off" | "on" | "no";
137
130
  };
138
- interface UseSelectProps<Option, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>> {
139
- customStyles: StylesConfig<Option, IsMulti, Group>;
140
- customComponents: Partial<SelectComponents<Option, IsMulti, Group>>;
141
- refContainer: React.RefObject<HTMLDivElement>;
142
- menuIsOpen: boolean;
143
- menuPlacement: MenuPlacement;
144
- openMenuHandler: () => Promise<void>;
145
- closeMenuHandler: () => void;
146
- }
147
131
  /**
148
132
  * A hook used by selects to share the common code
149
133
  *
150
134
  * @param {SelectProps} props - The props for the Select component
151
- * @returns {UseSelectProps} Select component
135
+ * @returns {ReactSelectProps} Props for react-select component
152
136
  */
153
- export declare const useSelect: <Option, IsAsync extends boolean = false, IsMulti extends boolean = false, Group extends GroupBase<Option> = GroupBase<Option>>({ id, className, "data-testid": dataTestId, prefix, async, maxMenuHeight, label, hasError, disabled, isMulti, components, value, options, onChange, isLoading, classNamePrefix, onMenuOpen, onMenuClose, maxSelectedDisplayCount, isClearable, isSearchable, onMenuScrollToBottom, styles, filterOption, onInputChange, getOptionLabelDescription, getOptionPrefix, fieldSize, ...props }: SelectProps<Option, IsAsync, IsMulti, Group>) => UseSelectProps<Option, IsMulti, Group>;
154
- export {};
137
+ export declare const useSelect: <TOption, TIsAsync extends boolean = false, TIsMulti extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>({ disabled, "data-testid": dataTestId, onMenuOpen, onMenuClose, options, value, onChange, defaultValue, ...restProps }: SelectProps<TOption, TIsAsync, TIsMulti, TGroup>) => ReactSelectProps<TOption, TIsMulti, TGroup>;
@@ -1,7 +1,7 @@
1
1
  import { CommonProps, Size } from "@trackunit/react-components";
2
2
  import { ReactElement, ReactNode } from "react";
3
3
  import { BaseInputProps } from "../BaseInput";
4
- type BaseInputExposedProps = Omit<BaseInputProps, "type" | "suffix" | "prefix" | "addonAfter" | "addonBefore" | "actions" | "placeholder" | "fieldSize" | "size" | "nonInteractive">;
4
+ type BaseInputExposedProps = Omit<BaseInputProps, "type" | "suffix" | "prefix" | "addonAfter" | "addonBefore" | "actions" | "placeholder" | "fieldSize" | "size">;
5
5
  export interface DropZoneProps extends BaseInputExposedProps, CommonProps {
6
6
  /**
7
7
  * A JSX element or a string to set a focusable label in Drop Zone. If not provided, the default label will be used.
@@ -1,5 +1,5 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
- import { ReactNode } from "react";
2
+ import { ReactElement, ReactNode } from "react";
3
3
  export interface FormGroupProps extends CommonProps {
4
4
  /**
5
5
  * The label for the form group.
@@ -42,4 +42,4 @@ export interface FormGroupProps extends CommonProps {
42
42
  * @param {FormGroupProps} props - The props for the FormGroup component
43
43
  * @returns {ReactElement} FormGroup component
44
44
  */
45
- export declare const FormGroup: ({ isInvalid, isWarning, helpText, helpAddon, tip, className, "data-testid": dataTestId, label, htmlFor, children, required, }: FormGroupProps) => import("react/jsx-runtime").JSX.Element;
45
+ export declare const FormGroup: ({ isInvalid, isWarning, helpText, helpAddon, tip, className, "data-testid": dataTestId, label, htmlFor, children, required, }: FormGroupProps) => ReactElement;
@@ -1,36 +1,39 @@
1
1
  import { CommonProps } from "@trackunit/react-components";
2
2
  import { MappedOmit } from "@trackunit/shared-utils";
3
- import { FocusEvent, ReactNode, Ref } from "react";
3
+ import { FocusEvent, ReactElement, ReactNode, Ref } from "react";
4
4
  import { GroupBase, MultiValue } from "react-select";
5
5
  import { SelectProps } from "../BaseSelect/useSelect";
6
6
  import { FormGroupProps } from "../FormGroup/FormGroup";
7
+ import { BaseOptionType } from "../SelectField/FormFieldSelectAdapter";
7
8
  /**
8
9
  * NOTE: Single and multi adapters are intentionally separate.
9
10
  * Single uses a primitive value model and a real hidden <select> with <option>s,
10
11
  * dispatching native "change" events for RHF/native forms and supporting a backup option.
11
- * Multi uses MultiValue<Option> and different hidden inputs semantics.
12
+ * Multi uses MultiValue<TOption> and different hidden inputs semantics.
12
13
  * Unifying would increase conditional logic and reduce clarity.
13
14
  */
14
15
  /**
15
- * Generic over `Option` to mirror BaseSelect typing.
16
- * Multi-value uses `MultiValue<Option>` from react-select.
16
+ * Generic over `TOption` to mirror BaseSelect typing.
17
+ * Multi-value uses `MultiValue<TOption>` from react-select.
17
18
  */
18
19
  type FormGroupExposedProps = Pick<FormGroupProps, "label" | "tip" | "helpText" | "helpAddon" | "isInvalid">;
19
20
  /** Allow all BaseSelect props except those we adapt/wrap here */
20
- type SelectExposedProps<Option> = MappedOmit<SelectProps<Option, false, true, GroupBase<Option>>, "label" | "hasError" | "onBlur" | "options" | "value" | "defaultValue" | "onChange" | "isMulti" | "id">;
21
- export type MultiSelectFieldProps<Option> = CommonProps & FormGroupExposedProps & SelectExposedProps<Option> & {
21
+ type SelectExposedProps<TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>> = MappedOmit<SelectProps<TOption, TIsAsync, true, TGroup>, "label" | "hasError" | "onBlur" | "options" | "value" | "defaultValue" | "onChange" | "isMulti" | "id">;
22
+ export type MultiSelectFieldProps<TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>> = CommonProps & FormGroupExposedProps & SelectExposedProps<TOption, TIsAsync, TGroup> & {
22
23
  /** RHF/native-friendly blur signature */
23
24
  onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
24
25
  /** Options to render (same shape as BaseSelect) */
25
- options: Array<Option>;
26
+ options: Array<TOption>;
26
27
  /** Multi-value from react-select */
27
- value?: MultiValue<Option> | null;
28
+ value?: MultiValue<TOption> | null;
28
29
  /** Default selected options (MultiValue) */
29
- defaultValue?: MultiValue<Option>;
30
- /** onChange passes MultiValue<Option> (or null when cleared) */
31
- onChange?: (value: MultiValue<Option> | null) => void;
30
+ defaultValue?: MultiValue<TOption>;
31
+ /** onChange passes MultiValue<TOption> (or null when cleared) */
32
+ onChange?: (value: MultiValue<TOption> | null) => void;
32
33
  /** Invalid state message rendered via FormGroup */
33
34
  errorMessage?: string;
35
+ /** The htmlFor attribute for the label. If not provided, falls back to id or generates a unique value. */
36
+ htmlFor?: string;
34
37
  /** External ref target (points to the hidden <select /> below) */
35
38
  ref?: Ref<HTMLSelectElement>;
36
39
  /** Name used for optional hidden inputs when `getOptionValue` is provided */
@@ -38,22 +41,22 @@ export type MultiSelectFieldProps<Option> = CommonProps & FormGroupExposedProps
38
41
  /** Field id; also propagated to BaseSelect via child props */
39
42
  id?: string;
40
43
  };
41
- interface FormFieldSelectAdapterMultiProps<Option> extends MultiSelectFieldProps<Option> {
44
+ interface FormFieldSelectAdapterMultiProps<TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>> extends MultiSelectFieldProps<TOption, TIsAsync, TGroup> {
42
45
  /**
43
46
  * Child render-prop receives exact BaseSelect props specialized for multi.
44
47
  */
45
- children: (props: SelectProps<Option, false, true, GroupBase<Option>>) => ReactNode;
48
+ children: (props: SelectProps<TOption, TIsAsync, true, TGroup>) => ReactNode;
46
49
  }
47
50
  /**
48
51
  * Multi adapter:
49
- * - keeps Option[] semantics (via `MultiValue<Option>`)
52
+ * - keeps TOption[] semantics (via `MultiValue<TOption>`)
50
53
  * - renders FormGroup chrome (label, help, error)
51
54
  * - exposes a hidden <select> for a stable ref target
52
55
  * - optionally renders one hidden <input> per selected option IF `getOptionValue` is provided
53
56
  * - passes through all remaining BaseSelect props with isMulti=true
57
+ *
58
+ * @param {FormFieldSelectAdapterMultiProps} props - The props for the FormFieldSelectAdapterMulti component
59
+ * @returns {ReactElement} FormFieldSelectAdapterMulti component
54
60
  */
55
- export declare const FormFieldSelectAdapterMulti: {
56
- <Option>(props: FormFieldSelectAdapterMultiProps<Option>): import("react/jsx-runtime").JSX.Element;
57
- displayName: string;
58
- };
61
+ export declare const FormFieldSelectAdapterMulti: <TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>(props: FormFieldSelectAdapterMultiProps<TOption, TIsAsync, TGroup>) => ReactElement;
59
62
  export {};
@@ -1,10 +1,15 @@
1
+ import { ReactElement } from "react";
2
+ import { GroupBase } from "react-select";
3
+ import { BaseOptionType } from "../SelectField/FormFieldSelectAdapter";
1
4
  import { MultiSelectFieldProps } from "./FormFieldSelectAdapterMulti";
2
5
  /**
3
- * MultiSelectField validated multi-select field.
4
- * Types mirror BaseSelect: options: Option[], value/defaultValue: Option[], onChange: (Option[] | null) => void
5
- * Implemented as a generic const component (no forwardRef, no assertions).
6
+ * MultiSelectField is a custom Select component wrapped in the FormGroup component
7
+ * that allows you to select multiple options from a list.
8
+ *
9
+ * @param {MultiSelectFieldProps} props - The props for the MultiSelectField component
10
+ * @returns {ReactElement} MultiSelectField component
6
11
  */
7
12
  export declare const MultiSelectField: {
8
- <Option>({ ref, ...props }: MultiSelectFieldProps<Option>): import("react/jsx-runtime").JSX.Element;
13
+ <TOption extends BaseOptionType = BaseOptionType, TIsAsync extends boolean = false, TGroup extends GroupBase<TOption> = GroupBase<TOption>>({ ref, ...props }: MultiSelectFieldProps<TOption, TIsAsync, TGroup>): ReactElement;
9
14
  displayName: string;
10
15
  };