@scm-manager/ui-core 4.0.0-REACT19-20250825-073633 → 4.0.0-REACT19-20250910-124634

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 (60) hide show
  1. package/.turbo/turbo-test.log +174 -0
  2. package/.turbo/turbo-typecheck.log +1 -1
  3. package/package.json +4 -4
  4. package/src/base/buttons/Button.tsx +74 -60
  5. package/src/base/buttons/Icon.tsx +4 -3
  6. package/src/base/forms/ConfigurationForm.tsx +7 -7
  7. package/src/base/forms/FormRow.tsx +9 -9
  8. package/src/base/forms/base/Control.tsx +7 -3
  9. package/src/base/forms/base/ExpandableText.tsx +11 -12
  10. package/src/base/forms/checkbox/Checkbox.tsx +63 -65
  11. package/src/base/forms/checkbox/CheckboxField.tsx +4 -4
  12. package/src/base/forms/chip-input/ChipInputField.tsx +28 -30
  13. package/src/base/forms/chip-input/ControlledChipInputField.tsx +20 -22
  14. package/src/base/forms/combobox/Combobox.tsx +3 -13
  15. package/src/base/forms/combobox/ComboboxField.tsx +11 -14
  16. package/src/base/forms/headless-chip-input/ChipInput.tsx +49 -46
  17. package/src/base/forms/helpers.ts +3 -7
  18. package/src/base/forms/input/Input.tsx +4 -3
  19. package/src/base/forms/input/InputField.tsx +55 -43
  20. package/src/base/forms/input/Textarea.tsx +4 -3
  21. package/src/base/forms/radio-button/RadioButton.tsx +37 -27
  22. package/src/base/forms/radio-button/RadioGroup.tsx +4 -3
  23. package/src/base/forms/radio-button/RadioGroupField.tsx +15 -16
  24. package/src/base/forms/select/Select.tsx +15 -16
  25. package/src/base/forms/select/SelectField.tsx +19 -19
  26. package/src/base/layout/_helpers/with-classes.tsx +15 -12
  27. package/src/base/layout/card/Card.tsx +28 -21
  28. package/src/base/layout/card/CardDetail.tsx +65 -76
  29. package/src/base/layout/card/CardRow.tsx +9 -9
  30. package/src/base/layout/card/CardTitle.tsx +5 -5
  31. package/src/base/layout/card-list/CardList.tsx +9 -9
  32. package/src/base/layout/collapsible/Collapsible.tsx +42 -35
  33. package/src/base/layout/tabs/TabTrigger.tsx +5 -4
  34. package/src/base/layout/tabs/Tabs.tsx +4 -4
  35. package/src/base/layout/tabs/TabsList.tsx +5 -3
  36. package/src/base/layout/templates/data-page/DataPageHeader.tsx +10 -11
  37. package/src/base/misc/Image.tsx +5 -5
  38. package/src/base/misc/Level.tsx +4 -3
  39. package/src/base/misc/Loading.tsx +25 -25
  40. package/src/base/misc/SubSubtitle.tsx +9 -9
  41. package/src/base/misc/Subtitle.tsx +10 -10
  42. package/src/base/misc/Title.tsx +22 -14
  43. package/src/base/notifications/Notification.tsx +12 -13
  44. package/src/base/overlays/dialog/Dialog.tsx +39 -40
  45. package/src/base/overlays/menu/Menu.tsx +49 -52
  46. package/src/base/overlays/menu/MenuTrigger.tsx +6 -6
  47. package/src/base/overlays/popover/Popover.tsx +4 -6
  48. package/src/base/overlays/tooltip/ExpandableHint.tsx +7 -8
  49. package/src/base/overlays/tooltip/Tooltip.tsx +5 -3
  50. package/src/base/status/StatusIcon.tsx +46 -39
  51. package/src/index.ts +1 -0
  52. package/src/routing/admin.ts +38 -0
  53. package/src/routing/group.ts +22 -0
  54. package/src/routing/help.ts +21 -0
  55. package/src/routing/import.ts +17 -0
  56. package/src/routing/index.ts +24 -0
  57. package/src/routing/me.ts +26 -0
  58. package/src/routing/namespace.ts +39 -0
  59. package/src/routing/repository.ts +91 -0
  60. package/src/routing/user.ts +22 -0
