@noya-app/noya-designsystem 0.1.42 → 0.1.43
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-build.log +9 -9
- package/CHANGELOG.md +6 -0
- package/dist/index.css +1 -1
- package/dist/index.d.mts +61 -36
- package/dist/index.d.ts +61 -36
- package/dist/index.js +209 -138
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +217 -140
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Combobox.tsx +145 -51
- package/src/components/TextArea.tsx +61 -24
- package/src/components/Toolbar.tsx +4 -9
- package/src/components/WorkspaceLayout.tsx +145 -152
package/package.json
CHANGED
|
@@ -25,17 +25,12 @@ import { InputField, InputFieldSize } from "./InputField";
|
|
|
25
25
|
import { ListView } from "./ListView";
|
|
26
26
|
import { Small } from "./Text";
|
|
27
27
|
|
|
28
|
-
export type
|
|
28
|
+
export type BaseComboboxProps = {
|
|
29
29
|
id?: string;
|
|
30
30
|
loading?: boolean;
|
|
31
|
-
initialValue?: string;
|
|
32
31
|
placeholder?: string;
|
|
33
32
|
items: ComboboxItem[];
|
|
34
|
-
onChange?: (value: string) => void;
|
|
35
|
-
onHoverItem?: (item: ComboboxOption | undefined) => void;
|
|
36
|
-
onSelectItem?: (item: ComboboxOption) => void;
|
|
37
33
|
onFocus?: (event: React.FocusEvent<HTMLInputElement>) => void;
|
|
38
|
-
onBlur?: (didSubmit: boolean, value: string) => void;
|
|
39
34
|
onDeleteWhenEmpty?: () => void;
|
|
40
35
|
size?: InputFieldSize;
|
|
41
36
|
style?: React.CSSProperties;
|
|
@@ -43,15 +38,40 @@ export type ComboboxProps = {
|
|
|
43
38
|
label?: React.ReactNode;
|
|
44
39
|
children?: React.ReactNode;
|
|
45
40
|
hideMenuWhenEmptyValue?: boolean;
|
|
46
|
-
allowArbitraryValues?: boolean;
|
|
47
41
|
readOnly?: boolean;
|
|
48
42
|
tabBehavior?: "autocomplete" | "select";
|
|
49
43
|
openMenuBehavior?: "showAllItems" | "showFilteredItems";
|
|
50
44
|
};
|
|
51
45
|
|
|
46
|
+
export type StringModeOnlyProps = {
|
|
47
|
+
mode: "string";
|
|
48
|
+
initialValue?: string;
|
|
49
|
+
onChange?: (value: string) => void;
|
|
50
|
+
onSelectItem?: (value: string) => void;
|
|
51
|
+
onBlur?: (didSubmit: boolean, value: string) => void;
|
|
52
|
+
onHoverItem?: (value: string | undefined) => void;
|
|
53
|
+
allowArbitraryValues?: boolean;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type StringModeProps = BaseComboboxProps & StringModeOnlyProps;
|
|
57
|
+
|
|
58
|
+
export type OptionModeOnlyProps = {
|
|
59
|
+
mode?: "option";
|
|
60
|
+
initialValue?: ComboboxOption;
|
|
61
|
+
onChange?: (value: ComboboxOption) => void;
|
|
62
|
+
onSelectItem?: (value: ComboboxOption) => void;
|
|
63
|
+
onBlur?: (didSubmit: boolean, value: ComboboxOption) => void;
|
|
64
|
+
onHoverItem?: (value: ComboboxOption | undefined) => void;
|
|
65
|
+
allowArbitraryValues?: false;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export type OptionModeProps = BaseComboboxProps & OptionModeOnlyProps;
|
|
69
|
+
|
|
70
|
+
export type ComboboxProps = StringModeProps | OptionModeProps;
|
|
71
|
+
|
|
52
72
|
export interface ComboboxRef {
|
|
53
73
|
focus(): void;
|
|
54
|
-
setValue(value: string): void;
|
|
74
|
+
setValue(value: string | ComboboxOption): void;
|
|
55
75
|
selectAllInputText(): void;
|
|
56
76
|
}
|
|
57
77
|
|
|
@@ -60,31 +80,68 @@ export const Combobox = memo(
|
|
|
60
80
|
{
|
|
61
81
|
id,
|
|
62
82
|
loading,
|
|
63
|
-
initialValue = "",
|
|
64
83
|
placeholder,
|
|
65
84
|
items,
|
|
66
85
|
size,
|
|
67
|
-
onChange,
|
|
68
|
-
onSelectItem,
|
|
69
|
-
onHoverItem,
|
|
70
|
-
onFocus,
|
|
71
|
-
onBlur,
|
|
72
|
-
onDeleteWhenEmpty,
|
|
73
86
|
style,
|
|
74
87
|
className,
|
|
75
88
|
label,
|
|
76
89
|
children,
|
|
77
90
|
hideMenuWhenEmptyValue = false,
|
|
78
|
-
allowArbitraryValues = false,
|
|
79
91
|
readOnly = false,
|
|
80
92
|
tabBehavior = "select",
|
|
81
93
|
openMenuBehavior = "showFilteredItems",
|
|
94
|
+
onFocus,
|
|
95
|
+
onDeleteWhenEmpty,
|
|
96
|
+
...rest
|
|
82
97
|
}: ComboboxProps,
|
|
83
98
|
forwardedRef: ForwardedRef<ComboboxRef>
|
|
84
99
|
) {
|
|
100
|
+
// We make a separate props object for the mode-specific props for memoizing
|
|
101
|
+
// since we put the props object into hook deps
|
|
102
|
+
const props = useMemo((): StringModeOnlyProps | OptionModeOnlyProps => {
|
|
103
|
+
if (rest.mode === "string") {
|
|
104
|
+
return {
|
|
105
|
+
mode: rest.mode,
|
|
106
|
+
initialValue: rest.initialValue,
|
|
107
|
+
onChange: rest.onChange,
|
|
108
|
+
onSelectItem: rest.onSelectItem,
|
|
109
|
+
onHoverItem: rest.onHoverItem,
|
|
110
|
+
onBlur: rest.onBlur,
|
|
111
|
+
allowArbitraryValues: rest.allowArbitraryValues,
|
|
112
|
+
} satisfies StringModeOnlyProps;
|
|
113
|
+
} else {
|
|
114
|
+
return {
|
|
115
|
+
mode: rest.mode,
|
|
116
|
+
initialValue: rest.initialValue,
|
|
117
|
+
onChange: rest.onChange,
|
|
118
|
+
onSelectItem: rest.onSelectItem,
|
|
119
|
+
onHoverItem: rest.onHoverItem,
|
|
120
|
+
onBlur: rest.onBlur,
|
|
121
|
+
} satisfies OptionModeOnlyProps;
|
|
122
|
+
}
|
|
123
|
+
}, [
|
|
124
|
+
rest.mode,
|
|
125
|
+
rest.initialValue,
|
|
126
|
+
rest.onChange,
|
|
127
|
+
rest.onSelectItem,
|
|
128
|
+
rest.onHoverItem,
|
|
129
|
+
rest.onBlur,
|
|
130
|
+
rest.allowArbitraryValues,
|
|
131
|
+
]);
|
|
132
|
+
|
|
85
133
|
const ref = useRef<HTMLInputElement>(null);
|
|
134
|
+
const initialValueString =
|
|
135
|
+
typeof props.initialValue === "string"
|
|
136
|
+
? props.initialValue
|
|
137
|
+
: props.initialValue?.name ?? "";
|
|
86
138
|
const [comboboxState] = useState(
|
|
87
|
-
() =>
|
|
139
|
+
() =>
|
|
140
|
+
new ComboboxState(
|
|
141
|
+
items,
|
|
142
|
+
initialValueString,
|
|
143
|
+
props.mode === "string" && (props.allowArbitraryValues ?? false)
|
|
144
|
+
)
|
|
88
145
|
);
|
|
89
146
|
const state = useComboboxState(comboboxState);
|
|
90
147
|
const [isFocused, setIsFocused] = useState(false);
|
|
@@ -98,11 +155,8 @@ export const Combobox = memo(
|
|
|
98
155
|
|
|
99
156
|
const { filter, selectedIndex, filteredItems } = state;
|
|
100
157
|
|
|
101
|
-
const shouldShowMenu =
|
|
102
|
-
|
|
103
|
-
if (hideMenuWhenEmptyValue && filter === "") return false;
|
|
104
|
-
return true;
|
|
105
|
-
}, [hideMenuWhenEmptyValue, filter, isFocused]);
|
|
158
|
+
const shouldShowMenu =
|
|
159
|
+
isFocused && !(hideMenuWhenEmptyValue && filter === "");
|
|
106
160
|
|
|
107
161
|
useEffect(() => {
|
|
108
162
|
if (listRef.current) {
|
|
@@ -112,16 +166,29 @@ export const Combobox = memo(
|
|
|
112
166
|
|
|
113
167
|
const handleBlur = useCallback(() => {
|
|
114
168
|
ref.current?.blur();
|
|
115
|
-
comboboxState.reset(
|
|
116
|
-
|
|
169
|
+
comboboxState.reset(initialValueString);
|
|
170
|
+
if (props.mode === "string") {
|
|
171
|
+
props.onBlur?.(
|
|
172
|
+
state.filter === state.lastSubmittedValue.filter,
|
|
173
|
+
filter
|
|
174
|
+
);
|
|
175
|
+
} else {
|
|
176
|
+
const selectedItem = comboboxState.getSelectedItem();
|
|
177
|
+
if (selectedItem && selectedItem.type !== "sectionHeader") {
|
|
178
|
+
props.onBlur?.(
|
|
179
|
+
state.filter === state.lastSubmittedValue.filter,
|
|
180
|
+
selectedItem
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
117
184
|
setIsFocused(false);
|
|
118
|
-
}, [filter,
|
|
185
|
+
}, [filter, initialValueString, props, state, comboboxState]);
|
|
119
186
|
|
|
120
187
|
const handleFocus: FocusEventHandler<HTMLInputElement> = useCallback(
|
|
121
188
|
(event) => {
|
|
122
189
|
setIsFocused(true);
|
|
123
190
|
comboboxState.reset(
|
|
124
|
-
openMenuBehavior === "showAllItems" ? "" :
|
|
191
|
+
openMenuBehavior === "showAllItems" ? "" : initialValueString
|
|
125
192
|
);
|
|
126
193
|
if (ref.current) {
|
|
127
194
|
const length = ref.current.value.length;
|
|
@@ -129,7 +196,7 @@ export const Combobox = memo(
|
|
|
129
196
|
}
|
|
130
197
|
onFocus?.(event);
|
|
131
198
|
},
|
|
132
|
-
[
|
|
199
|
+
[initialValueString, onFocus, openMenuBehavior, comboboxState]
|
|
133
200
|
);
|
|
134
201
|
|
|
135
202
|
const handleUpdateSelection = useCallback(
|
|
@@ -139,11 +206,16 @@ export const Combobox = memo(
|
|
|
139
206
|
const selectedItem = comboboxState.selectCurrentItem(item);
|
|
140
207
|
if (!selectedItem || selectedItem.type === "sectionHeader") return;
|
|
141
208
|
|
|
142
|
-
|
|
143
|
-
|
|
209
|
+
if (props.mode === "string") {
|
|
210
|
+
props.onSelectItem?.(selectedItem.name);
|
|
211
|
+
props.onHoverItem?.(undefined);
|
|
212
|
+
} else {
|
|
213
|
+
props.onSelectItem?.(selectedItem);
|
|
214
|
+
props.onHoverItem?.(undefined);
|
|
215
|
+
}
|
|
144
216
|
setShouldBlur(true);
|
|
145
217
|
},
|
|
146
|
-
[
|
|
218
|
+
[props, comboboxState]
|
|
147
219
|
);
|
|
148
220
|
|
|
149
221
|
const handleIndexChange = useCallback(
|
|
@@ -151,12 +223,32 @@ export const Combobox = memo(
|
|
|
151
223
|
comboboxState.setSelectedIndex(index);
|
|
152
224
|
const item = comboboxState.getSelectedItem();
|
|
153
225
|
if (item && item.type !== "sectionHeader") {
|
|
154
|
-
|
|
226
|
+
if (props.mode === "string") {
|
|
227
|
+
props.onHoverItem?.(item.name);
|
|
228
|
+
} else {
|
|
229
|
+
props.onHoverItem?.(item);
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
props.onHoverItem?.(undefined);
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
[props, comboboxState]
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
const handleChange = useCallback(
|
|
239
|
+
(value: string) => {
|
|
240
|
+
if (readOnly) return;
|
|
241
|
+
comboboxState.setFilter(value);
|
|
242
|
+
if (props.mode === "string") {
|
|
243
|
+
props.onChange?.(value);
|
|
155
244
|
} else {
|
|
156
|
-
|
|
245
|
+
const selectedItem = comboboxState.getSelectedItem();
|
|
246
|
+
if (selectedItem && selectedItem.type !== "sectionHeader") {
|
|
247
|
+
props.onChange?.(selectedItem);
|
|
248
|
+
}
|
|
157
249
|
}
|
|
158
250
|
},
|
|
159
|
-
[
|
|
251
|
+
[readOnly, props, comboboxState]
|
|
160
252
|
);
|
|
161
253
|
|
|
162
254
|
const handleKeyDown = useCallback(
|
|
@@ -177,8 +269,11 @@ export const Combobox = memo(
|
|
|
177
269
|
if (shouldShowMenu) {
|
|
178
270
|
if (item) {
|
|
179
271
|
handleUpdateSelection(item);
|
|
180
|
-
} else if (
|
|
181
|
-
|
|
272
|
+
} else if (
|
|
273
|
+
props.mode === "string" &&
|
|
274
|
+
props.allowArbitraryValues
|
|
275
|
+
) {
|
|
276
|
+
// If no item is selected but arbitrary filters are allowed in string mode,
|
|
182
277
|
// submit the current filter value
|
|
183
278
|
comboboxState.submitArbitraryFilter(filter);
|
|
184
279
|
handleBlur();
|
|
@@ -213,8 +308,12 @@ export const Combobox = memo(
|
|
|
213
308
|
}
|
|
214
309
|
handled = true;
|
|
215
310
|
}
|
|
216
|
-
} else if (
|
|
217
|
-
|
|
311
|
+
} else if (
|
|
312
|
+
props.mode === "string" &&
|
|
313
|
+
props.allowArbitraryValues &&
|
|
314
|
+
filter !== ""
|
|
315
|
+
) {
|
|
316
|
+
// Allow submitting arbitrary filter on Tab only in string mode
|
|
218
317
|
comboboxState.submitArbitraryFilter(filter);
|
|
219
318
|
handleBlur();
|
|
220
319
|
handled = true;
|
|
@@ -250,19 +349,10 @@ export const Combobox = memo(
|
|
|
250
349
|
shouldShowMenu,
|
|
251
350
|
comboboxState,
|
|
252
351
|
tabBehavior,
|
|
253
|
-
|
|
352
|
+
props,
|
|
254
353
|
]
|
|
255
354
|
);
|
|
256
355
|
|
|
257
|
-
const handleChange = useCallback(
|
|
258
|
-
(value: string) => {
|
|
259
|
-
if (readOnly) return;
|
|
260
|
-
comboboxState.setFilter(value);
|
|
261
|
-
onChange?.(value);
|
|
262
|
-
},
|
|
263
|
-
[onChange, readOnly, comboboxState]
|
|
264
|
-
);
|
|
265
|
-
|
|
266
356
|
const typeaheadValue = comboboxState.getTypeaheadValue();
|
|
267
357
|
|
|
268
358
|
useImperativeHandle(forwardedRef, () => ({
|
|
@@ -273,8 +363,12 @@ export const Combobox = memo(
|
|
|
273
363
|
ref.current.setSelectionRange(length, length);
|
|
274
364
|
}
|
|
275
365
|
},
|
|
276
|
-
setValue: (value: string) => {
|
|
277
|
-
|
|
366
|
+
setValue: (value: string | ComboboxOption) => {
|
|
367
|
+
if (typeof value === "string") {
|
|
368
|
+
comboboxState.setFilter(value);
|
|
369
|
+
} else {
|
|
370
|
+
comboboxState.setFilter(value.name);
|
|
371
|
+
}
|
|
278
372
|
},
|
|
279
373
|
selectAllInputText: () => {
|
|
280
374
|
ref.current?.setSelectionRange(0, ref.current.value.length);
|
|
@@ -292,14 +386,14 @@ export const Combobox = memo(
|
|
|
292
386
|
|
|
293
387
|
// Use openMenuBehavior consistently for both focus and chevron click
|
|
294
388
|
comboboxState.reset(
|
|
295
|
-
openMenuBehavior === "showAllItems" ? "" :
|
|
389
|
+
openMenuBehavior === "showAllItems" ? "" : initialValueString
|
|
296
390
|
);
|
|
297
391
|
ref.current?.focus();
|
|
298
392
|
},
|
|
299
393
|
[
|
|
300
394
|
shouldShowMenu,
|
|
301
395
|
openMenuBehavior,
|
|
302
|
-
|
|
396
|
+
initialValueString,
|
|
303
397
|
handleBlur,
|
|
304
398
|
comboboxState,
|
|
305
399
|
]
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { assignRef } from "@noya-app/react-utils";
|
|
2
|
-
import React, {
|
|
2
|
+
import React, {
|
|
3
|
+
ComponentProps,
|
|
4
|
+
forwardRef,
|
|
5
|
+
memo,
|
|
6
|
+
useCallback,
|
|
7
|
+
useEffect,
|
|
8
|
+
useRef,
|
|
9
|
+
} from "react";
|
|
3
10
|
import { cx } from "../utils/classNames";
|
|
4
11
|
|
|
5
|
-
export const useAutoResize = (value: string) => {
|
|
12
|
+
export const useAutoResize = (value: string | undefined) => {
|
|
6
13
|
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
7
14
|
|
|
8
15
|
useEffect(() => {
|
|
16
|
+
if (value === undefined) return;
|
|
9
17
|
if (!textareaRef.current) return;
|
|
10
18
|
|
|
11
19
|
textareaRef.current.style.height = "auto"; // Reset the height
|
|
@@ -15,29 +23,29 @@ export const useAutoResize = (value: string) => {
|
|
|
15
23
|
return textareaRef;
|
|
16
24
|
};
|
|
17
25
|
|
|
18
|
-
export const
|
|
19
|
-
forwardRef(function
|
|
26
|
+
export const TextArea = memo(
|
|
27
|
+
forwardRef(function TextArea(
|
|
20
28
|
{
|
|
21
29
|
value,
|
|
22
30
|
onChangeText,
|
|
23
31
|
className,
|
|
24
|
-
end,
|
|
25
|
-
endClassName,
|
|
26
32
|
onChange,
|
|
33
|
+
autoResize = false,
|
|
27
34
|
...rest
|
|
28
35
|
}: {
|
|
29
|
-
onChangeText
|
|
36
|
+
onChangeText?: (value: string) => void;
|
|
30
37
|
value?: string;
|
|
31
|
-
|
|
32
|
-
endClassName?: string;
|
|
38
|
+
autoResize?: boolean;
|
|
33
39
|
} & React.TextareaHTMLAttributes<HTMLTextAreaElement>,
|
|
34
40
|
forwardedRef: React.ForwardedRef<HTMLTextAreaElement>
|
|
35
41
|
) {
|
|
36
|
-
const
|
|
42
|
+
const autoResizeRef = useAutoResize(
|
|
43
|
+
autoResize ? value || rest.placeholder || "" : undefined
|
|
44
|
+
);
|
|
37
45
|
|
|
38
46
|
const handleChange = useCallback(
|
|
39
47
|
(event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
40
|
-
onChangeText(event.target.value);
|
|
48
|
+
onChangeText?.(event.target.value);
|
|
41
49
|
onChange?.(event);
|
|
42
50
|
},
|
|
43
51
|
[onChangeText, onChange]
|
|
@@ -45,24 +53,53 @@ export const AutoResizingTextArea = memo(
|
|
|
45
53
|
|
|
46
54
|
const handleRef = useCallback(
|
|
47
55
|
(value: HTMLTextAreaElement | null) => {
|
|
48
|
-
|
|
56
|
+
if (autoResize) {
|
|
57
|
+
autoResizeRef.current = value;
|
|
58
|
+
}
|
|
49
59
|
assignRef(forwardedRef, value);
|
|
50
60
|
},
|
|
51
|
-
[
|
|
61
|
+
[autoResize, autoResizeRef, forwardedRef]
|
|
52
62
|
);
|
|
53
63
|
|
|
54
64
|
return (
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
<textarea
|
|
66
|
+
className={cx(
|
|
67
|
+
`font-sans text-heading5 font-normal text-text bg-input-background flex-1 py-1 px-1.5 border-none outline-none min-h-6 w-full rounded resize-none placeholder:text-text-disabled focus:ring-2 focus:ring-primary read-only:text-text-disabled focus:z-interactable transition-all`,
|
|
68
|
+
className
|
|
69
|
+
)}
|
|
70
|
+
ref={handleRef}
|
|
71
|
+
{...rest}
|
|
72
|
+
onChange={handleChange}
|
|
73
|
+
value={value}
|
|
74
|
+
/>
|
|
75
|
+
);
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
export const TextAreaRow = memo(
|
|
80
|
+
forwardRef(function TextAreaRow(
|
|
81
|
+
{
|
|
82
|
+
className,
|
|
83
|
+
textAreaClassName,
|
|
84
|
+
textAreaRef,
|
|
85
|
+
end,
|
|
86
|
+
endClassName,
|
|
87
|
+
...rest
|
|
88
|
+
}: {
|
|
89
|
+
className?: string;
|
|
90
|
+
textAreaClassName?: string;
|
|
91
|
+
textAreaRef?: React.Ref<HTMLTextAreaElement>;
|
|
92
|
+
end?: React.ReactNode;
|
|
93
|
+
endClassName?: string;
|
|
94
|
+
} & ComponentProps<typeof TextArea>,
|
|
95
|
+
forwardedRef: React.ForwardedRef<HTMLDivElement>
|
|
96
|
+
) {
|
|
97
|
+
return (
|
|
98
|
+
<div
|
|
99
|
+
ref={forwardedRef}
|
|
100
|
+
className={cx("relative w-full h-full", className)}
|
|
101
|
+
>
|
|
102
|
+
<TextArea className={textAreaClassName} {...rest} ref={textAreaRef} />
|
|
66
103
|
<div className={cx("absolute right-1 top-4", endClassName)}>{end}</div>
|
|
67
104
|
</div>
|
|
68
105
|
);
|
|
@@ -88,19 +88,20 @@ export function ToolbarMenu<T extends string>({
|
|
|
88
88
|
return (
|
|
89
89
|
<Button
|
|
90
90
|
key={i}
|
|
91
|
+
disabled={item.disabled}
|
|
91
92
|
onClick={() => {
|
|
92
93
|
if (onSelectMenuItem && item.value) {
|
|
93
94
|
onSelectMenuItem(item.value);
|
|
94
95
|
}
|
|
95
96
|
}}
|
|
96
97
|
>
|
|
98
|
+
{item.title}
|
|
97
99
|
{item.icon && (
|
|
98
100
|
<>
|
|
99
|
-
{renderIcon(item.icon)}
|
|
100
101
|
<Spacer.Horizontal inline size={6} />
|
|
102
|
+
{renderIcon(item.icon)}
|
|
101
103
|
</>
|
|
102
104
|
)}
|
|
103
|
-
{item.title}
|
|
104
105
|
</Button>
|
|
105
106
|
);
|
|
106
107
|
}
|
|
@@ -115,13 +116,7 @@ export function ToolbarMenu<T extends string>({
|
|
|
115
116
|
}
|
|
116
117
|
}}
|
|
117
118
|
>
|
|
118
|
-
<Button>
|
|
119
|
-
{item.icon && (
|
|
120
|
-
<>
|
|
121
|
-
{renderIcon(item.icon)}
|
|
122
|
-
<Spacer.Horizontal size={6} />
|
|
123
|
-
</>
|
|
124
|
-
)}
|
|
119
|
+
<Button disabled={item.disabled}>
|
|
125
120
|
{item.title}
|
|
126
121
|
<Spacer.Horizontal size={6} />
|
|
127
122
|
<DropdownChevronIcon />
|