@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.
- package/.turbo/turbo-test.log +174 -0
- package/.turbo/turbo-typecheck.log +1 -1
- package/package.json +4 -4
- package/src/base/buttons/Button.tsx +74 -60
- package/src/base/buttons/Icon.tsx +4 -3
- package/src/base/forms/ConfigurationForm.tsx +7 -7
- package/src/base/forms/FormRow.tsx +9 -9
- package/src/base/forms/base/Control.tsx +7 -3
- package/src/base/forms/base/ExpandableText.tsx +11 -12
- package/src/base/forms/checkbox/Checkbox.tsx +63 -65
- package/src/base/forms/checkbox/CheckboxField.tsx +4 -4
- package/src/base/forms/chip-input/ChipInputField.tsx +28 -30
- package/src/base/forms/chip-input/ControlledChipInputField.tsx +20 -22
- package/src/base/forms/combobox/Combobox.tsx +3 -13
- package/src/base/forms/combobox/ComboboxField.tsx +11 -14
- package/src/base/forms/headless-chip-input/ChipInput.tsx +49 -46
- package/src/base/forms/helpers.ts +3 -7
- package/src/base/forms/input/Input.tsx +4 -3
- package/src/base/forms/input/InputField.tsx +55 -43
- package/src/base/forms/input/Textarea.tsx +4 -3
- package/src/base/forms/radio-button/RadioButton.tsx +37 -27
- package/src/base/forms/radio-button/RadioGroup.tsx +4 -3
- package/src/base/forms/radio-button/RadioGroupField.tsx +15 -16
- package/src/base/forms/select/Select.tsx +15 -16
- package/src/base/forms/select/SelectField.tsx +19 -19
- package/src/base/layout/_helpers/with-classes.tsx +15 -12
- package/src/base/layout/card/Card.tsx +28 -21
- package/src/base/layout/card/CardDetail.tsx +65 -76
- package/src/base/layout/card/CardRow.tsx +9 -9
- package/src/base/layout/card/CardTitle.tsx +5 -5
- package/src/base/layout/card-list/CardList.tsx +9 -9
- package/src/base/layout/collapsible/Collapsible.tsx +42 -35
- package/src/base/layout/tabs/TabTrigger.tsx +5 -4
- package/src/base/layout/tabs/Tabs.tsx +4 -4
- package/src/base/layout/tabs/TabsList.tsx +5 -3
- package/src/base/layout/templates/data-page/DataPageHeader.tsx +10 -11
- package/src/base/misc/Image.tsx +5 -5
- package/src/base/misc/Level.tsx +4 -3
- package/src/base/misc/Loading.tsx +25 -25
- package/src/base/misc/SubSubtitle.tsx +9 -9
- package/src/base/misc/Subtitle.tsx +10 -10
- package/src/base/misc/Title.tsx +22 -14
- package/src/base/notifications/Notification.tsx +12 -13
- package/src/base/overlays/dialog/Dialog.tsx +39 -40
- package/src/base/overlays/menu/Menu.tsx +49 -52
- package/src/base/overlays/menu/MenuTrigger.tsx +6 -6
- package/src/base/overlays/popover/Popover.tsx +4 -6
- package/src/base/overlays/tooltip/ExpandableHint.tsx +7 -8
- package/src/base/overlays/tooltip/Tooltip.tsx +5 -3
- package/src/base/status/StatusIcon.tsx +46 -39
- package/src/index.ts +1 -0
- package/src/routing/admin.ts +38 -0
- package/src/routing/group.ts +22 -0
- package/src/routing/help.ts +21 -0
- package/src/routing/import.ts +17 -0
- package/src/routing/index.ts +24 -0
- package/src/routing/me.ts +26 -0
- package/src/routing/namespace.ts +39 -0
- package/src/routing/repository.ts +91 -0
- 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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
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,
|
|
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
|
|
31
|
+
const ChipInputWrapper: FC<any> = ({ ref, ...props }) => (
|
|
33
32
|
// @ts-ignore
|
|
34
33
|
<ChipInput ref={ref} {...props} />
|
|
35
|
-
)
|
|
34
|
+
);
|
|
36
35
|
|
|
37
|
-
const NewChipInputWrapper
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
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
|
|
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?:
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
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
|
|
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?:
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
(e)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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 {
|
|
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> |
|
|
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) {
|