@scm-manager/ui-core 3.10.4-20250824-132529 → 4.0.0-REACT18-20250824-143504
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.
- package/{src/base/buttons/a11y.test.ts → .storybook/i18n.ts} +27 -9
- package/.storybook/main.ts +54 -0
- package/.storybook/preview-head.html +6 -1
- package/.storybook/preview.tsx +125 -0
- package/.turbo/turbo-test.log +164 -0
- package/.turbo/turbo-typecheck.log +3 -2
- package/package.json +36 -41
- package/src/base/buttons/Button.stories.tsx +179 -70
- package/src/base/buttons/Button.tsx +9 -9
- package/src/base/forms/AddListEntryForm.tsx +8 -8
- package/src/base/forms/ConfigurationForm.tsx +14 -5
- package/src/base/forms/Form.stories.tsx +599 -289
- package/src/base/forms/Form.tsx +8 -8
- package/src/base/forms/FormPathContext.tsx +3 -3
- package/src/base/forms/ScmFormContext.tsx +7 -4
- package/src/base/forms/ScmFormListContext.tsx +2 -1
- package/src/base/forms/base/Field.tsx +1 -1
- package/src/base/forms/base/label/Label.tsx +1 -1
- package/src/base/forms/chip-input/ChipInputField.stories.tsx +109 -28
- package/src/base/forms/chip-input/ChipInputField.tsx +20 -8
- package/src/base/forms/chip-input/ControlledChipInputField.tsx +3 -1
- package/src/base/forms/combobox/Combobox.stories.tsx +216 -89
- package/src/base/forms/combobox/Combobox.tsx +4 -2
- package/src/base/forms/combobox/ComboboxField.tsx +2 -1
- package/src/base/forms/headless-chip-input/ChipInput.tsx +9 -9
- package/src/base/forms/helpers.ts +12 -9
- package/src/base/forms/input/ControlledSecretConfirmationField.tsx +4 -2
- package/src/base/forms/radio-button/RadioButton.stories.tsx +317 -124
- package/src/base/forms/radio-button/RadioButton.tsx +8 -4
- package/src/base/forms/radio-button/RadioButtonContext.tsx +2 -1
- package/src/base/forms/table/ControlledColumn.tsx +1 -1
- package/src/base/forms/table/ControlledTable.tsx +12 -4
- package/src/base/helpers/useDocumentTitle.test.ts +15 -7
- package/src/base/layout/card/Card.stories.tsx +171 -72
- package/src/base/layout/card/Card.tsx +4 -4
- package/src/base/layout/card/CardDetail.tsx +2 -3
- package/src/base/layout/card-list/CardList.stories.tsx +283 -169
- package/src/base/layout/collapsible/Collapsible.stories.tsx +54 -16
- package/src/base/layout/index.ts +2 -5
- package/src/base/layout/tabs/Tabs.stories.tsx +58 -16
- package/src/base/layout/templates/data-page/DataPage.stories.tsx +289 -156
- package/src/base/layout/templates/data-page/DataPageHeader.tsx +1 -1
- package/src/base/overlays/dialog/Dialog.stories.tsx +94 -34
- package/src/base/overlays/menu/Menu.stories.tsx +116 -48
- package/src/base/overlays/menu/Menu.tsx +1 -0
- package/src/base/overlays/popover/Popover.stories.tsx +50 -37
- package/src/base/shortcuts/iterator/keyboardIterator.test.tsx +16 -7
- package/src/base/shortcuts/iterator/keyboardIterator.tsx +13 -5
- package/src/base/shortcuts/useShortcutDocs.tsx +2 -3
- package/src/base/status/StatusIcon.stories.tsx +76 -27
- package/src/base/status/index.ts +1 -1
- package/src/base/text/SplitAndReplace.stories.tsx +128 -50
- package/src/base/text/index.ts +1 -1
- package/.storybook/RemoveThemesPlugin.js +0 -49
- package/.storybook/main.js +0 -86
- package/.storybook/preview.js +0 -87
- package/src/base/buttons/image-snapshot.test.ts +0 -26
package/src/base/forms/Form.tsx
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import React, { FC, useCallback, useEffect, useState } from "react";
|
|
18
|
-
import {
|
|
18
|
+
import { DefaultValues, SubmitHandler, useForm, UseFormReturn } from "react-hook-form";
|
|
19
19
|
import { ErrorNotification } from "../notifications";
|
|
20
20
|
import { Level } from "../misc";
|
|
21
21
|
import { ScmFormContextProvider } from "./ScmFormContext";
|
|
@@ -47,11 +47,11 @@ const SuccessNotification: FC<{ label?: string; hide: () => void }> = ({ label,
|
|
|
47
47
|
);
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
-
type Props<FormType extends Record<string, unknown
|
|
50
|
+
type Props<FormType extends Record<string, unknown>> = {
|
|
51
51
|
children: ((renderProps: RenderProps<FormType>) => React.ReactNode | React.ReactNode[]) | React.ReactNode;
|
|
52
52
|
translationPath: [namespace: string, prefix: string];
|
|
53
53
|
onSubmit: SubmitHandler<FormType>;
|
|
54
|
-
defaultValues: DefaultValues
|
|
54
|
+
defaultValues: DefaultValues<FormType>;
|
|
55
55
|
readOnly?: boolean;
|
|
56
56
|
submitButtonTestId?: string;
|
|
57
57
|
/**
|
|
@@ -73,7 +73,7 @@ type Props<FormType extends Record<string, unknown>, DefaultValues extends FormT
|
|
|
73
73
|
*
|
|
74
74
|
* @since 2.43.0
|
|
75
75
|
*/
|
|
76
|
-
withResetTo?: DefaultValues
|
|
76
|
+
withResetTo?: DefaultValues<FormType>;
|
|
77
77
|
/**
|
|
78
78
|
* Message to display after a successful submit if no translation key is defined.
|
|
79
79
|
*
|
|
@@ -89,7 +89,7 @@ type Props<FormType extends Record<string, unknown>, DefaultValues extends FormT
|
|
|
89
89
|
* @beta
|
|
90
90
|
* @since 2.41.0
|
|
91
91
|
*/
|
|
92
|
-
function Form<FormType extends Record<string, unknown
|
|
92
|
+
function Form<FormType extends Record<string, unknown>>({
|
|
93
93
|
children,
|
|
94
94
|
onSubmit,
|
|
95
95
|
defaultValues,
|
|
@@ -99,10 +99,10 @@ function Form<FormType extends Record<string, unknown>, DefaultValues extends Fo
|
|
|
99
99
|
withDiscardChanges,
|
|
100
100
|
successMessageFallback,
|
|
101
101
|
submitButtonTestId,
|
|
102
|
-
}: Props<FormType
|
|
102
|
+
}: Props<FormType>) {
|
|
103
103
|
const form = useForm<FormType>({
|
|
104
104
|
mode: "onChange",
|
|
105
|
-
defaultValues: defaultValues
|
|
105
|
+
defaultValues: defaultValues,
|
|
106
106
|
});
|
|
107
107
|
const { formState, handleSubmit, reset, setValue } = form;
|
|
108
108
|
const [ns, prefix] = translationPath;
|
|
@@ -149,7 +149,7 @@ function Form<FormType extends Record<string, unknown>, DefaultValues extends Fo
|
|
|
149
149
|
}, [isDirty]);
|
|
150
150
|
|
|
151
151
|
const submit = useCallback(
|
|
152
|
-
async (data) => {
|
|
152
|
+
async (data: any) => {
|
|
153
153
|
setError(null);
|
|
154
154
|
try {
|
|
155
155
|
return await onSubmit(data);
|
|
@@ -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, { FC, useContext, useMemo } from "react";
|
|
17
|
+
import React, { FC, ReactNode, useContext, useMemo } from "react";
|
|
18
18
|
|
|
19
19
|
const ScmFormPathContext = React.createContext<string>("");
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@ export function useScmFormPathContext() {
|
|
|
22
22
|
return useContext(ScmFormPathContext);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export const ScmFormPathContextProvider: FC<{ path: string }> = ({ children, path }) => (
|
|
25
|
+
export const ScmFormPathContextProvider: FC<{ path: string; children?: ReactNode }> = ({ children, path }) => (
|
|
26
26
|
<ScmFormPathContext.Provider value={path}>{children}</ScmFormPathContext.Provider>
|
|
27
27
|
);
|
|
28
28
|
|
|
@@ -58,7 +58,7 @@ export const ScmFormPathContextProvider: FC<{ path: string }> = ({ children, pat
|
|
|
58
58
|
* // This pattern becomes useful in complex or large forms.
|
|
59
59
|
* ```
|
|
60
60
|
*/
|
|
61
|
-
export const ScmNestedFormPathContextProvider: FC<{ path: string }> = ({ children, path }) => {
|
|
61
|
+
export const ScmNestedFormPathContextProvider: FC<{ path: string; children?: ReactNode }> = ({ children, path }) => {
|
|
62
62
|
const prefix = useScmFormPathContext();
|
|
63
63
|
const pathWithPrefix = useMemo(() => (prefix ? `${prefix}.${path}` : path), [path, prefix]);
|
|
64
64
|
return <ScmFormPathContext.Provider value={pathWithPrefix}>{children}</ScmFormPathContext.Provider>;
|
|
@@ -15,18 +15,21 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import React, { PropsWithChildren, useContext } from "react";
|
|
18
|
-
import { UseFormReturn } from "react-hook-form";
|
|
18
|
+
import { FieldValues, UseFormReturn } from "react-hook-form";
|
|
19
19
|
import type { TFunction } from "i18next";
|
|
20
20
|
|
|
21
|
-
type ContextType<T
|
|
21
|
+
type ContextType<T extends FieldValues> = UseFormReturn<T> & {
|
|
22
22
|
t: TFunction;
|
|
23
23
|
readOnly?: boolean;
|
|
24
24
|
formId: string;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const ScmFormContext = React.createContext<ContextType
|
|
27
|
+
const ScmFormContext = React.createContext<ContextType<any>>(null as any);
|
|
28
28
|
|
|
29
|
-
export function ScmFormContextProvider<T>({
|
|
29
|
+
export function ScmFormContextProvider<T extends FieldValues>({
|
|
30
|
+
children,
|
|
31
|
+
...props
|
|
32
|
+
}: PropsWithChildren<ContextType<T>>) {
|
|
30
33
|
return <ScmFormContext.Provider value={props}>{children}</ScmFormContext.Provider>;
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -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, { FC, useContext, useMemo } from "react";
|
|
17
|
+
import React, { FC, ReactNode, useContext, useMemo } from "react";
|
|
18
18
|
import { FieldValues, useFieldArray, UseFieldArrayReturn } from "react-hook-form";
|
|
19
19
|
import { ScmFormPathContextProvider, useScmFormPathContext } from "./FormPathContext";
|
|
20
20
|
import { useScmFormContext } from "./ScmFormContext";
|
|
@@ -25,6 +25,7 @@ const ScmFormListContext = React.createContext<ContextType>(null as unknown as C
|
|
|
25
25
|
|
|
26
26
|
type Props = {
|
|
27
27
|
name: string;
|
|
28
|
+
children?: ReactNode;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -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, { FC, HTMLProps } from "react";
|
|
17
|
+
import React, { FC, HTMLProps, JSX } from "react";
|
|
18
18
|
import classNames from "classnames";
|
|
19
19
|
|
|
20
20
|
const Field: FC<HTMLProps<HTMLDivElement> | ({ as: keyof JSX.IntrinsicElements } & HTMLProps<HTMLElement>)> = ({
|
|
@@ -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, { FC, HTMLProps } from "react";
|
|
17
|
+
import React, { FC, HTMLProps, JSX } from "react";
|
|
18
18
|
import classNames from "classnames";
|
|
19
19
|
|
|
20
20
|
const Label: FC<HTMLProps<HTMLLabelElement> | ({ as: keyof JSX.IntrinsicElements } & HTMLProps<HTMLElement>)> = ({
|
|
@@ -14,37 +14,95 @@
|
|
|
14
14
|
* along with this program. If not, see https://www.gnu.org/licenses/.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import { storiesOf } from "@storybook/react";
|
|
17
|
+
// import { storiesOf } from "@storybook/react";
|
|
18
|
+
// import React, { useRef, useState } from "react";
|
|
19
|
+
// import ChipInputField from "./ChipInputField";
|
|
20
|
+
// import Combobox from "../combobox/Combobox";
|
|
21
|
+
// import { Option } from "@scm-manager/ui-types";
|
|
22
|
+
// import ChipInput from "../headless-chip-input/ChipInput";
|
|
23
|
+
//
|
|
24
|
+
// storiesOf("Chip Input Field", module)
|
|
25
|
+
// .add("Default", () => {
|
|
26
|
+
// const [value, setValue] = useState<Option<string>[]>([]);
|
|
27
|
+
// const ref = useRef<HTMLInputElement>(null);
|
|
28
|
+
// return (
|
|
29
|
+
// <>
|
|
30
|
+
// <ChipInputField
|
|
31
|
+
// value={value}
|
|
32
|
+
// onChange={setValue}
|
|
33
|
+
// label="Test Chips"
|
|
34
|
+
// placeholder="Type a new chip name and press enter to add"
|
|
35
|
+
// aria-label="My personal chip list"
|
|
36
|
+
// ref={ref}
|
|
37
|
+
// />
|
|
38
|
+
// <ChipInput.AddButton inputRef={ref}>Add</ChipInput.AddButton>
|
|
39
|
+
// </>
|
|
40
|
+
// );
|
|
41
|
+
// })
|
|
42
|
+
// .add("With Autocomplete", () => {
|
|
43
|
+
// const people = ["Durward Reynolds", "Kenton Towne", "Therese Wunsch", "Benedict Kessler", "Katelyn Rohan"];
|
|
44
|
+
//
|
|
45
|
+
// const [value, setValue] = useState<Option<string>[]>([]);
|
|
46
|
+
//
|
|
47
|
+
// return (
|
|
48
|
+
// <ChipInputField
|
|
49
|
+
// value={value}
|
|
50
|
+
// onChange={setValue}
|
|
51
|
+
// label="Persons"
|
|
52
|
+
// placeholder="Enter a new person"
|
|
53
|
+
// aria-label="Enter a new person"
|
|
54
|
+
// >
|
|
55
|
+
// <Combobox
|
|
56
|
+
// options={(query: string) =>
|
|
57
|
+
// Promise.resolve(
|
|
58
|
+
// people
|
|
59
|
+
// .map<Option<string>>((p) => ({ label: p, value: p }))
|
|
60
|
+
// .filter((t) => !value.some((val) => val.label === t.label) && t.label.startsWith(query))
|
|
61
|
+
// .concat({ label: query, value: query, displayValue: `Use '${query}'` })
|
|
62
|
+
// )
|
|
63
|
+
// }
|
|
64
|
+
// />
|
|
65
|
+
// </ChipInputField>
|
|
66
|
+
// );
|
|
67
|
+
// });
|
|
68
|
+
|
|
18
69
|
import React, { useRef, useState } from "react";
|
|
19
|
-
import
|
|
20
|
-
import Combobox from "../combobox/Combobox";
|
|
70
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
21
71
|
import { Option } from "@scm-manager/ui-types";
|
|
72
|
+
|
|
73
|
+
import ChipInputField from "./ChipInputField";
|
|
22
74
|
import ChipInput from "../headless-chip-input/ChipInput";
|
|
75
|
+
import Combobox from "../combobox/Combobox";
|
|
23
76
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const ref = useRef<HTMLInputElement>(null);
|
|
28
|
-
return (
|
|
29
|
-
<>
|
|
30
|
-
<ChipInputField
|
|
31
|
-
value={value}
|
|
32
|
-
onChange={setValue}
|
|
33
|
-
label="Test Chips"
|
|
34
|
-
placeholder="Type a new chip name and press enter to add"
|
|
35
|
-
aria-label="My personal chip list"
|
|
36
|
-
ref={ref}
|
|
37
|
-
/>
|
|
38
|
-
<ChipInput.AddButton inputRef={ref}>Add</ChipInput.AddButton>
|
|
39
|
-
</>
|
|
40
|
-
);
|
|
41
|
-
})
|
|
42
|
-
.add("With Autocomplete", () => {
|
|
43
|
-
const people = ["Durward Reynolds", "Kenton Towne", "Therese Wunsch", "Benedict Kessler", "Katelyn Rohan"];
|
|
77
|
+
const DefaultExample = () => {
|
|
78
|
+
const [value, setValue] = useState<Option<string>[]>([]);
|
|
79
|
+
const ref = useRef<HTMLInputElement>(null);
|
|
44
80
|
|
|
45
|
-
|
|
81
|
+
return (
|
|
82
|
+
<>
|
|
83
|
+
{/* @ts-ignore */}
|
|
84
|
+
<ChipInputField
|
|
85
|
+
value={value}
|
|
86
|
+
onChange={setValue}
|
|
87
|
+
label="Test Chips"
|
|
88
|
+
placeholder="Type a new chip name and press enter to add"
|
|
89
|
+
aria-label="My personal chip list"
|
|
90
|
+
ref={ref}
|
|
91
|
+
/>
|
|
92
|
+
<ChipInput.AddButton inputRef={ref} className="button is-link is-outlined ml-1 mt-2">
|
|
93
|
+
Add
|
|
94
|
+
</ChipInput.AddButton>
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const WithAutocompleteExample = () => {
|
|
100
|
+
const people = ["Durward Reynolds", "Kenton Towne", "Therese Wunsch", "Benedict Kessler", "Katelyn Rohan"];
|
|
101
|
+
const [value, setValue] = useState<Option<string>[]>([]);
|
|
46
102
|
|
|
47
|
-
|
|
103
|
+
return (
|
|
104
|
+
<>
|
|
105
|
+
{/* @ts-ignore */}
|
|
48
106
|
<ChipInputField
|
|
49
107
|
value={value}
|
|
50
108
|
onChange={setValue}
|
|
@@ -52,16 +110,39 @@ storiesOf("Chip Input Field", module)
|
|
|
52
110
|
placeholder="Enter a new person"
|
|
53
111
|
aria-label="Enter a new person"
|
|
54
112
|
>
|
|
113
|
+
{/* @ts-ignore */}
|
|
55
114
|
<Combobox
|
|
56
115
|
options={(query: string) =>
|
|
57
116
|
Promise.resolve(
|
|
58
117
|
people
|
|
59
118
|
.map<Option<string>>((p) => ({ label: p, value: p }))
|
|
60
119
|
.filter((t) => !value.some((val) => val.label === t.label) && t.label.startsWith(query))
|
|
61
|
-
.concat({ label: query, value: query, displayValue: `Use '${query}'` })
|
|
120
|
+
.concat({ label: query, value: query, displayValue: `Use '${query}'` }),
|
|
62
121
|
)
|
|
63
122
|
}
|
|
64
123
|
/>
|
|
65
124
|
</ChipInputField>
|
|
66
|
-
|
|
67
|
-
|
|
125
|
+
</>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const meta: Meta<typeof ChipInputField> = {
|
|
130
|
+
title: "Forms/ChipInputField",
|
|
131
|
+
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
component: ChipInputField,
|
|
134
|
+
decorators: [(Story) => <div style={{ margin: "2rem", maxWidth: "40rem" }}>{Story()}</div>],
|
|
135
|
+
tags: ["autodocs"],
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
export default meta;
|
|
139
|
+
|
|
140
|
+
type Story = StoryObj<typeof meta>;
|
|
141
|
+
|
|
142
|
+
export const Default: Story = {
|
|
143
|
+
render: () => <DefaultExample />,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const WithAutocomplete: Story = {
|
|
147
|
+
render: () => <WithAutocompleteExample />,
|
|
148
|
+
};
|
|
@@ -29,7 +29,17 @@ import { useTranslation } from "react-i18next";
|
|
|
29
29
|
import { withForwardRef } from "../helpers";
|
|
30
30
|
import { Option } from "@scm-manager/ui-types";
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const ChipInputWrapper = React.forwardRef<HTMLUListElement, any>((props, ref) => (
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
<ChipInput ref={ref} {...props} />
|
|
35
|
+
));
|
|
36
|
+
|
|
37
|
+
const NewChipInputWrapper = React.forwardRef<HTMLUListElement, any>((props, ref) => (
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
<NewChipInput ref={ref} {...props} />
|
|
40
|
+
));
|
|
41
|
+
|
|
42
|
+
const StyledChipInput = styled(ChipInputWrapper)`
|
|
33
43
|
min-height: 40px;
|
|
34
44
|
height: min-content;
|
|
35
45
|
gap: 0.5rem;
|
|
@@ -39,7 +49,7 @@ const StyledChipInput: typeof ChipInput = styled(ChipInput)`
|
|
|
39
49
|
}
|
|
40
50
|
`;
|
|
41
51
|
|
|
42
|
-
const StyledInput = styled(
|
|
52
|
+
const StyledInput = styled(NewChipInputWrapper)`
|
|
43
53
|
color: var(--scm-secondary-more-color);
|
|
44
54
|
font-size: 1rem;
|
|
45
55
|
height: initial;
|
|
@@ -48,7 +58,7 @@ const StyledInput = styled(NewChipInput)`
|
|
|
48
58
|
&:focus {
|
|
49
59
|
outline: none;
|
|
50
60
|
}
|
|
51
|
-
|
|
61
|
+
`;
|
|
52
62
|
|
|
53
63
|
const StyledDelete = styled(ChipInput.Chip.Delete)`
|
|
54
64
|
&:focus {
|
|
@@ -113,17 +123,18 @@ const ChipInputField = function ChipInputField<T>(
|
|
|
113
123
|
isNewItemDuplicate,
|
|
114
124
|
...props
|
|
115
125
|
}: PropsWithRef<InputFieldProps<T>>,
|
|
116
|
-
ref: React.ForwardedRef<HTMLInputElement
|
|
126
|
+
ref: React.ForwardedRef<HTMLInputElement>,
|
|
117
127
|
) {
|
|
118
128
|
const [t] = useTranslation("commons", { keyPrefix: "form.chipList" });
|
|
119
129
|
const deleteTextCallback = useCallback(
|
|
120
|
-
(item) => (createDeleteText ? createDeleteText(item) : t("delete", { item })),
|
|
121
|
-
[createDeleteText, t]
|
|
130
|
+
(item: any) => (createDeleteText ? createDeleteText(item) : t("delete", { item })),
|
|
131
|
+
[createDeleteText, t],
|
|
122
132
|
);
|
|
123
133
|
const inputId = useAriaId(id ?? testId);
|
|
124
134
|
const labelId = useAriaId();
|
|
125
135
|
const inputDescriptionId = useAriaId();
|
|
126
136
|
const variant = determineVariant(error, warning);
|
|
137
|
+
|
|
127
138
|
return (
|
|
128
139
|
<Field className={className} aria-owns={inputId}>
|
|
129
140
|
<Label id={labelId}>
|
|
@@ -134,7 +145,7 @@ const ChipInputField = function ChipInputField<T>(
|
|
|
134
145
|
<div className={classNames("control", { "is-loading": isLoading })}>
|
|
135
146
|
<StyledChipInput
|
|
136
147
|
value={value}
|
|
137
|
-
onChange={(e) => onChange && onChange(e ?? [])}
|
|
148
|
+
onChange={(e: any) => onChange && onChange(e ?? [])}
|
|
138
149
|
className="is-flex is-flex-wrap-wrap input"
|
|
139
150
|
aria-labelledby={labelId}
|
|
140
151
|
disabled={readOnly || disabled}
|
|
@@ -154,10 +165,11 @@ const ChipInputField = function ChipInputField<T>(
|
|
|
154
165
|
"is-shadowless",
|
|
155
166
|
"input",
|
|
156
167
|
"is-ellipsis-overflow",
|
|
157
|
-
createVariantClass(variant)
|
|
168
|
+
createVariantClass(variant),
|
|
158
169
|
)}
|
|
159
170
|
placeholder={!readOnly && !disabled ? placeholder : ""}
|
|
160
171
|
id={inputId}
|
|
172
|
+
// @ts-ignore
|
|
161
173
|
ref={ref}
|
|
162
174
|
aria-describedby={inputDescriptionId}
|
|
163
175
|
{...createAttributesForTesting(testId)}
|
|
@@ -56,7 +56,7 @@ function ControlledChipInputField<T extends Record<string, unknown>>(
|
|
|
56
56
|
optionFactory = defaultOptionFactory,
|
|
57
57
|
...props
|
|
58
58
|
}: Props<T>,
|
|
59
|
-
ref: React.ForwardedRef<HTMLInputElement
|
|
59
|
+
ref: React.ForwardedRef<HTMLInputElement>,
|
|
60
60
|
) {
|
|
61
61
|
const { control, t, readOnly: formReadonly } = useScmFormContext();
|
|
62
62
|
const formPathPrefix = useScmFormPathContext();
|
|
@@ -67,6 +67,7 @@ function ControlledChipInputField<T extends Record<string, unknown>>(
|
|
|
67
67
|
const placeholderTranslation = placeholder || t(`${prefixedNameWithoutIndices}.placeholder`) || "";
|
|
68
68
|
const ariaLabelTranslation = t(`${prefixedNameWithoutIndices}.ariaLabel`);
|
|
69
69
|
const helpTextTranslation = helpText || t(`${prefixedNameWithoutIndices}.helpText`);
|
|
70
|
+
|
|
70
71
|
return (
|
|
71
72
|
<Controller
|
|
72
73
|
control={control}
|
|
@@ -74,6 +75,7 @@ function ControlledChipInputField<T extends Record<string, unknown>>(
|
|
|
74
75
|
rules={rules}
|
|
75
76
|
defaultValue={defaultValue}
|
|
76
77
|
render={({ field: { value, onChange, ...field }, fieldState }) => (
|
|
78
|
+
// @ts-ignore
|
|
77
79
|
<ChipInputField
|
|
78
80
|
label={labelTranslation}
|
|
79
81
|
helpText={helpTextTranslation}
|