@firecms/ui 3.0.0-beta.11 → 3.0.0-beta.13
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/components/Avatar.d.ts +1 -0
- package/dist/components/BooleanSwitch.d.ts +1 -1
- package/dist/components/BooleanSwitchWithLabel.d.ts +1 -1
- package/dist/components/Button.d.ts +6 -4
- package/dist/components/CircularProgress.d.ts +1 -1
- package/dist/components/DateTimeField.d.ts +1 -1
- package/dist/components/Dialog.d.ts +2 -1
- package/dist/components/Menu.d.ts +4 -1
- package/dist/components/MultiSelect.d.ts +14 -22
- package/dist/components/Select.d.ts +10 -9
- package/dist/components/Sheet.d.ts +2 -0
- package/dist/components/TextField.d.ts +38 -3
- package/dist/index.es.js +788 -684
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +788 -684
- package/dist/index.umd.js.map +1 -1
- package/package.json +30 -29
- package/src/components/Avatar.tsx +4 -1
- package/src/components/BooleanSwitch.tsx +1 -1
- package/src/components/BooleanSwitchWithLabel.tsx +7 -2
- package/src/components/Button.tsx +16 -17
- package/src/components/Chip.tsx +1 -0
- package/src/components/CircularProgress.tsx +7 -3
- package/src/components/DateTimeField.tsx +29 -23
- package/src/components/Dialog.tsx +3 -1
- package/src/components/DialogContent.tsx +1 -1
- package/src/components/FileUpload.tsx +2 -1
- package/src/components/Menu.tsx +13 -4
- package/src/components/Menubar.tsx +1 -1
- package/src/components/MultiSelect.tsx +54 -51
- package/src/components/SearchBar.tsx +1 -1
- package/src/components/Select.tsx +70 -55
- package/src/components/Sheet.tsx +9 -1
- package/src/components/Tabs.tsx +3 -1
- package/src/components/TextField.tsx +190 -153
- package/src/components/TextareaAutosize.tsx +2 -2
- package/src/components/Tooltip.tsx +0 -1
|
@@ -18,41 +18,33 @@ import {
|
|
|
18
18
|
} from "../styles";
|
|
19
19
|
import { useInjectStyles } from "../hooks";
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
export type MultiSelectValue = string | number | boolean;
|
|
22
|
+
|
|
23
|
+
// Make the context properly generic
|
|
24
|
+
interface MultiSelectContextProps<T extends MultiSelectValue = string> {
|
|
25
|
+
fieldValue?: T[];
|
|
26
|
+
onItemClick: (v: T) => void;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
// Create a proper generic context
|
|
30
|
+
export const MultiSelectContext = React.createContext<MultiSelectContextProps<any>>({} as any);
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
33
|
* Props for MultiSelect component
|
|
30
34
|
*/
|
|
31
|
-
interface MultiSelectProps {
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* The modality of the popover. When set to true, interaction with outside elements
|
|
35
|
-
* will be disabled and only popover content will be visible to screen readers.
|
|
36
|
-
* Optional, defaults to false.
|
|
37
|
-
*/
|
|
35
|
+
interface MultiSelectProps<T extends MultiSelectValue = string> {
|
|
38
36
|
modalPopover?: boolean;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Additional class names to apply custom styles to the multi-select component.
|
|
42
|
-
* Optional, can be used to add custom styles.
|
|
43
|
-
*/
|
|
44
37
|
className?: string;
|
|
45
|
-
|
|
46
38
|
open?: boolean,
|
|
47
39
|
name?: string,
|
|
48
40
|
id?: string,
|
|
49
41
|
onOpenChange?: (open: boolean) => void,
|
|
50
|
-
value?:
|
|
42
|
+
value?: T[],
|
|
51
43
|
inputClassName?: string,
|
|
52
44
|
onChange?: React.EventHandler<ChangeEvent<HTMLSelectElement>>,
|
|
53
|
-
onValueChange?: (updatedValue:
|
|
45
|
+
onValueChange?: (updatedValue: T[]) => void,
|
|
54
46
|
placeholder?: React.ReactNode,
|
|
55
|
-
size?: "small" | "medium",
|
|
47
|
+
size?: "smallest" | "small" | "medium" | "large",
|
|
56
48
|
useChips?: boolean,
|
|
57
49
|
label?: React.ReactNode | string,
|
|
58
50
|
disabled?: boolean,
|
|
@@ -66,9 +58,10 @@ interface MultiSelectProps {
|
|
|
66
58
|
padding?: boolean,
|
|
67
59
|
invisible?: boolean,
|
|
68
60
|
children: React.ReactNode;
|
|
69
|
-
renderValues?: (values:
|
|
61
|
+
renderValues?: (values: T[]) => React.ReactNode;
|
|
70
62
|
}
|
|
71
63
|
|
|
64
|
+
// Use generic type for the forwarded ref
|
|
72
65
|
export const MultiSelect = React.forwardRef<
|
|
73
66
|
HTMLButtonElement,
|
|
74
67
|
MultiSelectProps
|
|
@@ -76,7 +69,7 @@ export const MultiSelect = React.forwardRef<
|
|
|
76
69
|
(
|
|
77
70
|
{
|
|
78
71
|
value,
|
|
79
|
-
size,
|
|
72
|
+
size = "large",
|
|
80
73
|
label,
|
|
81
74
|
error,
|
|
82
75
|
onValueChange,
|
|
@@ -95,8 +88,9 @@ export const MultiSelect = React.forwardRef<
|
|
|
95
88
|
},
|
|
96
89
|
ref
|
|
97
90
|
) => {
|
|
91
|
+
// Properly type the state variables to match the generic props
|
|
98
92
|
const [isPopoverOpen, setIsPopoverOpen] = React.useState(open ?? false);
|
|
99
|
-
const [selectedValues, setSelectedValues] = React.useState<
|
|
93
|
+
const [selectedValues, setSelectedValues] = React.useState<any[]>(value ?? []);
|
|
100
94
|
|
|
101
95
|
const onPopoverOpenChange = (open: boolean) => {
|
|
102
96
|
setIsPopoverOpen(open);
|
|
@@ -115,24 +109,24 @@ export const MultiSelect = React.forwardRef<
|
|
|
115
109
|
return child.props.value;
|
|
116
110
|
}
|
|
117
111
|
return null;
|
|
118
|
-
}).filter(Boolean) as
|
|
112
|
+
}).filter(Boolean) as any[]
|
|
119
113
|
: [];
|
|
120
114
|
|
|
121
115
|
React.useEffect(() => {
|
|
122
116
|
setSelectedValues(value ?? []);
|
|
123
117
|
}, [value]);
|
|
124
118
|
|
|
125
|
-
function onItemClick(newValue:
|
|
126
|
-
let newSelectedValues:
|
|
127
|
-
if (selectedValues.
|
|
128
|
-
newSelectedValues = selectedValues.filter(
|
|
119
|
+
function onItemClick(newValue: any) {
|
|
120
|
+
let newSelectedValues: any[];
|
|
121
|
+
if (selectedValues.some(v => String(v) === String(newValue))) {
|
|
122
|
+
newSelectedValues = selectedValues.filter(v => String(v) !== String(newValue));
|
|
129
123
|
} else {
|
|
130
124
|
newSelectedValues = [...selectedValues, newValue];
|
|
131
125
|
}
|
|
132
126
|
updateValues(newSelectedValues);
|
|
133
127
|
}
|
|
134
128
|
|
|
135
|
-
function updateValues(values:
|
|
129
|
+
function updateValues(values: any[]) {
|
|
136
130
|
setSelectedValues(values);
|
|
137
131
|
onValueChange?.(values);
|
|
138
132
|
}
|
|
@@ -149,9 +143,9 @@ export const MultiSelect = React.forwardRef<
|
|
|
149
143
|
}
|
|
150
144
|
};
|
|
151
145
|
|
|
152
|
-
const toggleOption = (value:
|
|
153
|
-
const newSelectedValues = selectedValues.
|
|
154
|
-
? selectedValues.filter(
|
|
146
|
+
const toggleOption = (value: any) => {
|
|
147
|
+
const newSelectedValues = selectedValues.some(v => String(v) === String(value))
|
|
148
|
+
? selectedValues.filter(v => String(v) !== String(value))
|
|
155
149
|
: [...selectedValues, value];
|
|
156
150
|
updateValues(newSelectedValues);
|
|
157
151
|
};
|
|
@@ -199,9 +193,20 @@ export const MultiSelect = React.forwardRef<
|
|
|
199
193
|
ref={ref}
|
|
200
194
|
onClick={handleTogglePopover}
|
|
201
195
|
className={cls(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
196
|
+
{
|
|
197
|
+
"min-h-[28px]": size === "smallest",
|
|
198
|
+
"min-h-[32px]": size === "small",
|
|
199
|
+
"min-h-[42px]": size === "medium",
|
|
200
|
+
"min-h-[64px]": size === "large",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"py-1": size === "small" || size === "smallest",
|
|
204
|
+
"py-2": size === "medium" || size === "large",
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"px-2": size === "small" || size === "smallest",
|
|
208
|
+
"px-4": size === "medium" || size === "large",
|
|
209
|
+
},
|
|
205
210
|
"select-none rounded-md text-sm",
|
|
206
211
|
invisible ? fieldBackgroundInvisibleMixin : fieldBackgroundMixin,
|
|
207
212
|
disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
|
|
@@ -222,14 +227,14 @@ export const MultiSelect = React.forwardRef<
|
|
|
222
227
|
}
|
|
223
228
|
}).filter(Boolean);
|
|
224
229
|
|
|
225
|
-
const option = childrenProps.find((o) => o.value === value);
|
|
230
|
+
const option = childrenProps.find((o) => String(o.value) === String(value));
|
|
226
231
|
if (!useChips) {
|
|
227
232
|
return option?.children;
|
|
228
233
|
}
|
|
229
234
|
return (
|
|
230
235
|
<Chip
|
|
231
236
|
size={"medium"}
|
|
232
|
-
key={value}
|
|
237
|
+
key={String(value)}
|
|
233
238
|
className={cls("flex flex-row items-center p-1")}
|
|
234
239
|
>
|
|
235
240
|
{option?.children}
|
|
@@ -255,7 +260,7 @@ export const MultiSelect = React.forwardRef<
|
|
|
255
260
|
/>}
|
|
256
261
|
<div className={cls("px-2 h-full flex items-center")}>
|
|
257
262
|
<KeyboardArrowDownIcon size={"small"}
|
|
258
|
-
|
|
263
|
+
className={cls("transition", isPopoverOpen ? "rotate-180" : "")}/>
|
|
259
264
|
</div>
|
|
260
265
|
</div>
|
|
261
266
|
</div>
|
|
@@ -266,7 +271,7 @@ export const MultiSelect = React.forwardRef<
|
|
|
266
271
|
</span>
|
|
267
272
|
<div className={cls("px-2 h-full flex items-center")}>
|
|
268
273
|
<KeyboardArrowDownIcon size={"small"}
|
|
269
|
-
|
|
274
|
+
className={cls("transition", isPopoverOpen ? "rotate-180" : "")}/>
|
|
270
275
|
</div>
|
|
271
276
|
</div>
|
|
272
277
|
)}
|
|
@@ -319,7 +324,6 @@ export const MultiSelect = React.forwardRef<
|
|
|
319
324
|
</CommandPrimitive.Item>}
|
|
320
325
|
{children}
|
|
321
326
|
</CommandPrimitive.Group>
|
|
322
|
-
|
|
323
327
|
</CommandPrimitive.List>
|
|
324
328
|
</CommandPrimitive>
|
|
325
329
|
</PopoverPrimitive.Content>
|
|
@@ -331,18 +335,17 @@ export const MultiSelect = React.forwardRef<
|
|
|
331
335
|
|
|
332
336
|
MultiSelect.displayName = "MultiSelect";
|
|
333
337
|
|
|
334
|
-
export interface MultiSelectItemProps {
|
|
335
|
-
value:
|
|
338
|
+
export interface MultiSelectItemProps<T extends MultiSelectValue = string> {
|
|
339
|
+
value: T;
|
|
336
340
|
children?: React.ReactNode,
|
|
337
341
|
className?: string;
|
|
338
342
|
}
|
|
339
343
|
|
|
340
|
-
export function MultiSelectItem({
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
344
|
+
export function MultiSelectItem<T extends MultiSelectValue = string>({
|
|
345
|
+
children,
|
|
346
|
+
value,
|
|
347
|
+
className
|
|
348
|
+
}: MultiSelectItemProps<T>) {
|
|
346
349
|
const context = React.useContext(MultiSelectContext);
|
|
347
350
|
if (!context) throw new Error("MultiSelectItem must be used inside a MultiSelect");
|
|
348
351
|
const {
|
|
@@ -350,9 +353,9 @@ export function MultiSelectItem({
|
|
|
350
353
|
onItemClick
|
|
351
354
|
} = context;
|
|
352
355
|
|
|
353
|
-
const isSelected = (fieldValue ?? []).
|
|
356
|
+
const isSelected = (fieldValue ?? []).some(v => String(v) === String(value));
|
|
357
|
+
|
|
354
358
|
return <CommandPrimitive.Item
|
|
355
|
-
// value={value}
|
|
356
359
|
onMouseDown={(e) => {
|
|
357
360
|
e.preventDefault();
|
|
358
361
|
e.stopPropagation();
|
|
@@ -375,9 +378,9 @@ export function MultiSelectItem({
|
|
|
375
378
|
<InnerCheckBox checked={isSelected}/>
|
|
376
379
|
{children}
|
|
377
380
|
</CommandPrimitive.Item>;
|
|
378
|
-
|
|
379
381
|
}
|
|
380
382
|
|
|
383
|
+
|
|
381
384
|
function InnerCheckBox({ checked }: { checked: boolean }) {
|
|
382
385
|
return <div className={cls(
|
|
383
386
|
"p-2",
|
|
@@ -69,7 +69,7 @@ export function SearchBar({
|
|
|
69
69
|
className)}>
|
|
70
70
|
<div
|
|
71
71
|
className="absolute p-0 px-4 h-full pointer-events-none flex items-center justify-center top-0">
|
|
72
|
-
{loading ? <CircularProgress size={"
|
|
72
|
+
{loading ? <CircularProgress size={"smallest"}/> : <SearchIcon className={"text-text-disabled dark:text-text-disabled-dark"}/>}
|
|
73
73
|
</div>
|
|
74
74
|
<input
|
|
75
75
|
value={searchText ?? ""}
|
|
@@ -13,20 +13,22 @@ import { CheckIcon, KeyboardArrowDownIcon } from "../icons";
|
|
|
13
13
|
import { cls } from "../util";
|
|
14
14
|
import { SelectInputLabel } from "./common/SelectInputLabel";
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type SelectValue = string | number | boolean;
|
|
17
|
+
|
|
18
|
+
export type SelectProps<T extends SelectValue = string> = {
|
|
17
19
|
open?: boolean,
|
|
18
20
|
name?: string,
|
|
19
21
|
fullWidth?: boolean,
|
|
20
22
|
id?: string,
|
|
21
23
|
onOpenChange?: (open: boolean) => void,
|
|
22
|
-
value?:
|
|
24
|
+
value?: T,
|
|
23
25
|
className?: string,
|
|
24
26
|
inputClassName?: string,
|
|
25
27
|
onChange?: React.EventHandler<ChangeEvent<HTMLSelectElement>>,
|
|
26
|
-
onValueChange?: (updatedValue:
|
|
28
|
+
onValueChange?: (updatedValue: T) => void,
|
|
27
29
|
placeholder?: React.ReactNode,
|
|
28
|
-
renderValue?: (value:
|
|
29
|
-
size?: "small" | "medium" | "large",
|
|
30
|
+
renderValue?: (value: T) => React.ReactNode,
|
|
31
|
+
size?: "smallest" | "small" | "medium" | "large",
|
|
30
32
|
label?: React.ReactNode | string,
|
|
31
33
|
disabled?: boolean,
|
|
32
34
|
error?: boolean,
|
|
@@ -39,30 +41,30 @@ export type SelectProps = {
|
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
44
|
+
inputRef,
|
|
45
|
+
open,
|
|
46
|
+
name,
|
|
47
|
+
fullWidth = false,
|
|
48
|
+
id,
|
|
49
|
+
onOpenChange,
|
|
50
|
+
value,
|
|
51
|
+
onChange,
|
|
52
|
+
onValueChange,
|
|
53
|
+
className,
|
|
54
|
+
inputClassName,
|
|
55
|
+
placeholder,
|
|
56
|
+
renderValue,
|
|
57
|
+
label,
|
|
58
|
+
size = "large",
|
|
59
|
+
error,
|
|
60
|
+
disabled,
|
|
61
|
+
padding = true,
|
|
62
|
+
position = "item-aligned",
|
|
63
|
+
endAdornment,
|
|
64
|
+
invisible,
|
|
65
|
+
children,
|
|
66
|
+
...props
|
|
67
|
+
}, ref) => {
|
|
66
68
|
|
|
67
69
|
const [openInternal, setOpenInternal] = useState(open ?? false);
|
|
68
70
|
|
|
@@ -71,24 +73,32 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
71
73
|
}, [open]);
|
|
72
74
|
|
|
73
75
|
const onValueChangeInternal = useCallback((newValue: string) => {
|
|
74
|
-
|
|
76
|
+
// Convert string value to appropriate type
|
|
77
|
+
let typedValue: SelectValue = newValue;
|
|
78
|
+
if (newValue === "true") typedValue = true;
|
|
79
|
+
else if (newValue === "false") typedValue = false;
|
|
80
|
+
else if (!isNaN(Number(newValue)) && newValue.trim() !== '') typedValue = Number(newValue);
|
|
81
|
+
|
|
82
|
+
onValueChange?.(typedValue as any);
|
|
75
83
|
if (onChange) {
|
|
76
84
|
const event = {
|
|
77
85
|
target: {
|
|
78
86
|
name,
|
|
79
|
-
value:
|
|
87
|
+
value: typedValue
|
|
80
88
|
}
|
|
81
|
-
} as ChangeEvent<HTMLSelectElement>;
|
|
89
|
+
} as unknown as ChangeEvent<HTMLSelectElement>;
|
|
82
90
|
onChange(event);
|
|
83
91
|
}
|
|
84
|
-
}, [onChange,
|
|
92
|
+
}, [onChange, onValueChange, name]);
|
|
85
93
|
|
|
86
94
|
const hasValue = Array.isArray(value) ? value.length > 0 : (value != null && value !== "" && value !== undefined);
|
|
95
|
+
// Convert non-string values to strings for Radix UI
|
|
96
|
+
const stringValue = value !== undefined ? String(value) : undefined;
|
|
87
97
|
|
|
88
98
|
return (
|
|
89
99
|
<SelectPrimitive.Root
|
|
90
100
|
name={name}
|
|
91
|
-
value={
|
|
101
|
+
value={stringValue}
|
|
92
102
|
open={openInternal}
|
|
93
103
|
disabled={disabled}
|
|
94
104
|
onValueChange={onValueChangeInternal}
|
|
@@ -105,7 +115,8 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
105
115
|
"relative flex items-center",
|
|
106
116
|
className,
|
|
107
117
|
{
|
|
108
|
-
"min-h-[28px]": size === "
|
|
118
|
+
"min-h-[28px]": size === "smallest",
|
|
119
|
+
"min-h-[32px]": size === "small",
|
|
109
120
|
"min-h-[42px]": size === "medium",
|
|
110
121
|
"min-h-[64px]": size === "large",
|
|
111
122
|
"w-fit": !fullWidth,
|
|
@@ -122,7 +133,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
122
133
|
padding ? {
|
|
123
134
|
"px-4": size === "large",
|
|
124
135
|
"px-3": size === "medium",
|
|
125
|
-
"px-2": size === "small"
|
|
136
|
+
"px-2": size === "small" || size === "smallest",
|
|
126
137
|
} : "",
|
|
127
138
|
"outline-none focus:outline-none",
|
|
128
139
|
"select-none rounded-md text-sm",
|
|
@@ -131,7 +142,8 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
131
142
|
disabled ? "text-surface-accent-600 dark:text-surface-accent-400" : "text-surface-accent-800 dark:text-white",
|
|
132
143
|
"relative flex flex-row items-center",
|
|
133
144
|
{
|
|
134
|
-
"min-h-[28px]": size === "
|
|
145
|
+
"min-h-[28px]": size === "smallest",
|
|
146
|
+
"min-h-[32px]": size === "small",
|
|
135
147
|
"min-h-[42px]": size === "medium",
|
|
136
148
|
"min-h-[64px]": size === "large",
|
|
137
149
|
"w-full": fullWidth,
|
|
@@ -145,7 +157,8 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
145
157
|
"flex-grow max-w-full flex flex-row gap-2 items-center",
|
|
146
158
|
"overflow-visible",
|
|
147
159
|
{
|
|
148
|
-
"min-h-[28px]": size === "
|
|
160
|
+
"min-h-[28px]": size === "smallest",
|
|
161
|
+
"min-h-[32px]": size === "small",
|
|
149
162
|
"min-h-[42px]": size === "medium",
|
|
150
163
|
"min-h-[64px]": size === "large"
|
|
151
164
|
}
|
|
@@ -157,10 +170,9 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
157
170
|
}}
|
|
158
171
|
placeholder={placeholder}
|
|
159
172
|
className={"w-full"}>
|
|
160
|
-
{hasValue && value && renderValue ? renderValue(value) : placeholder}
|
|
173
|
+
{hasValue && value !== undefined && renderValue ? renderValue(value) : placeholder}
|
|
161
174
|
{/*{hasValue && !renderValue && value}*/}
|
|
162
175
|
{hasValue && !renderValue && (() => {
|
|
163
|
-
|
|
164
176
|
// @ts-ignore
|
|
165
177
|
const childrenProps: SelectItemProps[] = Children.map(children, (child) => {
|
|
166
178
|
if (React.isValidElement(child)) {
|
|
@@ -168,7 +180,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
168
180
|
}
|
|
169
181
|
}).filter(Boolean);
|
|
170
182
|
|
|
171
|
-
const option = childrenProps.find((o) => o.value === value);
|
|
183
|
+
const option = childrenProps.find((o) => String(o.value) === String(value));
|
|
172
184
|
return option?.children;
|
|
173
185
|
})()}
|
|
174
186
|
|
|
@@ -187,10 +199,10 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
187
199
|
)}
|
|
188
200
|
<SelectPrimitive.Icon asChild>
|
|
189
201
|
<KeyboardArrowDownIcon size={"medium"}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
className={cls("transition", open ? "rotate-180" : "", {
|
|
203
|
+
"px-2": size === "large",
|
|
204
|
+
"px-1": size === "medium" || size === "small",
|
|
205
|
+
})}/>
|
|
194
206
|
</SelectPrimitive.Icon>
|
|
195
207
|
</div>
|
|
196
208
|
</SelectPrimitive.Trigger>
|
|
@@ -211,22 +223,25 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>(({
|
|
|
211
223
|
|
|
212
224
|
Select.displayName = "Select";
|
|
213
225
|
|
|
214
|
-
export type SelectItemProps = {
|
|
215
|
-
value:
|
|
226
|
+
export type SelectItemProps<T extends SelectValue = string> = {
|
|
227
|
+
value: T,
|
|
216
228
|
children?: React.ReactNode,
|
|
217
229
|
disabled?: boolean,
|
|
218
230
|
className?: string,
|
|
219
231
|
};
|
|
220
232
|
|
|
221
|
-
export function SelectItem({
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
233
|
+
export function SelectItem<T extends SelectValue = string>({
|
|
234
|
+
value,
|
|
235
|
+
children,
|
|
236
|
+
disabled,
|
|
237
|
+
className
|
|
238
|
+
}: SelectItemProps<T>) {
|
|
239
|
+
// Convert value to string for Radix UI
|
|
240
|
+
const stringValue = String(value);
|
|
241
|
+
|
|
227
242
|
return <SelectPrimitive.Item
|
|
228
|
-
key={
|
|
229
|
-
value={
|
|
243
|
+
key={stringValue}
|
|
244
|
+
value={stringValue}
|
|
230
245
|
disabled={disabled}
|
|
231
246
|
className={cls(
|
|
232
247
|
"w-full",
|
package/src/components/Sheet.tsx
CHANGED
|
@@ -15,7 +15,9 @@ interface SheetProps {
|
|
|
15
15
|
transparent?: boolean;
|
|
16
16
|
onOpenChange?: (open: boolean) => void;
|
|
17
17
|
className?: string;
|
|
18
|
+
style?: React.CSSProperties;
|
|
18
19
|
overlayClassName?: string;
|
|
20
|
+
overlayStyle?: React.CSSProperties;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export const Sheet: React.FC<SheetProps> = ({
|
|
@@ -28,7 +30,9 @@ export const Sheet: React.FC<SheetProps> = ({
|
|
|
28
30
|
onOpenChange,
|
|
29
31
|
transparent,
|
|
30
32
|
className,
|
|
33
|
+
style,
|
|
31
34
|
overlayClassName,
|
|
35
|
+
overlayStyle,
|
|
32
36
|
...props
|
|
33
37
|
}) => {
|
|
34
38
|
const [displayed, setDisplayed] = useState(false);
|
|
@@ -64,6 +68,7 @@ export const Sheet: React.FC<SheetProps> = ({
|
|
|
64
68
|
</DialogPrimitive.Title>
|
|
65
69
|
{includeBackgroundOverlay && <DialogPrimitive.Overlay
|
|
66
70
|
className={cls(
|
|
71
|
+
"outline-none",
|
|
67
72
|
"fixed inset-0 transition-opacity z-20 ease-in-out duration-100 backdrop-blur-sm",
|
|
68
73
|
"bg-black bg-opacity-50",
|
|
69
74
|
"dark:bg-surface-900 dark:bg-opacity-60",
|
|
@@ -71,13 +76,15 @@ export const Sheet: React.FC<SheetProps> = ({
|
|
|
71
76
|
overlayClassName
|
|
72
77
|
)}
|
|
73
78
|
style={{
|
|
74
|
-
pointerEvents: displayed ? "auto" : "none"
|
|
79
|
+
pointerEvents: displayed ? "auto" : "none",
|
|
80
|
+
...overlayStyle
|
|
75
81
|
}}
|
|
76
82
|
/>}
|
|
77
83
|
<DialogPrimitive.Content
|
|
78
84
|
{...props}
|
|
79
85
|
onFocusCapture={(event) => event.preventDefault()}
|
|
80
86
|
className={cls(
|
|
87
|
+
"outline-none",
|
|
81
88
|
borderClass[side],
|
|
82
89
|
defaultBorderMixin,
|
|
83
90
|
"transform-gpu",
|
|
@@ -93,6 +100,7 @@ export const Sheet: React.FC<SheetProps> = ({
|
|
|
93
100
|
!displayed || !open ? transformValue[side] : "",
|
|
94
101
|
className
|
|
95
102
|
)}
|
|
103
|
+
style={style}
|
|
96
104
|
>
|
|
97
105
|
{children}
|
|
98
106
|
</DialogPrimitive.Content>
|
package/src/components/Tabs.tsx
CHANGED
|
@@ -20,6 +20,7 @@ export function Tabs({
|
|
|
20
20
|
|
|
21
21
|
return <TabsPrimitive.Root value={value} onValueChange={onValueChange} className={className}>
|
|
22
22
|
<TabsPrimitive.List className={cls(
|
|
23
|
+
"w-max",
|
|
23
24
|
"flex text-sm font-medium text-center text-surface-accent-800 dark:text-white max-w-full overflow-auto no-scrollbar items-end",
|
|
24
25
|
innerClassName)
|
|
25
26
|
}>
|
|
@@ -54,7 +55,8 @@ export function Tab({
|
|
|
54
55
|
"data-[state=active]:text-surface-accent-900 data-[state=active]:dark:text-white",
|
|
55
56
|
"hover:text-surface-accent-800 dark:hover:text-surface-accent-200"),
|
|
56
57
|
className)}>
|
|
57
|
-
<div className={cls("
|
|
58
|
+
<div className={cls("line-clamp-1",
|
|
59
|
+
"uppercase inline-block p-2 px-4 rounded",
|
|
58
60
|
"hover:bg-surface-accent-200 hover:bg-opacity-75 dark:hover:bg-surface-accent-800",
|
|
59
61
|
innerClassName)}>
|
|
60
62
|
{children}
|