@sproutsocial/seeds-react-menu 1.17.0 → 1.18.0
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 +14 -22
- package/CHANGELOG.md +30 -0
- package/dist/esm/index.js +542 -229
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/v3/index.js +793 -1038
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/v3/index.d.mts +64 -38
- package/dist/v3/index.d.ts +64 -38
- package/dist/v3/index.js +813 -1058
- package/dist/v3/index.js.map +1 -1
- package/dist/v3/menu.css +947 -0
- package/package.json +20 -21
- package/src/v3/ActionMenuStyles.tsx +169 -149
- package/src/v3/Common/ComboboxStyles.tsx +396 -511
- package/src/v3/Common/SelectIcons.tsx +17 -8
- package/src/v3/Common/SelectItem.tsx +25 -38
- package/src/v3/Common/SelectStyles.tsx +146 -144
- package/src/v3/Common/cn.ts +38 -0
- package/src/v3/MenuButtonStyles.tsx +55 -34
- package/src/v3/MultiSearchableSelect.tsx +8 -8
- package/src/v3/MultiSelect.tsx +11 -16
- package/src/v3/SingleSelect.tsx +13 -13
- package/src/v3/menu.css +947 -0
- package/tsup.config.ts +0 -1
- package/dist/esm/chunk-ROQATIB7.js +0 -357
- package/dist/esm/chunk-ROQATIB7.js.map +0 -1
- package/dist/esm/v2/index.js +0 -2089
- package/dist/esm/v2/index.js.map +0 -1
- package/dist/v2/index.d.mts +0 -108
- package/dist/v2/index.d.ts +0 -108
- package/dist/v2/index.js +0 -2280
- package/dist/v2/index.js.map +0 -1
- package/src/v2/Autocomplete/Autocomplete.stories.tsx +0 -645
- package/src/v2/Autocomplete/MultiAutocomplete.tsx +0 -487
- package/src/v2/Autocomplete/SingleAutocomplete.tsx +0 -366
- package/src/v2/Autocomplete/index.ts +0 -2
- package/src/v2/Common-V2/ComboboxContent.tsx +0 -457
- package/src/v2/Common-V2/MenuGroup.tsx +0 -60
- package/src/v2/Common-V2/MenuGroupTypes.ts +0 -30
- package/src/v2/Common-V2/MenuHeading.tsx +0 -83
- package/src/v2/Common-V2/MenuItem.tsx +0 -138
- package/src/v2/Common-V2/Popout.tsx +0 -124
- package/src/v2/Common-V2/PopoutTypes.tsx +0 -109
- package/src/v2/Common-V2/SelectToggleButton.tsx +0 -99
- package/src/v2/Common-V2/index.ts +0 -11
- package/src/v2/Common-V2/props.ts +0 -84
- package/src/v2/Common-V2/styles.tsx +0 -41
- package/src/v2/Common-V2/types.ts +0 -16
- package/src/v2/Common-V2/useHighlightedIndex.ts +0 -62
- package/src/v2/Common-V2/utils.ts +0 -238
- package/src/v2/SearchableSelect/AutocompleteContent.tsx +0 -325
- package/src/v2/SearchableSelect/SearchableMultiSelect.tsx +0 -527
- package/src/v2/SearchableSelect/SearchableSelect.tsx +0 -395
- package/src/v2/SearchableSelect/index.ts +0 -12
- package/src/v2/Select/MultiSelect.tsx +0 -417
- package/src/v2/Select/Select.stories.tsx +0 -593
- package/src/v2/Select/SingleSelect.tsx +0 -285
- package/src/v2/Select/index.ts +0 -2
- package/src/v2/index.ts +0 -2
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
import { useState, useMemo, useEffect } from "react";
|
|
2
|
-
import { useCombobox } from "downshift";
|
|
3
|
-
import type { ReactNode } from "react";
|
|
4
|
-
import { Label } from "@sproutsocial/seeds-react-label";
|
|
5
|
-
import { Input } from "@sproutsocial/seeds-react-input";
|
|
6
|
-
// This will eventually be imported from seeds-react-popout
|
|
7
|
-
import { Popout, SelectToggleButton } from "../Common-V2";
|
|
8
|
-
import {
|
|
9
|
-
VirtualizedAutocompleteContent,
|
|
10
|
-
NonVirtualizedAutocompleteContent,
|
|
11
|
-
} from "./AutocompleteContent";
|
|
12
|
-
import {
|
|
13
|
-
isGroupHeading,
|
|
14
|
-
isToggleItem,
|
|
15
|
-
menuAnimationConfig,
|
|
16
|
-
getFilteredItems,
|
|
17
|
-
groupItemsWithHeadings,
|
|
18
|
-
useHighlightedIndex,
|
|
19
|
-
createItemToStringForDownshift,
|
|
20
|
-
} from "../Common-V2";
|
|
21
|
-
import {
|
|
22
|
-
type DataWithId,
|
|
23
|
-
type GroupedItem,
|
|
24
|
-
type ToggleItem,
|
|
25
|
-
type BaseSingleAutocompleteProps,
|
|
26
|
-
} from "../Common-V2";
|
|
27
|
-
|
|
28
|
-
function defaultReducer(state, actionAndChanges) {
|
|
29
|
-
const { changes, type } = actionAndChanges;
|
|
30
|
-
|
|
31
|
-
switch (type) {
|
|
32
|
-
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
33
|
-
case useCombobox.stateChangeTypes.ItemClick:
|
|
34
|
-
return {
|
|
35
|
-
...changes,
|
|
36
|
-
inputValue: "",
|
|
37
|
-
isOpen: false, // close the menu after selection for single select
|
|
38
|
-
highlightedIndex: 0, // reset highlight
|
|
39
|
-
};
|
|
40
|
-
default:
|
|
41
|
-
return changes;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface SearchableSelectProps<T extends DataWithId>
|
|
46
|
-
extends BaseSingleAutocompleteProps<T> {
|
|
47
|
-
name: string;
|
|
48
|
-
renderSelection?: (item: T | null) => ReactNode;
|
|
49
|
-
triggerButtonProps?: any;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function SearchableSelect<T extends DataWithId>({
|
|
53
|
-
id,
|
|
54
|
-
data,
|
|
55
|
-
selectedItemId: controlledSelectedItemId,
|
|
56
|
-
inputValue: controlledInputValue,
|
|
57
|
-
isOpen: controlledIsOpen,
|
|
58
|
-
itemToKey = (item: T) => item?.id,
|
|
59
|
-
itemToString,
|
|
60
|
-
itemToSearchString,
|
|
61
|
-
renderSelection,
|
|
62
|
-
renderItem,
|
|
63
|
-
groupBy,
|
|
64
|
-
renderGroupHeading,
|
|
65
|
-
isVirtualized = false,
|
|
66
|
-
EmptyState,
|
|
67
|
-
name,
|
|
68
|
-
placeholder,
|
|
69
|
-
placeholderItem,
|
|
70
|
-
onSelectedItemIdChange,
|
|
71
|
-
onInputValueChange,
|
|
72
|
-
onIsOpenChange,
|
|
73
|
-
stateReducer = defaultReducer,
|
|
74
|
-
triggerButtonProps,
|
|
75
|
-
onPointerDownOutside,
|
|
76
|
-
onInteractOutside,
|
|
77
|
-
popoutPlacement,
|
|
78
|
-
}: SearchableSelectProps<T>) {
|
|
79
|
-
const [uncontrolledInputValue, setUncontrolledInputValue] =
|
|
80
|
-
useState<string>("");
|
|
81
|
-
const [uncontrolledSelectedItemId, setUncontrolledSelectedItemId] = useState<
|
|
82
|
-
T["id"] | null
|
|
83
|
-
>(null);
|
|
84
|
-
const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState<boolean>(false);
|
|
85
|
-
|
|
86
|
-
// Use controlled selectedItemId if provided, otherwise use internal state
|
|
87
|
-
const isSelectedItemIdControlled = controlledSelectedItemId !== undefined;
|
|
88
|
-
const selectedItemId = isSelectedItemIdControlled
|
|
89
|
-
? controlledSelectedItemId
|
|
90
|
-
: uncontrolledSelectedItemId;
|
|
91
|
-
|
|
92
|
-
// Convert selectedItemId to selectedItem for internal use
|
|
93
|
-
const selectedItem = useMemo<T | null>(() => {
|
|
94
|
-
if (selectedItemId === null || selectedItemId === undefined) {
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
|
-
return data.find((item) => itemToKey(item) === selectedItemId) ?? null;
|
|
98
|
-
}, [selectedItemId, data, itemToKey]);
|
|
99
|
-
|
|
100
|
-
// Use controlled inputValue if provided, otherwise use internal state
|
|
101
|
-
const isInputValueControlled = controlledInputValue !== undefined;
|
|
102
|
-
const inputValue = isInputValueControlled
|
|
103
|
-
? controlledInputValue
|
|
104
|
-
: uncontrolledInputValue;
|
|
105
|
-
|
|
106
|
-
// Use controlled isOpen if provided, otherwise use internal state
|
|
107
|
-
const isIsOpenControlled = controlledIsOpen !== undefined;
|
|
108
|
-
const isOpen = isIsOpenControlled ? controlledIsOpen : uncontrolledIsOpen;
|
|
109
|
-
|
|
110
|
-
const updateSelectedItem = (newSelectedItem: T | null) => {
|
|
111
|
-
const newSelectedItemId = newSelectedItem
|
|
112
|
-
? itemToKey(newSelectedItem)
|
|
113
|
-
: null;
|
|
114
|
-
if (!isSelectedItemIdControlled) {
|
|
115
|
-
setUncontrolledSelectedItemId(newSelectedItemId);
|
|
116
|
-
}
|
|
117
|
-
onSelectedItemIdChange?.(newSelectedItemId);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const updateInputValue = (newInputValue: string) => {
|
|
121
|
-
if (!isInputValueControlled) {
|
|
122
|
-
setUncontrolledInputValue(newInputValue);
|
|
123
|
-
}
|
|
124
|
-
onInputValueChange?.(newInputValue);
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const updateIsOpen = (newIsOpen: boolean) => {
|
|
128
|
-
if (!isIsOpenControlled) {
|
|
129
|
-
setUncontrolledIsOpen(newIsOpen);
|
|
130
|
-
}
|
|
131
|
-
onIsOpenChange?.(newIsOpen);
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// Use itemToSearchString if provided, otherwise fallback to itemToString
|
|
135
|
-
const searchStringFn =
|
|
136
|
-
itemToSearchString ?? ((item: T) => itemToString(item));
|
|
137
|
-
|
|
138
|
-
const filteredItems = useMemo<T[]>(
|
|
139
|
-
() =>
|
|
140
|
-
getFilteredItems(data, inputValue, searchStringFn, itemToString, {
|
|
141
|
-
selectedItem,
|
|
142
|
-
}),
|
|
143
|
-
[data, selectedItem, inputValue, searchStringFn, itemToString]
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
const items = useMemo<GroupedItem<T>[]>(() => {
|
|
147
|
-
let groupedItems: GroupedItem<T>[];
|
|
148
|
-
|
|
149
|
-
if (groupBy) {
|
|
150
|
-
// Group first, then add placeholderItem at the beginning
|
|
151
|
-
groupedItems = groupItemsWithHeadings(filteredItems, groupBy, data);
|
|
152
|
-
} else {
|
|
153
|
-
groupedItems = filteredItems;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Add placeholderItem at the beginning if provided
|
|
157
|
-
if (placeholderItem) {
|
|
158
|
-
return [placeholderItem, ...groupedItems];
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return groupedItems;
|
|
162
|
-
}, [filteredItems, groupBy, placeholderItem, data]);
|
|
163
|
-
|
|
164
|
-
// Filter out headings for downshift
|
|
165
|
-
const itemsForCombobox = useMemo<(T | ToggleItem)[]>(() => {
|
|
166
|
-
return items.filter(
|
|
167
|
-
(item): item is T | ToggleItem => !isGroupHeading(item)
|
|
168
|
-
);
|
|
169
|
-
}, [items]);
|
|
170
|
-
|
|
171
|
-
// Wrapper function to handle ToggleItem separately
|
|
172
|
-
const itemToStringForDownshift = useMemo(
|
|
173
|
-
() => createItemToStringForDownshift(itemToString),
|
|
174
|
-
[itemToString]
|
|
175
|
-
);
|
|
176
|
-
|
|
177
|
-
const comboboxProps = useCombobox<T | ToggleItem>({
|
|
178
|
-
inputId: id,
|
|
179
|
-
items: itemsForCombobox,
|
|
180
|
-
itemToString: itemToStringForDownshift,
|
|
181
|
-
defaultHighlightedIndex: 0,
|
|
182
|
-
selectedItem: selectedItem,
|
|
183
|
-
inputValue,
|
|
184
|
-
isOpen,
|
|
185
|
-
stateReducer,
|
|
186
|
-
onStateChange({
|
|
187
|
-
inputValue: newInputValue,
|
|
188
|
-
type,
|
|
189
|
-
selectedItem: newSelectedItem,
|
|
190
|
-
isOpen: newIsOpen,
|
|
191
|
-
}) {
|
|
192
|
-
// Handle isOpen changes for any state change type
|
|
193
|
-
if (
|
|
194
|
-
newIsOpen !== undefined &&
|
|
195
|
-
type !== useCombobox.stateChangeTypes.InputBlur
|
|
196
|
-
) {
|
|
197
|
-
updateIsOpen(newIsOpen);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
switch (type) {
|
|
201
|
-
case useCombobox.stateChangeTypes.InputKeyDownEnter:
|
|
202
|
-
case useCombobox.stateChangeTypes.ItemClick:
|
|
203
|
-
if (newSelectedItem) {
|
|
204
|
-
updateInputValue("");
|
|
205
|
-
// If placeholderItem is selected, set selectedItem to null
|
|
206
|
-
// Note: placeholderItem won't be in itemsForCombobox, so this check is for safety
|
|
207
|
-
if (
|
|
208
|
-
placeholderItem &&
|
|
209
|
-
isToggleItem(newSelectedItem) &&
|
|
210
|
-
newSelectedItem.id === placeholderItem.id
|
|
211
|
-
) {
|
|
212
|
-
updateSelectedItem(null);
|
|
213
|
-
} else {
|
|
214
|
-
updateSelectedItem(newSelectedItem as T);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
break;
|
|
218
|
-
|
|
219
|
-
case useCombobox.stateChangeTypes.InputChange:
|
|
220
|
-
updateInputValue(newInputValue ?? "");
|
|
221
|
-
break;
|
|
222
|
-
|
|
223
|
-
default:
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
});
|
|
228
|
-
const {
|
|
229
|
-
isOpen: comboboxIsOpen,
|
|
230
|
-
getLabelProps,
|
|
231
|
-
getMenuProps,
|
|
232
|
-
getInputProps,
|
|
233
|
-
highlightedIndex: comboboxHighlightedIndex,
|
|
234
|
-
getItemProps,
|
|
235
|
-
} = comboboxProps;
|
|
236
|
-
|
|
237
|
-
// Map the highlighted index from combobox (which only knows about items) to the full items array (which includes headings)
|
|
238
|
-
const highlightedIndex = useHighlightedIndex(
|
|
239
|
-
items,
|
|
240
|
-
itemsForCombobox,
|
|
241
|
-
comboboxHighlightedIndex,
|
|
242
|
-
!!groupBy,
|
|
243
|
-
false // Single select components hardcode selectHeadings to false
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
const buttonContent = renderSelection
|
|
247
|
-
? renderSelection(selectedItem)
|
|
248
|
-
: selectedItem
|
|
249
|
-
? itemToString(selectedItem)
|
|
250
|
-
: placeholder;
|
|
251
|
-
|
|
252
|
-
// Handle button click to toggle popout
|
|
253
|
-
const handleButtonClick = () => {
|
|
254
|
-
updateIsOpen(!comboboxIsOpen);
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
return (
|
|
258
|
-
<Popout
|
|
259
|
-
open={comboboxIsOpen}
|
|
260
|
-
onOpenChange={updateIsOpen}
|
|
261
|
-
side={popoutPlacement}
|
|
262
|
-
animationConfig={menuAnimationConfig}
|
|
263
|
-
onOpenAutoFocus={(e) => {
|
|
264
|
-
// Prevent default auto-focus behavior - we'll focus the input manually
|
|
265
|
-
e.preventDefault();
|
|
266
|
-
// Focus the input when popout opens
|
|
267
|
-
const inputElement = document.querySelector(
|
|
268
|
-
`input[name="${name}"]`
|
|
269
|
-
) as HTMLInputElement;
|
|
270
|
-
if (inputElement) {
|
|
271
|
-
setTimeout(() => {
|
|
272
|
-
inputElement.focus();
|
|
273
|
-
}, 0);
|
|
274
|
-
}
|
|
275
|
-
}}
|
|
276
|
-
onCloseAutoFocus={(e) => {
|
|
277
|
-
// Prevent default auto-focus behavior
|
|
278
|
-
e.preventDefault();
|
|
279
|
-
}}
|
|
280
|
-
onPointerDownOutside={onPointerDownOutside}
|
|
281
|
-
onInteractOutside={onInteractOutside}
|
|
282
|
-
content={
|
|
283
|
-
<div>
|
|
284
|
-
{/* Input inside the Popout */}
|
|
285
|
-
<div style={{ marginBottom: "8px" }}>
|
|
286
|
-
{(() => {
|
|
287
|
-
const inputProps = getInputProps();
|
|
288
|
-
const { ref, id, ...restProps } = inputProps as any;
|
|
289
|
-
return (
|
|
290
|
-
<Input
|
|
291
|
-
id={id}
|
|
292
|
-
name={name}
|
|
293
|
-
inputProps={{
|
|
294
|
-
autoComplete: "off",
|
|
295
|
-
...restProps,
|
|
296
|
-
}}
|
|
297
|
-
innerRef={ref}
|
|
298
|
-
placeholder={placeholder}
|
|
299
|
-
/>
|
|
300
|
-
);
|
|
301
|
-
})()}
|
|
302
|
-
</div>
|
|
303
|
-
{/* Menu inside the Popout */}
|
|
304
|
-
{isVirtualized ? (
|
|
305
|
-
<VirtualizedAutocompleteContent
|
|
306
|
-
items={items}
|
|
307
|
-
getMenuProps={getMenuProps}
|
|
308
|
-
getItemProps={(props: { index: number }) => {
|
|
309
|
-
// Only apply getItemProps to actual items, not headings or ToggleItems
|
|
310
|
-
const item = items[props.index];
|
|
311
|
-
if (isGroupHeading(item)) {
|
|
312
|
-
return {};
|
|
313
|
-
}
|
|
314
|
-
if (isToggleItem(item)) {
|
|
315
|
-
// Handle ToggleItem (placeholderItem) clicks manually
|
|
316
|
-
return {
|
|
317
|
-
onClick: () => {
|
|
318
|
-
if (placeholderItem && item.id === placeholderItem.id) {
|
|
319
|
-
updateSelectedItem(null);
|
|
320
|
-
}
|
|
321
|
-
},
|
|
322
|
-
};
|
|
323
|
-
}
|
|
324
|
-
const dataItem = item as T;
|
|
325
|
-
// Find the index in itemsForCombobox
|
|
326
|
-
const itemIndex = itemsForCombobox.indexOf(dataItem);
|
|
327
|
-
if (itemIndex === -1) {
|
|
328
|
-
return {};
|
|
329
|
-
}
|
|
330
|
-
return getItemProps({ item: dataItem, index: itemIndex });
|
|
331
|
-
}}
|
|
332
|
-
selectedItems={selectedItem ? [selectedItem] : []}
|
|
333
|
-
highlightedIndex={highlightedIndex ?? -1}
|
|
334
|
-
renderItem={renderItem}
|
|
335
|
-
renderGroupHeading={renderGroupHeading}
|
|
336
|
-
EmptyState={EmptyState}
|
|
337
|
-
itemToKey={itemToKey}
|
|
338
|
-
itemToString={itemToString}
|
|
339
|
-
inputType="radio"
|
|
340
|
-
/>
|
|
341
|
-
) : (
|
|
342
|
-
<NonVirtualizedAutocompleteContent
|
|
343
|
-
items={items}
|
|
344
|
-
getMenuProps={getMenuProps}
|
|
345
|
-
getItemProps={(props: { index: number }) => {
|
|
346
|
-
// Only apply getItemProps to actual items, not headings or ToggleItems
|
|
347
|
-
const item = items[props.index];
|
|
348
|
-
if (isGroupHeading(item)) {
|
|
349
|
-
return {};
|
|
350
|
-
}
|
|
351
|
-
if (isToggleItem(item)) {
|
|
352
|
-
// Handle ToggleItem (placeholderItem) clicks manually
|
|
353
|
-
return {
|
|
354
|
-
onClick: () => {
|
|
355
|
-
if (placeholderItem && item.id === placeholderItem.id) {
|
|
356
|
-
updateSelectedItem(null);
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
};
|
|
360
|
-
}
|
|
361
|
-
const dataItem = item as T;
|
|
362
|
-
// Find the index in itemsForCombobox
|
|
363
|
-
const itemIndex = itemsForCombobox.indexOf(dataItem);
|
|
364
|
-
if (itemIndex === -1) {
|
|
365
|
-
return {};
|
|
366
|
-
}
|
|
367
|
-
return getItemProps({ item: dataItem, index: itemIndex });
|
|
368
|
-
}}
|
|
369
|
-
selectedItems={selectedItem ? [selectedItem] : []}
|
|
370
|
-
highlightedIndex={highlightedIndex ?? -1}
|
|
371
|
-
renderItem={renderItem}
|
|
372
|
-
renderGroupHeading={renderGroupHeading}
|
|
373
|
-
EmptyState={EmptyState}
|
|
374
|
-
itemToKey={itemToKey}
|
|
375
|
-
itemToString={itemToString}
|
|
376
|
-
inputType="radio"
|
|
377
|
-
/>
|
|
378
|
-
)}
|
|
379
|
-
</div>
|
|
380
|
-
}
|
|
381
|
-
>
|
|
382
|
-
<div>
|
|
383
|
-
<SelectToggleButton
|
|
384
|
-
onClick={handleButtonClick}
|
|
385
|
-
{...triggerButtonProps}
|
|
386
|
-
name={name}
|
|
387
|
-
isOpen={comboboxIsOpen}
|
|
388
|
-
type="button"
|
|
389
|
-
>
|
|
390
|
-
{buttonContent}
|
|
391
|
-
</SelectToggleButton>
|
|
392
|
-
</div>
|
|
393
|
-
</Popout>
|
|
394
|
-
);
|
|
395
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// These are currently experimental components
|
|
2
|
-
// These use the combobox pattern, but have a "dialog" popup.
|
|
3
|
-
// The dialog content includes an inline autocomplete which is always open.
|
|
4
|
-
// https://www.w3.org/WAI/ARIA/apg/patterns/combobox/
|
|
5
|
-
// Still need to determine wether we should have
|
|
6
|
-
// - The Root component be the "Combobox" and the popup be a dialog with another combobox inside
|
|
7
|
-
// - Or the Root component simply be a "Dialog" with a combobox inside
|
|
8
|
-
// currently it is the latter.
|
|
9
|
-
export { SearchableSelect } from "./SearchableSelect";
|
|
10
|
-
export type { SearchableSelectProps } from "./SearchableSelect";
|
|
11
|
-
export { SearchableMultiSelect } from "./SearchableMultiSelect";
|
|
12
|
-
export type { SearchableMultiSelectProps } from "./SearchableMultiSelect";
|