@bosonprotocol/react-kit 0.36.3-alpha.2 → 0.36.3-alpha.4
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/dist/cjs/components/form/Select.d.ts +48 -3
- package/dist/cjs/components/form/Select.d.ts.map +1 -1
- package/dist/cjs/components/form/Select.js +48 -21
- package/dist/cjs/components/form/Select.js.map +1 -1
- package/dist/cjs/components/form/Upload/BaseUpload.d.ts.map +1 -1
- package/dist/cjs/components/form/index.d.ts +1 -1
- package/dist/cjs/components/form/index.d.ts.map +1 -1
- package/dist/cjs/components/form/index.js +2 -3
- package/dist/cjs/components/form/index.js.map +1 -1
- package/dist/cjs/components/form/types.d.ts +2 -34
- package/dist/cjs/components/form/types.d.ts.map +1 -1
- package/dist/cjs/components/modal/components/common/VariationSelects.js +2 -2
- package/dist/cjs/components/modal/components/common/VariationSelects.js.map +1 -1
- package/dist/esm/components/form/Select.d.ts +48 -3
- package/dist/esm/components/form/Select.d.ts.map +1 -1
- package/dist/esm/components/form/Select.js +63 -24
- package/dist/esm/components/form/Select.js.map +1 -1
- package/dist/esm/components/form/Upload/BaseUpload.d.ts.map +1 -1
- package/dist/esm/components/form/index.d.ts +1 -1
- package/dist/esm/components/form/index.d.ts.map +1 -1
- package/dist/esm/components/form/index.js +1 -1
- package/dist/esm/components/form/index.js.map +1 -1
- package/dist/esm/components/form/types.d.ts +2 -34
- package/dist/esm/components/form/types.d.ts.map +1 -1
- package/dist/esm/components/modal/components/common/VariationSelects.js +2 -2
- package/dist/esm/components/modal/components/common/VariationSelects.js.map +1 -1
- package/package.json +2 -2
- package/src/components/form/Select.tsx +167 -52
- package/src/components/form/index.ts +1 -1
- package/src/components/form/types.ts +4 -44
- package/src/components/modal/components/common/VariationSelects.tsx +2 -2
- package/src/stories/selects/Select.stories.tsx +9 -2
|
@@ -1,30 +1,92 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: "off" */
|
|
2
1
|
import React from "react";
|
|
3
2
|
import { useField } from "formik";
|
|
4
|
-
import
|
|
3
|
+
import ReactSelect, {
|
|
4
|
+
GroupBase,
|
|
5
|
+
StylesConfig,
|
|
6
|
+
MultiValue,
|
|
7
|
+
SingleValue,
|
|
8
|
+
ActionMeta,
|
|
9
|
+
Props as ReactSelectProps,
|
|
10
|
+
PropsValue,
|
|
11
|
+
CSSObjectWithLabel
|
|
12
|
+
} from "react-select";
|
|
13
|
+
import { CSSProperties } from "react";
|
|
5
14
|
import { checkIfValueIsEmpty } from "../../lib/object/checkIfValueIsEmpty";
|
|
6
15
|
import { colors, getCssVar } from "../../theme";
|
|
7
16
|
import { zIndex } from "../ui/zIndex";
|
|
8
|
-
|
|
9
17
|
import Error from "./Error";
|
|
10
|
-
import type { SelectDataProps, SelectProps } from "./types";
|
|
11
18
|
import { useFixSelectFont } from "../../hooks/form/useFixSelectFont";
|
|
12
|
-
export
|
|
19
|
+
export { GroupBase } from "react-select";
|
|
20
|
+
|
|
21
|
+
// Base theme type with proper CSS types
|
|
22
|
+
type SelectTheme = Partial<{
|
|
23
|
+
control: Partial<CSSProperties> &
|
|
24
|
+
Partial<{
|
|
25
|
+
disabled: Partial<CSSProperties>;
|
|
26
|
+
hover: Partial<CSSProperties>;
|
|
27
|
+
focus: Partial<CSSProperties>;
|
|
28
|
+
error: Partial<CSSProperties>;
|
|
29
|
+
}>;
|
|
30
|
+
option: Partial<CSSProperties> &
|
|
31
|
+
Partial<{
|
|
32
|
+
selected: Partial<CSSProperties>;
|
|
33
|
+
disabled: Partial<CSSProperties>;
|
|
34
|
+
focus: Partial<CSSProperties>;
|
|
35
|
+
error: Partial<CSSObjectWithLabel>;
|
|
36
|
+
}>;
|
|
37
|
+
placeholder: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
38
|
+
input: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
39
|
+
singleValue: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
40
|
+
multiValue: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
41
|
+
}>;
|
|
42
|
+
export type DefaultSelectOption = {
|
|
43
|
+
label: string;
|
|
44
|
+
value: string | number;
|
|
45
|
+
disabled?: boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Base option type that all options must extend
|
|
49
|
+
export interface SelectOption extends Record<string, unknown> {
|
|
50
|
+
label: string;
|
|
51
|
+
value: string | number;
|
|
52
|
+
disabled?: boolean;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Type-safe props with conditional types based on IsMulti
|
|
56
|
+
export type SelectProps<
|
|
57
|
+
Option extends SelectOption = DefaultSelectOption,
|
|
58
|
+
IsMulti extends boolean = false,
|
|
59
|
+
Group extends GroupBase<Option> = GroupBase<Option>
|
|
60
|
+
> = Omit<ReactSelectProps<Option, IsMulti, Group>, "styles" | "theme"> & {
|
|
61
|
+
name: string;
|
|
62
|
+
errorMessage?: string;
|
|
63
|
+
label?: string;
|
|
64
|
+
theme?: Partial<SelectTheme>;
|
|
65
|
+
reactSelectTheme?: ReactSelectProps<Option, IsMulti, Group>["theme"];
|
|
66
|
+
};
|
|
13
67
|
|
|
14
|
-
|
|
68
|
+
// Custom styles function with proper typing
|
|
69
|
+
const customStyles = <
|
|
70
|
+
Option extends SelectOption,
|
|
71
|
+
IsMulti extends boolean,
|
|
72
|
+
Group extends GroupBase<Option>
|
|
73
|
+
>(
|
|
15
74
|
error: unknown,
|
|
16
|
-
customTheme
|
|
17
|
-
): StylesConfig<Option,
|
|
18
|
-
control: (provided, state
|
|
19
|
-
const before =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
75
|
+
customTheme?: Partial<SelectTheme>
|
|
76
|
+
): StylesConfig<Option, IsMulti, Group> => ({
|
|
77
|
+
control: (provided, state) => {
|
|
78
|
+
const before =
|
|
79
|
+
"label" in state.selectProps && state.selectProps.label
|
|
80
|
+
? {
|
|
81
|
+
":before": {
|
|
82
|
+
content: `"${state.selectProps.label}"`,
|
|
83
|
+
fontWeight: "600",
|
|
84
|
+
paddingLeft: "1rem"
|
|
85
|
+
}
|
|
25
86
|
}
|
|
26
|
-
|
|
27
|
-
|
|
87
|
+
: null;
|
|
88
|
+
const defaultBorderColor =
|
|
89
|
+
customTheme?.control?.borderColor || colors.border;
|
|
28
90
|
return {
|
|
29
91
|
...provided,
|
|
30
92
|
borderRadius: 0,
|
|
@@ -32,48 +94,71 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
|
|
|
32
94
|
boxShadow: "none",
|
|
33
95
|
background: getCssVar("--background-color"),
|
|
34
96
|
...customTheme?.control,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
97
|
+
cursor: state.isDisabled ? "not-allowed" : "default",
|
|
98
|
+
opacity: state.isDisabled
|
|
99
|
+
? (customTheme?.control?.disabled?.opacity ?? "0.5")
|
|
100
|
+
: (customTheme?.control?.opacity ?? "1"),
|
|
101
|
+
border: state.isDisabled
|
|
102
|
+
? `1px solid ${defaultBorderColor}`
|
|
103
|
+
: state.isFocused
|
|
104
|
+
? (customTheme?.control?.focus?.border ??
|
|
105
|
+
`1px solid ${colors.violet}`)
|
|
106
|
+
: !checkIfValueIsEmpty(error)
|
|
107
|
+
? (customTheme?.control?.error?.border ??
|
|
108
|
+
`1px solid ${colors.orange}`)
|
|
109
|
+
: (customTheme?.control?.border ??
|
|
110
|
+
`1px solid ${defaultBorderColor}`),
|
|
111
|
+
...(state.isDisabled
|
|
112
|
+
? {
|
|
113
|
+
":hover": {
|
|
114
|
+
border: `1px solid ${defaultBorderColor}`
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
: {
|
|
118
|
+
":hover": {
|
|
119
|
+
borderColor: colors.violet,
|
|
120
|
+
borderWidth: "1px",
|
|
121
|
+
...customTheme?.control?.hover
|
|
122
|
+
}
|
|
123
|
+
}),
|
|
46
124
|
...before
|
|
47
125
|
};
|
|
48
126
|
},
|
|
49
|
-
container: (provided, state
|
|
127
|
+
container: (provided, state) => ({
|
|
50
128
|
...provided,
|
|
129
|
+
pointerEvents: "initial",
|
|
51
130
|
zIndex: state.isFocused ? zIndex.Select + 1 : zIndex.Select,
|
|
52
131
|
position: "relative",
|
|
53
132
|
width: "100%"
|
|
54
133
|
}),
|
|
55
|
-
option: (provided, state
|
|
134
|
+
option: (provided, state) => {
|
|
56
135
|
return {
|
|
57
136
|
...provided,
|
|
58
|
-
cursor: state.isDisabled ? "not-allowed" : "
|
|
137
|
+
cursor: state.isDisabled ? "not-allowed" : "default",
|
|
59
138
|
opacity: state.isDisabled
|
|
60
139
|
? (customTheme?.option?.disabled?.opacity ?? "0.5")
|
|
61
140
|
: (customTheme?.option?.opacity ?? "1"),
|
|
62
141
|
background:
|
|
63
|
-
state.
|
|
142
|
+
state.isSelected || state.isFocused
|
|
64
143
|
? (customTheme?.option?.selected?.background ?? colors.greyLight)
|
|
65
144
|
: (customTheme?.option?.background ?? colors.white),
|
|
66
|
-
color:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
: (customTheme?.option?.color ?? colors.black),
|
|
145
|
+
color: state.isSelected
|
|
146
|
+
? (customTheme?.option?.selected?.color ?? colors.violet)
|
|
147
|
+
: (customTheme?.option?.color ?? colors.black),
|
|
70
148
|
...(state.isDisabled && customTheme?.option?.disabled),
|
|
71
|
-
...(
|
|
72
|
-
customTheme?.option?.selected),
|
|
149
|
+
...(state.isSelected && customTheme?.option?.selected),
|
|
73
150
|
...(state.isFocused && customTheme?.option?.focus),
|
|
74
151
|
...(!checkIfValueIsEmpty(error) && customTheme?.option?.error)
|
|
75
152
|
};
|
|
76
153
|
},
|
|
154
|
+
indicatorsContainer: (provided, state) => {
|
|
155
|
+
return {
|
|
156
|
+
...provided,
|
|
157
|
+
...(state.isDisabled && {
|
|
158
|
+
pointerEvents: "none"
|
|
159
|
+
})
|
|
160
|
+
};
|
|
161
|
+
},
|
|
77
162
|
indicatorSeparator: () => ({
|
|
78
163
|
display: "none"
|
|
79
164
|
}),
|
|
@@ -95,26 +180,44 @@ const customStyles = <Option extends Record<string, unknown> = SelectDataProps>(
|
|
|
95
180
|
...customTheme?.singleValue,
|
|
96
181
|
...(!checkIfValueIsEmpty(error) && customTheme?.singleValue?.error)
|
|
97
182
|
};
|
|
183
|
+
},
|
|
184
|
+
multiValue: (provided, state) => {
|
|
185
|
+
return {
|
|
186
|
+
...provided,
|
|
187
|
+
...customTheme?.multiValue,
|
|
188
|
+
...(state.isDisabled && {
|
|
189
|
+
pointerEvents: "none"
|
|
190
|
+
}),
|
|
191
|
+
...(!checkIfValueIsEmpty(error) && customTheme?.multiValue?.error)
|
|
192
|
+
};
|
|
98
193
|
}
|
|
99
194
|
});
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
195
|
+
export type DefaultSelectProps<IsMulti extends boolean = false> = SelectProps<
|
|
196
|
+
DefaultSelectOption,
|
|
197
|
+
IsMulti,
|
|
198
|
+
GroupBase<DefaultSelectOption>
|
|
199
|
+
>;
|
|
200
|
+
export function Select<
|
|
201
|
+
Option extends SelectOption = DefaultSelectOption,
|
|
202
|
+
IsMulti extends boolean = false,
|
|
203
|
+
Group extends GroupBase<Option> = GroupBase<Option>
|
|
104
204
|
>({
|
|
105
205
|
name,
|
|
106
206
|
options,
|
|
107
207
|
placeholder = "Choose...",
|
|
108
208
|
isClearable = false,
|
|
109
209
|
isSearchable = true,
|
|
110
|
-
|
|
210
|
+
isDisabled = false,
|
|
111
211
|
errorMessage,
|
|
112
212
|
onChange,
|
|
213
|
+
onBlur,
|
|
113
214
|
theme,
|
|
215
|
+
reactSelectTheme,
|
|
114
216
|
isMulti,
|
|
115
217
|
...props
|
|
116
|
-
}: SelectProps<
|
|
218
|
+
}: SelectProps<Option, IsMulti, Group>) {
|
|
117
219
|
const [field, meta, helpers] = useField(name);
|
|
220
|
+
|
|
118
221
|
const displayErrorMessage =
|
|
119
222
|
meta.error && meta.touched && !errorMessage
|
|
120
223
|
? meta.error
|
|
@@ -126,43 +229,55 @@ export default function SelectComponent<
|
|
|
126
229
|
typeof displayErrorMessage === "string" && displayErrorMessage !== "";
|
|
127
230
|
|
|
128
231
|
const handleChange = (
|
|
129
|
-
option:
|
|
130
|
-
actionMeta:
|
|
232
|
+
option: IsMulti extends true ? MultiValue<Option> : SingleValue<Option>,
|
|
233
|
+
actionMeta: ActionMeta<Option>
|
|
131
234
|
) => {
|
|
235
|
+
if (isDisabled) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
132
238
|
if (!meta.touched) {
|
|
133
239
|
helpers.setTouched(true);
|
|
134
240
|
}
|
|
135
241
|
helpers.setValue(option);
|
|
136
242
|
onChange?.(option, actionMeta);
|
|
137
243
|
};
|
|
138
|
-
|
|
244
|
+
|
|
245
|
+
const handleBlur = (event: React.FocusEvent<HTMLInputElement>) => {
|
|
139
246
|
if (!meta.touched) {
|
|
140
247
|
helpers.setTouched(true);
|
|
141
248
|
}
|
|
249
|
+
field.onBlur(event);
|
|
250
|
+
onBlur?.(event);
|
|
142
251
|
};
|
|
252
|
+
|
|
143
253
|
const { jsx, selectClassName } = useFixSelectFont({
|
|
144
254
|
selectClassName: "boson-select"
|
|
145
255
|
});
|
|
256
|
+
|
|
146
257
|
return (
|
|
147
258
|
<>
|
|
148
259
|
{jsx}
|
|
149
|
-
<
|
|
150
|
-
styles={customStyles<Option>(
|
|
260
|
+
<ReactSelect<Option, IsMulti, Group>
|
|
261
|
+
styles={customStyles<Option, IsMulti, Group>(
|
|
262
|
+
displayErrorMessage,
|
|
263
|
+
theme
|
|
264
|
+
)}
|
|
151
265
|
{...field}
|
|
152
266
|
{...props}
|
|
267
|
+
theme={reactSelectTheme}
|
|
153
268
|
className={selectClassName}
|
|
154
269
|
isMulti={isMulti}
|
|
155
270
|
placeholder={placeholder}
|
|
156
271
|
options={options}
|
|
157
|
-
value={field.value}
|
|
272
|
+
value={field.value as PropsValue<Option>}
|
|
158
273
|
onChange={handleChange}
|
|
159
274
|
onBlur={handleBlur}
|
|
160
275
|
isSearchable={isSearchable}
|
|
161
276
|
isClearable={isClearable}
|
|
162
|
-
isDisabled={
|
|
277
|
+
isDisabled={isDisabled}
|
|
163
278
|
isOptionDisabled={(option) => !!option.disabled}
|
|
164
279
|
/>
|
|
165
|
-
<Error display={displayError} message={displayErrorMessage} />
|
|
280
|
+
<Error display={displayError} message={displayErrorMessage} />
|
|
166
281
|
</>
|
|
167
282
|
);
|
|
168
283
|
}
|
|
@@ -6,7 +6,7 @@ export { FormField, FormFieldProps } from "./FormField";
|
|
|
6
6
|
export * from "./BaseInput";
|
|
7
7
|
export { default as Input, InputProps } from "./Input";
|
|
8
8
|
export { default as Phone, PhoneProps } from "./Phone";
|
|
9
|
-
export
|
|
9
|
+
export * from "./Select";
|
|
10
10
|
export * from "./CountrySelect";
|
|
11
11
|
export * from "./BaseTagsInput";
|
|
12
12
|
export * from "./BaseTextArea";
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
import {
|
|
3
|
-
ActionMeta,
|
|
4
|
-
CSSObjectWithLabel,
|
|
5
|
-
MultiValue,
|
|
6
|
-
SingleValue
|
|
7
|
-
} from "react-select";
|
|
2
|
+
import { SingleValue } from "react-select";
|
|
8
3
|
import { CSSProperties } from "styled-components";
|
|
9
4
|
import { ImageEditorModalProps } from "./Upload/ImageEditorModal/ImageEditorModal";
|
|
10
5
|
import type {
|
|
@@ -106,8 +101,7 @@ export type SupportedReactSelectProps<
|
|
|
106
101
|
Option extends Record<string, unknown> = SelectDataProps
|
|
107
102
|
> = Pick<
|
|
108
103
|
StateManagerProps<Option, M extends undefined ? false : boolean>,
|
|
109
|
-
| "
|
|
110
|
-
| "formatOptionLabel"
|
|
104
|
+
// | "formatOptionLabel"
|
|
111
105
|
| "menuPlacement"
|
|
112
106
|
| "menuPosition"
|
|
113
107
|
| "menuIsOpen"
|
|
@@ -126,43 +120,9 @@ export type SupportedReactSelectProps<
|
|
|
126
120
|
| "closeMenuOnSelect"
|
|
127
121
|
| "captureMenuScroll"
|
|
128
122
|
| "defaultMenuIsOpen"
|
|
123
|
+
| "placeholder"
|
|
124
|
+
| "hideSelectedOptions"
|
|
129
125
|
>;
|
|
130
|
-
export type SelectProps<
|
|
131
|
-
M extends boolean | undefined = false,
|
|
132
|
-
Option extends Record<string, unknown> = SelectDataProps
|
|
133
|
-
> = BaseProps & {
|
|
134
|
-
isMulti?: M;
|
|
135
|
-
disabled?: boolean;
|
|
136
|
-
isClearable?: boolean;
|
|
137
|
-
isSearchable?: boolean;
|
|
138
|
-
options: Array<Option> | Readonly<Array<Option>>;
|
|
139
|
-
errorMessage?: string;
|
|
140
|
-
onChange?: (
|
|
141
|
-
option: M extends true ? MultiValue<Option> : SingleValue<Option>,
|
|
142
|
-
actionMeta?: ActionMeta<Option>
|
|
143
|
-
) => void;
|
|
144
|
-
label?: string;
|
|
145
|
-
theme?: Partial<{
|
|
146
|
-
control: Partial<CSSProperties> &
|
|
147
|
-
Partial<{
|
|
148
|
-
hover: Partial<CSSProperties>;
|
|
149
|
-
focus: Partial<CSSProperties>;
|
|
150
|
-
error: Partial<CSSProperties>;
|
|
151
|
-
}>;
|
|
152
|
-
option: Partial<CSSProperties> &
|
|
153
|
-
Partial<{
|
|
154
|
-
selected: Partial<CSSProperties>;
|
|
155
|
-
disabled: Partial<CSSProperties>;
|
|
156
|
-
focus: Partial<CSSProperties>;
|
|
157
|
-
error: Partial<CSSObjectWithLabel>;
|
|
158
|
-
}>;
|
|
159
|
-
placeholder: Partial<CSSProperties> &
|
|
160
|
-
Partial<{ error: CSSObjectWithLabel }>;
|
|
161
|
-
input: Partial<CSSProperties> & Partial<{ error: CSSObjectWithLabel }>;
|
|
162
|
-
singleValue: Partial<CSSProperties> &
|
|
163
|
-
Partial<{ error: CSSObjectWithLabel }>;
|
|
164
|
-
}>;
|
|
165
|
-
} & SupportedReactSelectProps<M, Option>;
|
|
166
126
|
|
|
167
127
|
export type UploadProps = BaseProps & {
|
|
168
128
|
accept?: string;
|
|
@@ -354,7 +354,7 @@ export default function VariationSelects({
|
|
|
354
354
|
setLastChangedVariation("color");
|
|
355
355
|
submitForm();
|
|
356
356
|
}}
|
|
357
|
-
|
|
357
|
+
isDisabled={disabled}
|
|
358
358
|
/>
|
|
359
359
|
</>
|
|
360
360
|
)}
|
|
@@ -373,7 +373,7 @@ export default function VariationSelects({
|
|
|
373
373
|
setLastChangedVariation("size");
|
|
374
374
|
submitForm();
|
|
375
375
|
}}
|
|
376
|
-
|
|
376
|
+
isDisabled={disabled}
|
|
377
377
|
/>
|
|
378
378
|
</>
|
|
379
379
|
)}
|
|
@@ -29,7 +29,10 @@ export default {
|
|
|
29
29
|
disable: true // remove name input in controls
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
|
-
|
|
32
|
+
isDisabled: { control: "boolean" },
|
|
33
|
+
isMulti: { control: "boolean" },
|
|
34
|
+
isClearable: { control: "boolean" },
|
|
35
|
+
isSearchable: { control: "boolean" },
|
|
33
36
|
placeholder: { control: "text" }
|
|
34
37
|
},
|
|
35
38
|
decorators: [
|
|
@@ -58,7 +61,7 @@ const BASE_ARGS = {
|
|
|
58
61
|
name: inputName,
|
|
59
62
|
options: [
|
|
60
63
|
{ label: "first option", value: "1" },
|
|
61
|
-
{ label: "second option", value: "2" },
|
|
64
|
+
{ label: "second option", value: "2", disabled: true },
|
|
62
65
|
{ label: "third option", value: "3" }
|
|
63
66
|
]
|
|
64
67
|
} as SelectProps;
|
|
@@ -114,3 +117,7 @@ export const WithError = {
|
|
|
114
117
|
placeholder: "this is a placeholder"
|
|
115
118
|
} satisfies SelectProps
|
|
116
119
|
};
|
|
120
|
+
|
|
121
|
+
export const WithLabel = {
|
|
122
|
+
args: { ...BASE_ARGS, label: "my label" } satisfies SelectProps
|
|
123
|
+
};
|