@@ -14,7 +14,7 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React, { InputHTMLAttributes } from "react";
17
+ import React, { InputHTMLAttributes, Ref, FC } from "react";
18
18
  import { createAttributesForTesting } from "../../helpers";
19
19
  import Help from "../base/help/Help";
20
20
  import styled from "styled-components";
@@ -36,71 +36,53 @@ type InputFieldProps = {
36
36
  descriptionText?: string;
37
37
  testId?: string;
38
38
  labelClassName?: string;
39
+ ref?: Ref<HTMLInputElement>;
39
40
  } & Omit<InputHTMLAttributes<HTMLInputElement>, "type">;
40
41
 
41
42
  /**
42
43
  * @see https://bulma.io/documentation/form/checkbox/
43
44
  */
44
- const Checkbox = React.forwardRef<HTMLInputElement, InputFieldProps>(
45
- (
46
- {
47
- readOnly,
48
- label,
49
- descriptionText,
50
- className,
51
- labelClassName,
52
- value,
53
- name,
54
- checked,
55
- defaultChecked,
56
- defaultValue,
57
- testId,
58
- helpText,
59
- ...props
60
- },
61
- ref
62
- ) => {
63
- const descriptionId = descriptionText ? `checkbox-description-${name}` : undefined;
64
- return (
65
- <>
66
- {descriptionText ? <p id={descriptionId}>{descriptionText}</p> : null}
67
- <StyledLabel
68
- className={classNames("checkbox is-align-items-center", labelClassName)}
69
- // @ts-ignore bulma uses the disabled attribute on labels, although it is not part of the html spec
70
- disabled={readOnly || props.disabled}
71
- >
72
- {readOnly ? (
73
- <>
74
- <input
75
- type="hidden"
76
- name={name}
77
- value={value}
78
- defaultValue={defaultValue}
79
- checked={checked}
80
- defaultChecked={defaultChecked}
81
- aria-describedby={descriptionId}
82
- readOnly
83
- />
84
- <StyledInput
85
- type="checkbox"
86
- className={classNames("m-3", className)}
87
- ref={ref}
88
- value={value}
89
- defaultValue={defaultValue}
90
- checked={checked}
91
- defaultChecked={defaultChecked}
92
- aria-describedby={descriptionId}
93
- {...props}
94
- {...createAttributesForTesting(testId)}
95
- disabled
96
- />
97
- </>
98
- ) : (
45
+ const Checkbox: FC<InputFieldProps> = ({
46
+ readOnly,
47
+ label,
48
+ descriptionText,
49
+ className,
50
+ labelClassName,
51
+ value,
52
+ name,
53
+ checked,
54
+ defaultChecked,
55
+ defaultValue,
56
+ testId,
57
+ helpText,
58
+ ref,
59
+ ...props
60
+ }) => {
61
+ const descriptionId = descriptionText ? `checkbox-description-${name}` : undefined;
62
+ return (
63
+ <>
64
+ {descriptionText ? <p id={descriptionId}>{descriptionText}</p> : null}
65
+ <StyledLabel
66
+ className={classNames("checkbox is-align-items-center", labelClassName)}
67
+ // @ts-ignore bulma uses the disabled attribute on labels, although it is not part of the html spec
68
+ disabled={readOnly || props.disabled}
69
+ >
70
+ {readOnly ? (
71
+ <>
72
+ <input
73
+ type="hidden"
74
+ name={name}
75
+ value={value}
76
+ defaultValue={defaultValue}
77
+ checked={checked}
78
+ defaultChecked={defaultChecked}
79
+ aria-describedby={descriptionId}
80
+ readOnly
81
+ />
99
82
  <StyledInput
100
83
  type="checkbox"
101
84
  className={classNames("m-3", className)}
102
85
  ref={ref}
103
- name={name}
104
86
  value={value}
105
87
  defaultValue={defaultValue}
106
88
  checked={checked}
@@ -108,14 +90,30 @@ const Checkbox = React.forwardRef<HTMLInputElement, InputFieldProps>(
108
90
  aria-describedby={descriptionId}
109
91
  {...props}
110
92
  {...createAttributesForTesting(testId)}
93
+ disabled
111
94
  />
112
- )}
95
+ </>
96
+ ) : (
97
+ <StyledInput
98
+ type="checkbox"
99
+ className={classNames("m-3", className)}
100
+ ref={ref}
101
+ name={name}
102
+ value={value}
103
+ defaultValue={defaultValue}
104
+ checked={checked}
105
+ defaultChecked={defaultChecked}
106
+ aria-describedby={descriptionId}
107
+ {...props}
108
+ {...createAttributesForTesting(testId)}
109
+ />
110
+ )}
111
+
112
+ {label}
113
+ {helpText ? <Help className="ml-1" text={helpText} /> : null}
114
+ </StyledLabel>
115
+ </>
116
+ );
117
+ };
113
118
 
114
- {label}
115
- {helpText ? <Help className="ml-1" text={helpText} /> : null}
116
- </StyledLabel>
117
- </>
118
- );
119
- }
120
- );
121
119
  export default Checkbox;
@@ -14,18 +14,18 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React from "react";
17
+ import React, { Ref, FC } from "react";
18
18
  import Field from "../base/Field";
19
19
  import Control from "../base/Control";
20
20
  import Checkbox from "./Checkbox";
21
21
 
22
- type Props = React.ComponentProps<typeof Checkbox>;
22
+ type Props = React.ComponentProps<typeof Checkbox> & { ref?: Ref<HTMLInputElement> };
23
23
 
24
- const CheckboxField = React.forwardRef<HTMLInputElement, Props>(({ className, ...props }, ref) => (
24
+ const CheckboxField: FC<Props> = ({ className, ref, ...props }) => (
25
25
  <Field className={className}>
26
26
  <Control>
27
27
  <Checkbox ref={ref} {...props} />
28
28
  </Control>
29
29
  </Field>
30
- ));
30
+ );
31
31
  export default CheckboxField;
@@ -14,7 +14,7 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React, { KeyboardEventHandler, PropsWithRef, ReactElement, Ref, useCallback } from "react";
17
+ import React, { KeyboardEventHandler, ReactElement, Ref, useCallback, FC } from "react";
18
18
  import { createAttributesForTesting, useAriaId } from "../../helpers";
19
19
  import Field from "../base/Field";
20
20
  import Label from "../base/label/Label";
@@ -26,18 +26,17 @@ import { createVariantClass, Variant } from "../variants";
26
26
  import ChipInput, { NewChipInput } from "../headless-chip-input/ChipInput";
27
27
  import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
28
28
  import { useTranslation } from "react-i18next";
29
- import { withForwardRef } from "../helpers";
30
29
  import { Option } from "@scm-manager/ui-types";
31
30
 
32
- const ChipInputWrapper = React.forwardRef<HTMLUListElement, any>((props, ref) => (
31
+ const ChipInputWrapper: FC<any> = ({ ref, ...props }) => (
33
32
  // @ts-ignore
34
33
  <ChipInput ref={ref} {...props} />
35
- ));
34
+ );
36
35
 
37
- const NewChipInputWrapper = React.forwardRef<HTMLUListElement, any>((props, ref) => (
36
+ const NewChipInputWrapper: FC<any> = ({ ref, ...props }) => (
38
37
  // @ts-ignore
39
38
  <NewChipInput ref={ref} {...props} />
40
- ));
39
+ );
41
40
 
42
41
  const StyledChipInput = styled(ChipInputWrapper)`
43
42
  min-height: 40px;
@@ -102,29 +101,27 @@ const determineVariant = (error: string | undefined, warning: string | undefined
102
101
  * @beta
103
102
  * @since 2.44.0
104
103
  */
105
- const ChipInputField = function ChipInputField<T>(
106
- {
107
- label,
108
- helpText,
109
- information,
110
- readOnly,
111
- disabled,
112
- error,
113
- warning,
114
- createDeleteText,
115
- onChange,
116
- placeholder,
117
- value,
118
- className,
119
- testId,
120
- id,
121
- children,
122
- isLoading,
123
- isNewItemDuplicate,
124
- ...props
125
- }: PropsWithRef<InputFieldProps<T>>,
126
- ref: React.ForwardedRef<HTMLInputElement>,
127
- ) {
104
+ const ChipInputField = function ChipInputField<T>({
105
+ label,
106
+ helpText,
107
+ information,
108
+ readOnly,
109
+ disabled,
110
+ error,
111
+ warning,
112
+ createDeleteText,
113
+ onChange,
114
+ placeholder,
115
+ value,
116
+ className,
117
+ testId,
118
+ id,
119
+ children,
120
+ isLoading,
121
+ isNewItemDuplicate,
122
+ ref,
123
+ ...props
124
+ }: InputFieldProps<T>) {
128
125
  const [t] = useTranslation("commons", { keyPrefix: "form.chipList" });
129
126
  const deleteTextCallback = useCallback(
130
127
  (item: any) => (createDeleteText ? createDeleteText(item) : t("delete", { item })),
@@ -185,4 +182,5 @@ const ChipInputField = function ChipInputField<T>(
185
182
  </Field>
186
183
  );
187
184
  };
188
- export default withForwardRef(ChipInputField);
185
+
186
+ export default ChipInputField;
@@ -14,11 +14,11 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React, { ComponentProps } from "react";
17
+ import React, { ComponentProps, Ref } from "react";
18
18
  import { Controller, ControllerRenderProps, Path } from "react-hook-form";
19
19
  import { useScmFormContext } from "../ScmFormContext";
20
20
  import { useScmFormPathContext } from "../FormPathContext";
21
- import { defaultOptionFactory, prefixWithoutIndices, withForwardRef } from "../helpers";
21
+ import { defaultOptionFactory, prefixWithoutIndices } from "../helpers";
22
22
  import classNames from "classnames";
23
23
  import ChipInputField from "./ChipInputField";
24
24
  import { Option } from "@scm-manager/ui-types";
@@ -33,31 +33,29 @@ type Props<T extends Record<string, unknown>> = Omit<
33
33
  defaultValue?: string[];
34
34
  createDeleteText?: (value: string) => string;
35
35
  optionFactory?: (val: any) => Option<unknown>;
36
- ref?: React.ForwardedRef<HTMLInputElement>;
36
+ ref?: Ref<HTMLInputElement>;
37
37
  };
38
38
 
39
39
  /**
40
40
  * @beta
41
41
  * @since 2.44.0
42
42
  */
43
- function ControlledChipInputField<T extends Record<string, unknown>>(
44
- {
45
- name,
46
- label,
47
- helpText,
48
- rules,
49
- testId,
50
- defaultValue,
51
- readOnly,
52
- placeholder,
53
- className,
54
- createDeleteText,
55
- children,
56
- optionFactory = defaultOptionFactory,
57
- ...props
58
- }: Props<T>,
59
- ref: React.ForwardedRef<HTMLInputElement>,
60
- ) {
43
+ function ControlledChipInputField<T extends Record<string, unknown>>({
44
+ name,
45
+ label,
46
+ helpText,
47
+ rules,
48
+ testId,
49
+ defaultValue,
50
+ readOnly,
51
+ placeholder,
52
+ className,
53
+ createDeleteText,
54
+ children,
55
+ optionFactory = defaultOptionFactory,
56
+ ref,
57
+ ...props
58
+ }: Props<T>) {
61
59
  const { control, t, readOnly: formReadonly } = useScmFormContext();
62
60
  const formPathPrefix = useScmFormPathContext();
63
61
 
@@ -102,4 +100,4 @@ function ControlledChipInputField<T extends Record<string, unknown>>(
102
100
  );
103
101
  }
104
102
 
105
- export default withForwardRef(ControlledChipInputField);
103
+ export default ControlledChipInputField;
@@ -14,20 +14,10 @@
14
14
  * along with this program. If not, see https://www.gnu.org/licenses/.
15
15
  */
16
16
 
17
- import React, {
18
- ForwardedRef,
19
- Fragment,
20
- KeyboardEventHandler,
21
- ReactElement,
22
- Ref,
23
- useEffect,
24
- useRef,
25
- useState,
26
- } from "react";
17
+ import React, { Fragment, KeyboardEventHandler, ReactElement, Ref, useEffect, useRef, useState } from "react";
27
18
  import { Combobox as HeadlessCombobox } from "@headlessui/react";
28
19
  import classNames from "classnames";
29
20
  import styled from "styled-components";
30
- import { withForwardRef } from "../helpers";
31
21
  import { createAttributesForTesting } from "../../helpers";
32
22
  import { Option } from "@scm-manager/ui-types";
33
23
 
@@ -104,7 +94,7 @@ export type ComboboxProps<T> =
104
94
  * @beta
105
95
  * @since 2.45.0
106
96
  */
107
- function ComboboxComponent<T>(props: ComboboxProps<T>, ref: ForwardedRef<HTMLInputElement>) {
97
+ function ComboboxComponent<T>({ ref, ...props }: ComboboxProps<T>) {
108
98
  const [query, setQuery] = useState("");
109
99
  const { onQueryChange } = props;
110
100
 
@@ -212,7 +202,7 @@ function ComboboxOptions<T>({ query, options, children }: ComboboxOptionsProps<T
212
202
  );
213
203
  }
214
204
 
215
- const Combobox = Object.assign(withForwardRef(ComboboxComponent), {
205
+ const Combobox = Object.assign(ComboboxComponent, {
216
206
  Option: StyledComboboxOption,
217
207
  });
218
208
 
@@ -19,7 +19,6 @@ import Label from "../base/label/Label";
19
19
  import Help from "../base/help/Help";
20
20
  import React from "react";
21
21
  import { useAriaId } from "../../helpers";
22
- import { withForwardRef } from "../helpers";
23
22
  import Combobox, { ComboboxProps } from "./Combobox";
24
23
  import classNames from "classnames";
25
24
  import RequiredMarker from "../misc/RequiredMarker";
@@ -28,18 +27,16 @@ import RequiredMarker from "../misc/RequiredMarker";
28
27
  * @beta
29
28
  * @since 2.45.0
30
29
  */
31
- const ComboboxField = function ComboboxField<T>(
32
- {
33
- label,
34
- helpText,
35
- error,
36
- className,
37
- isLoading,
38
- required,
39
- ...props
40
- }: ComboboxProps<T> & { label: string; helpText?: string; error?: string; isLoading?: boolean; required?: boolean },
41
- ref: React.ForwardedRef<HTMLInputElement>,
42
- ) {
30
+ const ComboboxField = function ComboboxField<T>({
31
+ label,
32
+ helpText,
33
+ error,
34
+ className,
35
+ isLoading,
36
+ required,
37
+ ref,
38
+ ...props
39
+ }: ComboboxProps<T> & { label: string; helpText?: string; error?: string; isLoading?: boolean; required?: boolean }) {
43
40
  const labelId = useAriaId();
44
41
  return (
45
42
  <Field className={className}>
@@ -55,4 +52,4 @@ const ComboboxField = function ComboboxField<T>(
55
52
  </Field>
56
53
  );
57
54
  };
58
- export default withForwardRef(ComboboxField);
55
+ export default ComboboxField;
@@ -20,10 +20,12 @@ import React, {
20
20
  ComponentType,
21
21
  Context,
22
22
  createContext,
23
+ FC,
23
24
  HTMLAttributes,
24
25
  KeyboardEventHandler,
25
26
  LiHTMLAttributes,
26
27
  ReactElement,
28
+ Ref,
27
29
  RefObject,
28
30
  useCallback,
29
31
  useContext,
@@ -32,7 +34,7 @@ import React, {
32
34
  } from "react";
33
35
  import { Slot } from "@radix-ui/react-slot";
34
36
  import { Option } from "@scm-manager/ui-types";
35
- import { mergeRefs, withForwardRef } from "../helpers";
37
+ import { mergeRefs } from "../helpers";
36
38
  import { Button } from "../../buttons";
37
39
 
38
40
  type ChipInputContextType<T> = {
@@ -54,46 +56,45 @@ type CustomNewChipInputProps<T> = {
54
56
  value?: Option<T> | null;
55
57
  readOnly?: boolean;
56
58
  disabled?: boolean;
57
- ref?: React.Ref<HTMLInputElement>;
59
+ ref?: Ref<HTMLInputElement>;
58
60
  className?: string;
59
61
  placeholder?: string;
60
62
  id?: string;
61
63
  "aria-describedby"?: string;
62
64
  };
63
65
 
64
- const DefaultNewChipInput = React.forwardRef<HTMLInputElement, CustomNewChipInputProps<string>>(
65
- ({ onChange, value, ...props }, ref) => {
66
- const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(
67
- (e) => {
68
- if (e.key === "Enter") {
69
- e.preventDefault();
70
- if (e.currentTarget.value) {
71
- onChange({ label: e.currentTarget.value, value: e.currentTarget.value });
72
- }
73
- return false;
66
+ const DefaultNewChipInput: FC<CustomNewChipInputProps<string>> = ({ onChange, value, ref, ...props }) => {
67
+ const handleKeyDown = useCallback<KeyboardEventHandler<HTMLInputElement>>(
68
+ (e) => {
69
+ if (e.key === "Enter") {
70
+ e.preventDefault();
71
+ if (e.currentTarget.value) {
72
+ onChange({ label: e.currentTarget.value, value: e.currentTarget.value });
74
73
  }
75
- },
76
- [onChange],
77
- );
78
-
79
- return (
80
- <div className="is-flex-grow-1">
81
- <input onKeyDown={handleKeyDown} {...props} ref={ref} />
82
- </div>
83
- );
84
- },
85
- );
74
+ return false;
75
+ }
76
+ },
77
+ [onChange],
78
+ );
79
+
80
+ return (
81
+ <div className="is-flex-grow-1">
82
+ <input onKeyDown={handleKeyDown} {...props} ref={ref} />
83
+ </div>
84
+ );
85
+ };
86
86
 
87
87
  type ChipDeleteProps = {
88
88
  asChild?: boolean;
89
89
  index: number;
90
+ ref?: Ref<HTMLButtonElement>;
90
91
  } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, "type" | "onClick">;
91
92
 
92
93
  /**
93
94
  * @beta
94
95
  * @since 2.44.0
95
96
  */
96
- export const ChipDelete = React.forwardRef<HTMLButtonElement, ChipDeleteProps>(({ asChild, index, ...props }, ref) => {
97
+ export const ChipDelete: FC<ChipDeleteProps> = ({ asChild, index, ref, ...props }) => {
97
98
  const { remove, disabled } = useContext(ChipInputContext);
98
99
  const Comp = asChild ? Slot : "button";
99
100
 
@@ -102,11 +103,11 @@ export const ChipDelete = React.forwardRef<HTMLButtonElement, ChipDeleteProps>((
102
103
  }
103
104
 
104
105
  return <Comp {...props} ref={ref} type="button" onClick={() => remove(index)} />;
105
- });
106
+ };
106
107
 
107
108
  type NewChipInputProps = {
108
109
  children?: ReactElement | null;
109
- ref?: React.Ref<HTMLInputElement>;
110
+ ref: Ref<HTMLInputElement>;
110
111
  className?: string;
111
112
  placeholder?: string;
112
113
  id?: string;
@@ -117,10 +118,7 @@ type NewChipInputProps = {
117
118
  * @beta
118
119
  * @since 2.44.0
119
120
  */
120
- export const NewChipInput = withForwardRef(function NewChipInput<T>(
121
- props: NewChipInputProps,
122
- ref: React.ForwardedRef<HTMLInputElement>,
123
- ) {
121
+ export const NewChipInput = function NewChipInput<T>(props: NewChipInputProps) {
124
122
  const { add, disabled, readOnly, inputRef } = useContext(getChipInputContext<T>());
125
123
 
126
124
  const Comp = props.children ? Slot : DefaultNewChipInput;
@@ -130,21 +128,20 @@ export const NewChipInput = withForwardRef(function NewChipInput<T>(
130
128
  readOnly,
131
129
  disabled,
132
130
  value: null,
133
- ref: mergeRefs(ref, inputRef),
131
+ ref: mergeRefs(props.ref, inputRef),
134
132
  });
135
- });
136
-
137
- type ChipProps = { asChild?: boolean } & LiHTMLAttributes<HTMLLIElement>;
133
+ };
138
134
 
135
+ type ChipProps = { asChild?: boolean; ref?: Ref<HTMLLIElement> } & LiHTMLAttributes<HTMLLIElement>;
139
136
  /**
140
137
  * @beta
141
138
  * @since 2.44.0
142
139
  */
143
- export const Chip = React.forwardRef<HTMLLIElement, ChipProps>(({ asChild, ...props }, ref) => {
140
+ export const Chip: FC<ChipProps> = ({ asChild, ref, ...props }) => {
144
141
  const Comp = asChild ? Slot : "li";
145
142
 
146
143
  return <Comp {...props} ref={ref} />;
147
- });
144
+ };
148
145
 
149
146
  type Props<T> = {
150
147
  value?: Option<T>[] | null;
@@ -152,16 +149,23 @@ type Props<T> = {
152
149
  readOnly?: boolean;
153
150
  disabled?: boolean;
154
151
  isNewItemDuplicate?: (existingItem: Option<T>, newItem: Option<T>) => boolean;
152
+ ref?: Ref<HTMLUListElement>;
155
153
  } & Omit<HTMLAttributes<HTMLUListElement>, "onChange">;
156
154
 
157
155
  /**
158
156
  * @beta
159
157
  * @since 2.44.0
160
158
  */
161
- const ChipInput = withForwardRef(function ChipInput<T>(
162
- { children, value = [], disabled, readOnly, onChange, isNewItemDuplicate, ...props }: Props<T>,
163
- ref: React.ForwardedRef<HTMLUListElement>,
164
- ) {
159
+ const ChipInput = function ChipInput<T>({
160
+ children,
161
+ value = [],
162
+ disabled,
163
+ readOnly,
164
+ onChange,
165
+ isNewItemDuplicate,
166
+ ref,
167
+ ...props
168
+ }: Props<T>) {
165
169
  const inputRef = useRef<HTMLInputElement>(null);
166
170
  const isInactive = useMemo(() => disabled || readOnly, [disabled, readOnly]);
167
171
  const add = useCallback<(newValue: Option<T>) => void>(
@@ -207,19 +211,18 @@ const ChipInput = withForwardRef(function ChipInput<T>(
207
211
  </ul>
208
212
  </Context.Provider>
209
213
  );
210
- });
214
+ };
211
215
 
212
- const AddButton = React.forwardRef<
213
- HTMLButtonElement,
214
- Omit<ComponentProps<typeof Button>, "onClick"> & { inputRef: RefObject<HTMLInputElement | null> }
215
- >(({ inputRef, children, ...props }, ref) => (
216
+ type AddButtonProps = Omit<ComponentProps<typeof Button>, "onClick"> & { inputRef: RefObject<HTMLInputElement | null> };
217
+
218
+ const AddButton: FC<AddButtonProps> = ({ inputRef, children, ...props }) => (
216
219
  <Button
217
220
  {...props}
218
221
  onClick={() => inputRef.current?.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }))}
219
222
  >
220
223
  {children}
221
224
  </Button>
222
- ));
225
+ );
223
226
 
224
227
  export default Object.assign(ChipInput, {
225
228
  Chip: Object.assign(Chip, {
@@ -15,7 +15,7 @@
15
15
  */
16
16
 
17
17
  import { FieldValues, DefaultValues, UseFormReturn } from "react-hook-form";
18
- import { ForwardedRef, forwardRef, MutableRefObject, Ref, RefCallback } from "react";
18
+ import { RefCallback, RefObject } from "react";
19
19
 
20
20
  export function prefixWithoutIndices(path: string): string {
21
21
  return path.replace(/(\.\d+)/g, "");
@@ -31,7 +31,7 @@ export function prefixWithoutIndices(path: string): string {
31
31
  export function setValues<T extends FieldValues>(
32
32
  newValues: DefaultValues<T>,
33
33
  setValue: UseFormReturn<T>["setValue"],
34
- path = ""
34
+ path = "",
35
35
  ) {
36
36
  for (const key of Object.keys(newValues)) {
37
37
  const val = newValues[key as keyof typeof newValues];
@@ -46,16 +46,12 @@ export function setValues<T extends FieldValues>(
46
46
  }
47
47
  }
48
48
 
49
- export function withForwardRef<T extends { name: string }>(component: T): T {
50
- return forwardRef(component as unknown as any) as any;
51
- }
52
-
53
49
  export const defaultOptionFactory = (item: any) =>
54
50
  typeof item === "object" && item !== null && "value" in item && typeof item["label"] === "string"
55
51
  ? item
56
52
  : { label: item as string, value: item };
57
53
 
58
- export function mergeRefs<T>(...refs: Array<RefCallback<T> | MutableRefObject<T> | ForwardedRef<T>>) {
54
+ export function mergeRefs<T>(...refs: Array<RefCallback<T> | RefObject<T | null> | null>) {
59
55
  return (el: T) =>
60
56
  refs.forEach((ref) => {
61
57
  if (ref) {