@sproutsocial/seeds-react-menu 1.7.1 → 1.7.5

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.
Files changed (47) hide show
  1. package/.turbo/turbo-build.log +19 -11
  2. package/BUNDLE_OPTIMIZATION.md +307 -0
  3. package/CHANGELOG.md +51 -0
  4. package/dist/esm/chunk-ROQATIB7.js +357 -0
  5. package/dist/esm/chunk-ROQATIB7.js.map +1 -0
  6. package/dist/esm/index.js +261 -2271
  7. package/dist/esm/index.js.map +1 -1
  8. package/dist/esm/v2/index.js +2000 -0
  9. package/dist/esm/v2/index.js.map +1 -0
  10. package/dist/index.d.mts +1 -0
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.js +297 -1989
  13. package/dist/index.js.map +1 -1
  14. package/dist/v2/index.d.mts +96 -0
  15. package/dist/v2/index.d.ts +96 -0
  16. package/dist/v2/index.js +2191 -0
  17. package/dist/v2/index.js.map +1 -0
  18. package/package.json +30 -14
  19. package/src/MenuItem/styles.tsx +7 -0
  20. package/src/v2/Autocomplete/Autocomplete.stories.tsx +609 -0
  21. package/src/v2/Autocomplete/MultiAutocomplete.tsx +453 -0
  22. package/src/v2/Autocomplete/SingleAutocomplete.tsx +362 -0
  23. package/src/v2/Autocomplete/index.ts +2 -0
  24. package/src/v2/Common-V2/ComboboxContent.tsx +448 -0
  25. package/src/v2/Common-V2/MenuGroup.tsx +60 -0
  26. package/src/v2/Common-V2/MenuGroupTypes.ts +30 -0
  27. package/src/v2/Common-V2/MenuHeading.tsx +83 -0
  28. package/src/v2/Common-V2/MenuItem.tsx +138 -0
  29. package/src/v2/Common-V2/Popout.tsx +102 -0
  30. package/src/v2/Common-V2/PopoutTypes.tsx +92 -0
  31. package/src/v2/Common-V2/SelectToggleButton.tsx +99 -0
  32. package/src/v2/Common-V2/index.ts +11 -0
  33. package/src/v2/Common-V2/props.ts +74 -0
  34. package/src/v2/Common-V2/styles.tsx +41 -0
  35. package/src/v2/Common-V2/types.ts +16 -0
  36. package/src/v2/Common-V2/useHighlightedIndex.ts +62 -0
  37. package/src/v2/Common-V2/utils.ts +238 -0
  38. package/src/v2/SearchableSelect/AutocompleteContent.tsx +325 -0
  39. package/src/v2/SearchableSelect/SearchableMultiSelect.tsx +521 -0
  40. package/src/v2/SearchableSelect/SearchableSelect.tsx +389 -0
  41. package/src/v2/SearchableSelect/index.ts +12 -0
  42. package/src/v2/Select/MultiSelect.tsx +404 -0
  43. package/src/v2/Select/Select.stories.tsx +593 -0
  44. package/src/v2/Select/SingleSelect.tsx +272 -0
  45. package/src/v2/Select/index.ts +2 -0
  46. package/src/v2/index.ts +2 -0
  47. package/tsup.config.ts +14 -5
@@ -0,0 +1,2191 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/v2/index.ts
31
+ var v2_exports = {};
32
+ __export(v2_exports, {
33
+ MultiAutocomplete: () => MultiAutocomplete,
34
+ MultiSelect: () => MultiSelect,
35
+ SingleAutocomplete: () => SingleAutocomplete,
36
+ SingleSelect: () => SingleSelect
37
+ });
38
+ module.exports = __toCommonJS(v2_exports);
39
+
40
+ // src/v2/Select/SingleSelect.tsx
41
+ var import_react8 = require("react");
42
+ var import_downshift = require("downshift");
43
+ var import_seeds_react_label = require("@sproutsocial/seeds-react-label");
44
+
45
+ // src/v2/Common-V2/utils.ts
46
+ var import_react = require("react");
47
+ var import_unitless = require("@sproutsocial/seeds-motion/unitless");
48
+ var import_seeds_react_popout = require("@sproutsocial/seeds-react-popout");
49
+ function isGroupHeading(item) {
50
+ return typeof item === "object" && item !== null && "type" in item && item.type === "heading";
51
+ }
52
+ function isToggleItem(item) {
53
+ return typeof item === "object" && item !== null && "label" in item && !("type" in item) && Object.keys(item).length === 2 && // ToggleItem only has id and label
54
+ "id" in item;
55
+ }
56
+ var menuPlacementOrigin = {
57
+ top: { originX: 0.5, originY: 1 },
58
+ ["top-start"]: { originX: 0, originY: 1 },
59
+ ["top-end"]: { originX: 1, originY: 1 },
60
+ bottom: { originX: 0.5, originY: 0 },
61
+ ["bottom-start"]: { originX: 0, originY: 0 },
62
+ ["bottom-end"]: { originX: 1, originY: 0 },
63
+ left: { originX: 1, originY: 0.5 },
64
+ ["left-start"]: { originX: 1, originY: 0 },
65
+ ["left-end"]: { originX: 1, originY: 1 },
66
+ right: { originX: 0, originY: 0.5 },
67
+ ["right-start"]: { originX: 0, originY: 0 },
68
+ ["right-end"]: { originX: 0, originY: 1 }
69
+ };
70
+ var menuAnimationConfig = {
71
+ // Turning off layout true. This seems to be what causes the crazy animations when searching.
72
+ // layout: true,
73
+ variants: {
74
+ initial: (custom = { placement: "bottom" }) => ({
75
+ ...menuPlacementOrigin[custom.placement],
76
+ scale: 0,
77
+ opacity: 0
78
+ }),
79
+ animate: (custom = { placement: "bottom" }) => ({
80
+ ...menuPlacementOrigin[custom.placement],
81
+ opacity: 1,
82
+ scale: 1,
83
+ transition: {
84
+ type: "tween",
85
+ duration: import_unitless.MOTION_DURATION_FAST,
86
+ ease: "circOut"
87
+ }
88
+ }),
89
+ exit: {
90
+ opacity: 0,
91
+ scale: 1,
92
+ transition: {
93
+ type: "tween",
94
+ duration: import_unitless.MOTION_DURATION_FAST,
95
+ ease: "circIn"
96
+ }
97
+ }
98
+ },
99
+ initial: "initial",
100
+ whileInView: "animate",
101
+ viewport: { once: true },
102
+ exit: "exit"
103
+ };
104
+ function getFilteredItems(data, inputValue, itemToSearchString, itemToString, options) {
105
+ const lowerCasedInputValue = inputValue.toLowerCase();
106
+ if (options?.selectedItem && itemToString(options?.selectedItem).toLowerCase() === lowerCasedInputValue) {
107
+ return data;
108
+ }
109
+ return data.filter(function filterItem(item) {
110
+ if (options?.selectedItems && !options.showSelectedItems && options.selectedItems.includes(item)) {
111
+ return false;
112
+ }
113
+ const searchString = itemToSearchString(item);
114
+ const searchableParts = searchString.split("|").map((part) => part.toLowerCase().trim());
115
+ return searchableParts.some((part) => part.includes(lowerCasedInputValue));
116
+ });
117
+ }
118
+ function groupItems(items, groupBy, allData) {
119
+ if (items.length === 0) {
120
+ return /* @__PURE__ */ new Map();
121
+ }
122
+ const dataForOrder = allData || items;
123
+ const groupOrder = [];
124
+ const seenGroups = /* @__PURE__ */ new Set();
125
+ for (const item of dataForOrder) {
126
+ let groupKey = groupBy(item);
127
+ if (item.id === "clear-selection") {
128
+ continue;
129
+ }
130
+ if (!seenGroups.has(groupKey)) {
131
+ seenGroups.add(groupKey);
132
+ groupOrder.push(groupKey);
133
+ }
134
+ }
135
+ const grouped = /* @__PURE__ */ new Map();
136
+ for (const item of items) {
137
+ let groupKey = groupBy(item);
138
+ if (item.id === "clear-selection") {
139
+ continue;
140
+ }
141
+ if (!grouped.has(groupKey)) {
142
+ grouped.set(groupKey, []);
143
+ }
144
+ grouped.get(groupKey).push(item);
145
+ }
146
+ const sortedGrouped = /* @__PURE__ */ new Map();
147
+ for (const groupKey of groupOrder) {
148
+ const groupItems2 = grouped.get(groupKey);
149
+ if (groupItems2) {
150
+ sortedGrouped.set(groupKey, groupItems2);
151
+ }
152
+ }
153
+ return sortedGrouped;
154
+ }
155
+ function groupItemsWithHeadings(items, groupBy, allData, selectHeadings = false) {
156
+ if (items.length === 0) {
157
+ return [];
158
+ }
159
+ const grouped = groupItems(items, groupBy, allData);
160
+ const result = [];
161
+ for (const groupKey of grouped.keys()) {
162
+ const groupItems2 = grouped.get(groupKey);
163
+ if (groupItems2 && groupItems2.length > 0) {
164
+ if (selectHeadings) {
165
+ result.push({
166
+ id: `heading-${groupKey}`,
167
+ type: "heading",
168
+ label: groupKey
169
+ });
170
+ }
171
+ result.push(...groupItems2);
172
+ }
173
+ }
174
+ return result;
175
+ }
176
+ function createItemToStringForDownshift(itemToString) {
177
+ return (item) => {
178
+ if (!item) return "";
179
+ if (isToggleItem(item)) {
180
+ return item.label;
181
+ }
182
+ if (isGroupHeading(item)) {
183
+ return item.label;
184
+ }
185
+ return itemToString(item);
186
+ };
187
+ }
188
+
189
+ // src/v2/Common-V2/Popout.tsx
190
+ var React2 = __toESM(require("react"));
191
+ var import_react2 = require("motion/react");
192
+ var Popover = __toESM(require("@radix-ui/react-popover"));
193
+ var import_unitless2 = require("@sproutsocial/seeds-motion/unitless");
194
+ var import_styled_components = __toESM(require("styled-components"));
195
+ var import_jsx_runtime = require("react/jsx-runtime");
196
+ var defaultAnimationConfig = {
197
+ initial: { opacity: 0 },
198
+ animate: { opacity: 1 },
199
+ exit: { opacity: 0 },
200
+ transition: {
201
+ ease: "circOut",
202
+ type: "tween",
203
+ duration: import_unitless2.MOTION_DURATION_FAST
204
+ }
205
+ };
206
+ var StyledContent = (0, import_styled_components.default)(Popover.Content)`
207
+ width: var(--radix-popover-trigger-width);
208
+ max-height: var(--radix-popover-content-available-height);
209
+ // This should be a prop on the Popout component
210
+ z-index: 7;
211
+ `;
212
+ var StyledMotionDiv = (0, import_styled_components.default)(import_react2.motion.div)`
213
+ background-color: ${({ theme }) => theme.colors.container.background.base};
214
+ border: ${({ theme }) => theme.borders[500]};
215
+ border-color: ${({ theme }) => theme.colors.container.border.base};
216
+ border-radius: ${({ theme }) => theme.radii[500]};
217
+ box-shadow: ${({ theme }) => theme.shadows.medium};
218
+ padding: ${({ theme }) => theme.space[400]};
219
+ `;
220
+ function Popout({
221
+ children,
222
+ content,
223
+ open,
224
+ defaultOpen,
225
+ onOpenChange,
226
+ animationConfig = defaultAnimationConfig,
227
+ side = "bottom",
228
+ sideOffset = 8,
229
+ align = "center",
230
+ alignOffset = 0,
231
+ onOpenAutoFocus,
232
+ onEscapeKeyDown,
233
+ onCloseAutoFocus,
234
+ ...rest
235
+ }) {
236
+ const [isOpen, setIsOpen] = React2.useState(defaultOpen ?? false);
237
+ const handleOpenChange = React2.useCallback(
238
+ (newOpen) => {
239
+ setIsOpen(newOpen);
240
+ onOpenChange?.(newOpen);
241
+ },
242
+ [onOpenChange]
243
+ );
244
+ const isControlled = open !== void 0;
245
+ const popoverOpen = isControlled ? open : isOpen;
246
+ const popoverOnOpenChange = isControlled ? onOpenChange : handleOpenChange;
247
+ const radixRef = React2.useRef(null);
248
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Popover.Root, { open: popoverOpen, onOpenChange: popoverOnOpenChange, children: [
249
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Popover.Trigger, { ref: radixRef, asChild: true, children }),
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Popover.Anchor, {}),
251
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Popover.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
252
+ StyledContent,
253
+ {
254
+ side,
255
+ sideOffset,
256
+ align,
257
+ alignOffset,
258
+ onOpenAutoFocus,
259
+ onEscapeKeyDown,
260
+ onCloseAutoFocus,
261
+ role: "presentation",
262
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StyledMotionDiv, { ...animationConfig, ...rest, children: content })
263
+ }
264
+ ) })
265
+ ] });
266
+ }
267
+
268
+ // src/v2/Common-V2/PopoutTypes.tsx
269
+ var React3 = require("react");
270
+
271
+ // src/v2/Common-V2/SelectToggleButton.tsx
272
+ var import_styled_components2 = __toESM(require("styled-components"));
273
+ var import_seeds_react_icon = require("@sproutsocial/seeds-react-icon");
274
+
275
+ // src/MenuToggleButton/MenuToggleButton.tsx
276
+ var import_seeds_react_button = require("@sproutsocial/seeds-react-button");
277
+
278
+ // src/MenuContext.tsx
279
+ var import_react3 = __toESM(require("react"));
280
+ var import_jsx_runtime2 = require("react/jsx-runtime");
281
+ var defaultMenuContext = {
282
+ items: [],
283
+ itemsMap: {},
284
+ isItemSelected: () => false,
285
+ getInputComponentProps: () => ({}),
286
+ hasVisibleItems: false,
287
+ isInitialized: false
288
+ };
289
+ var MenuToggleContext = (0, import_react3.createContext)(defaultMenuContext);
290
+ var MenuContentContext = (0, import_react3.createContext)(defaultMenuContext);
291
+
292
+ // src/MenuToggleButton/MenuToggleButton.tsx
293
+ var import_jsx_runtime3 = require("react/jsx-runtime");
294
+
295
+ // src/v2/Common-V2/SelectToggleButton.tsx
296
+ var import_seeds_react_button2 = __toESM(require("@sproutsocial/seeds-react-button"));
297
+ var import_jsx_runtime4 = require("react/jsx-runtime");
298
+ var StyledSelectToggleButton = (0, import_styled_components2.default)(
299
+ import_seeds_react_button2.default
300
+ )`
301
+ border-color: ${(props) => props.theme.colors.form.border.base};
302
+ width: 100%;
303
+
304
+ ${(props) => props.invalid && import_styled_components2.css`
305
+ border-color: ${(props2) => props2.theme.colors.form.border.error};
306
+ `}
307
+ `;
308
+ var StyledChevron = import_styled_components2.default.div`
309
+ margin-left: ${({ theme }) => theme.space[300]};
310
+
311
+ ${({ invalid }) => invalid && import_styled_components2.css`
312
+ color: ${(props) => props.theme.colors.icon.error};
313
+ `}
314
+ `;
315
+ var RotatingIcon = (0, import_styled_components2.default)(import_seeds_react_icon.Icon)`
316
+ transition: transform 0.15s;
317
+
318
+ ${({ $isOpen }) => $isOpen && `
319
+ transform: rotate(-180deg);
320
+ `}
321
+ `;
322
+ var StyledInnerButton = import_styled_components2.default.div`
323
+ display: flex;
324
+ justify-content: space-between;
325
+ `;
326
+ var EllipsisContent = import_styled_components2.default.div`
327
+ overflow: hidden;
328
+ text-overflow: ellipsis;
329
+ white-space: nowrap;
330
+ `;
331
+ var WrappedContent = import_styled_components2.default.div`
332
+ flex: 1;
333
+ width: 100%;
334
+ text-align: left;
335
+ text-wrap: auto;
336
+ `;
337
+ var SelectToggleButton = ({
338
+ children,
339
+ isOpen,
340
+ shouldOverflow,
341
+ ...buttonProps
342
+ }) => {
343
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StyledSelectToggleButton, { ...buttonProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(StyledInnerButton, { children: [
344
+ shouldOverflow ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(WrappedContent, { children }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EllipsisContent, { children }),
345
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(StyledChevron, { $isOpen: isOpen, invalid: buttonProps.invalid, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
346
+ RotatingIcon,
347
+ {
348
+ name: "chevron-down-outline",
349
+ fixedWidth: true,
350
+ "aria-hidden": true,
351
+ $isOpen: isOpen
352
+ }
353
+ ) })
354
+ ] }) });
355
+ };
356
+
357
+ // src/v2/Common-V2/MenuItem.tsx
358
+ var import_react4 = require("react");
359
+ var import_seeds_react_icon2 = require("@sproutsocial/seeds-react-icon");
360
+ var import_seeds_react_checkbox2 = require("@sproutsocial/seeds-react-checkbox");
361
+ var import_seeds_react_switch = require("@sproutsocial/seeds-react-switch");
362
+ var import_seeds_react_radio = require("@sproutsocial/seeds-react-radio");
363
+ var import_styled_components4 = require("styled-components");
364
+ var import_seeds_react_box = require("@sproutsocial/seeds-react-box");
365
+
366
+ // src/MenuItem/styles.tsx
367
+ var import_styled_components3 = __toESM(require("styled-components"));
368
+ var import_seeds_react_mixins = require("@sproutsocial/seeds-react-mixins");
369
+ var import_styled_system = require("styled-system");
370
+ var import_seeds_react_checkbox = require("@sproutsocial/seeds-react-checkbox");
371
+ var highlightedStyles = import_styled_components3.css`
372
+ cursor: pointer;
373
+ border: 1px solid ${({ theme }) => theme.colors.listItem.border.base};
374
+ background-color: ${({ theme }) => theme.colors.listItem.background.hover};
375
+ color: ${({ theme }) => theme.colors.text.body};
376
+ text-decoration: none;
377
+ `;
378
+ var activeStyles = import_styled_components3.css`
379
+ border: 1px solid ${({ theme }) => theme.colors.listItem.border.base};
380
+ background-color: ${({ theme }) => theme.colors.menuItem.background.active};
381
+ color: ${({ theme }) => theme.colors.text.body};
382
+ text-decoration: none;
383
+ `;
384
+ var selectedStyles = import_styled_components3.css`
385
+ font-weight: ${({ theme }) => theme.fontWeights.semibold};
386
+ `;
387
+ var MenuItemContainer = import_styled_components3.default.li`
388
+ box-sizing: border-box;
389
+ list-style-type: none;
390
+ margin-left: ${({ theme }) => theme.space[300]};
391
+ margin-right: ${({ theme }) => theme.space[300]};
392
+
393
+ &:first-child {
394
+ margin-top: ${({ theme }) => theme.space[300]};
395
+ }
396
+
397
+ &:last-child {
398
+ margin-bottom: ${({ theme }) => theme.space[300]};
399
+ }
400
+ `;
401
+ var StyledMenuItem = import_styled_components3.default.button`
402
+ display: block;
403
+ box-sizing: border-box;
404
+ width: 100%;
405
+ border-radius: ${({ theme }) => theme.radii[500]};
406
+ background-color: ${({ theme }) => theme.colors.listItem.background.base};
407
+ border: 1px solid ${({ theme }) => theme.colors.listItem.background.base};
408
+ color: ${({ theme }) => theme.colors.text.body};
409
+ font-family: ${({ theme }) => theme.fontFamily};
410
+ font-weight: ${({ theme }) => theme.fontWeights.normal};
411
+ text-align: left;
412
+ text-decoration: none;
413
+ padding: ${({ theme }) => theme.space[300]};
414
+ outline: 0;
415
+ ${({ theme }) => theme.typography[200]};
416
+ transition: all ${({ theme }) => theme.duration["fast"]};
417
+
418
+ /* Highlighted */
419
+ ${({ $highlighted }) => $highlighted && highlightedStyles}
420
+
421
+ /* Hovered, but not focused */
422
+ &:hover {
423
+ ${highlightedStyles}
424
+ ${import_seeds_react_checkbox.CheckboxContainer} {
425
+ ${import_seeds_react_checkbox.checkboxContainerHoverStyles}
426
+ }
427
+ ${import_seeds_react_checkbox.InputWrapper} {
428
+ ${import_seeds_react_checkbox.inputWrapperHoverStyles}
429
+ }
430
+ ${import_seeds_react_checkbox.PillInput} {
431
+ ${import_seeds_react_checkbox.pillInputHoverStyles}
432
+ }
433
+ }
434
+
435
+ /* focused */
436
+ &:focus {
437
+ ${import_seeds_react_mixins.focusRing}
438
+ }
439
+
440
+ /* Active */
441
+ ${({ $active }) => $active && activeStyles}
442
+
443
+ /* Pressed state*/
444
+ &:active {
445
+ ${activeStyles}
446
+ }
447
+
448
+ &[aria-disabled="true"] {
449
+ cursor: not-allowed;
450
+ ${import_seeds_react_mixins.disabled}
451
+ }
452
+
453
+ ${({ $selected }) => $selected && selectedStyles}
454
+
455
+ ${import_styled_system.border}
456
+ ${import_styled_system.color}
457
+ ${import_styled_system.flexbox}
458
+ ${import_styled_system.grid}
459
+ ${import_styled_system.layout}
460
+ ${import_styled_system.space}
461
+ `;
462
+ var MenuItemRow = import_styled_components3.default.div`
463
+ display: flex;
464
+ align-items: center;
465
+ pointer-events: none;
466
+ `;
467
+ var MenuItemAction = import_styled_components3.default.div`
468
+ display: flex;
469
+ align-items: center;
470
+ justify-content: center;
471
+ flex-shrink: 0;
472
+ `;
473
+ var MenuItemActionLeft = (0, import_styled_components3.default)(MenuItemAction)`
474
+ margin-right: ${({ theme }) => theme.space[300]};
475
+ `;
476
+ var MenuItemActionRight = (0, import_styled_components3.default)(MenuItemAction)`
477
+ margin-left: ${({ theme }) => theme.space[300]};
478
+ `;
479
+ var MenuItemText = import_styled_components3.default.div`
480
+ word-break: break-word;
481
+ flex-grow: 1;
482
+ min-width: 0;
483
+ `;
484
+
485
+ // src/v2/Common-V2/MenuItem.tsx
486
+ var import_jsx_runtime5 = require("react/jsx-runtime");
487
+ var SelectionIndicator = ({
488
+ id,
489
+ inputType = "icon",
490
+ "aria-labelledby": labeledBy,
491
+ selected
492
+ }) => {
493
+ const { space: space4 } = (0, import_styled_components4.useTheme)();
494
+ const inputStub = (e) => {
495
+ e.stopPropagation();
496
+ };
497
+ switch (inputType) {
498
+ case "checkbox":
499
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
500
+ import_seeds_react_checkbox2.Checkbox,
501
+ {
502
+ tabIndex: -1,
503
+ onChange: () => {
504
+ },
505
+ checked: selected,
506
+ "aria-labelledby": labeledBy,
507
+ id: `MenuItem-${inputType}-${id}`
508
+ }
509
+ );
510
+ case "switch":
511
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
512
+ import_seeds_react_switch.Switch,
513
+ {
514
+ tabIndex: -1,
515
+ onClick: inputStub,
516
+ checked: !!selected,
517
+ "aria-labelledby": labeledBy,
518
+ id: `MenuItem-${inputType}-${id}`
519
+ }
520
+ );
521
+ case "radio":
522
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
523
+ import_seeds_react_radio.Radio,
524
+ {
525
+ tabIndex: -1,
526
+ checked: selected,
527
+ id: `MenuItem-${inputType}-${id}`,
528
+ name: `MenuItem-${inputType}`,
529
+ "aria-labelledby": labeledBy
530
+ }
531
+ );
532
+ case "icon":
533
+ if (selected) {
534
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_seeds_react_icon2.Icon, { name: "check-solid", "aria-hidden": true, size: "small" });
535
+ } else {
536
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_seeds_react_box.Box, { width: space4["400"] });
537
+ }
538
+ default:
539
+ return null;
540
+ }
541
+ };
542
+ var MenuItem = ({
543
+ children,
544
+ $highlighted = false,
545
+ $active = false,
546
+ inputType,
547
+ selected = false,
548
+ id,
549
+ style,
550
+ ...props
551
+ }) => {
552
+ const labelId = (0, import_react4.useMemo)(
553
+ () => id ? `menu-item-child-${id}` : `menu-item-child-${Math.random().toString(36).substr(2, 9)}`,
554
+ [id]
555
+ );
556
+ const content = inputType ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(MenuItemRow, { children: [
557
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuItemActionLeft, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
558
+ SelectionIndicator,
559
+ {
560
+ id: String(id || ""),
561
+ "aria-labelledby": labelId,
562
+ inputType,
563
+ selected
564
+ }
565
+ ) }),
566
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MenuItemText, { id: labelId, children })
567
+ ] }) : children;
568
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
569
+ StyledMenuItem,
570
+ {
571
+ $highlighted,
572
+ $active,
573
+ $selected: selected,
574
+ style,
575
+ ...props,
576
+ children: content
577
+ }
578
+ );
579
+ };
580
+
581
+ // src/v2/Common-V2/MenuHeading.tsx
582
+ var import_styled_components5 = __toESM(require("styled-components"));
583
+ var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
584
+ var import_jsx_runtime6 = require("react/jsx-runtime");
585
+ var MenuHeaderContainer = (0, import_styled_components5.default)(import_seeds_react_box2.default)`
586
+ border-color: ${({ theme }) => theme.colors.container.border.base};
587
+ border-bottom-width: 1px;
588
+ border-bottom-style: solid;
589
+ font-size: ${({ theme }) => theme.typography[200].fontSize};
590
+ display: flex;
591
+ flex-direction: column;
592
+ padding: ${({ theme }) => theme.space[350]} ${({ theme }) => theme.space[400]};
593
+ `;
594
+ var MenuHeading = ({
595
+ label,
596
+ renderGroupHeading,
597
+ style,
598
+ selectable = false,
599
+ $highlighted = false,
600
+ selected = false,
601
+ id,
602
+ onClick,
603
+ ...props
604
+ }) => {
605
+ const combinedStyle = {
606
+ fontWeight: "bold",
607
+ ...style
608
+ };
609
+ if (selectable) {
610
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
611
+ MenuItem,
612
+ {
613
+ style: combinedStyle,
614
+ $highlighted,
615
+ $active: false,
616
+ inputType: "checkbox",
617
+ selected,
618
+ id,
619
+ onClick,
620
+ ...props,
621
+ children: renderGroupHeading ? renderGroupHeading(label) : label
622
+ }
623
+ );
624
+ }
625
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
626
+ MenuHeaderContainer,
627
+ {
628
+ style: combinedStyle,
629
+ role: "option",
630
+ "aria-disabled": true,
631
+ "aria-selected": false,
632
+ children: renderGroupHeading ? renderGroupHeading(label) : label
633
+ }
634
+ );
635
+ };
636
+
637
+ // src/v2/Common-V2/MenuGroup.tsx
638
+ var import_react5 = require("react");
639
+
640
+ // src/v2/Common-V2/styles.tsx
641
+ var import_styled_components6 = __toESM(require("styled-components"));
642
+ var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
643
+ var import_styled_system2 = require("styled-system");
644
+ var StyledMenuGroup = import_styled_components6.default.li`
645
+ font-family: ${({ theme }) => theme.fontFamily};
646
+ &:not(:last-child) {
647
+ border-bottom: 1px solid
648
+ ${({ theme }) => theme.colors.container.border.base};
649
+ }
650
+ list-style: none;
651
+ margin: 0;
652
+
653
+ ${import_styled_system2.border}
654
+ ${import_styled_system2.position}
655
+ ${import_styled_system2.color}
656
+ ${import_styled_system2.flexbox}
657
+ ${import_styled_system2.grid}
658
+ ${import_styled_system2.layout}
659
+ ${import_styled_system2.space}
660
+ `;
661
+ var StyledTitle = (0, import_styled_components6.default)(import_seeds_react_text.default.SmallSubHeadline)`
662
+ font-size: ${({ theme }) => theme.typography[100].fontSize};
663
+ margin: ${({ theme }) => theme.space[400]} ${({ theme }) => theme.space[400]}
664
+ 0px ${({ theme }) => theme.space[400]};
665
+ `;
666
+ var StyledMenuGroupUl = import_styled_components6.default.ul`
667
+ margin: 0;
668
+ padding: 0;
669
+ `;
670
+
671
+ // src/v2/Common-V2/MenuGroup.tsx
672
+ var import_jsx_runtime7 = require("react/jsx-runtime");
673
+ var MenuGroup = ({
674
+ titleAs = "h3",
675
+ children,
676
+ title,
677
+ color: color4,
678
+ id,
679
+ ...rest
680
+ }) => {
681
+ const titleId = `menu-group-title-${Math.random().toString(36).slice(2, 11)}`;
682
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
683
+ StyledMenuGroup,
684
+ {
685
+ role: "group",
686
+ id,
687
+ "aria-labelledby": title ? titleId : void 0,
688
+ color: color4,
689
+ ...rest,
690
+ children: [
691
+ title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StyledTitle, { role: "heading", as: titleAs, id: titleId, children: title }),
692
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StyledMenuGroupUl, { children })
693
+ ]
694
+ }
695
+ );
696
+ };
697
+ MenuGroup.__MENU_PRIMITIVE_TYPE = "MenuGroup";
698
+
699
+ // src/v2/Common-V2/useHighlightedIndex.ts
700
+ var import_react6 = require("react");
701
+ function useHighlightedIndex(items, itemsForDownshift, downshiftHighlightedIndex, hasGroups, selectHeadings) {
702
+ return (0, import_react6.useMemo)(() => {
703
+ if (downshiftHighlightedIndex === null || downshiftHighlightedIndex === void 0 || downshiftHighlightedIndex < 0) {
704
+ return null;
705
+ }
706
+ if (!hasGroups) {
707
+ return downshiftHighlightedIndex;
708
+ }
709
+ const highlightedItem = itemsForDownshift[downshiftHighlightedIndex];
710
+ if (!highlightedItem) {
711
+ return null;
712
+ }
713
+ if (selectHeadings) {
714
+ return items.findIndex((item) => item === highlightedItem);
715
+ } else {
716
+ return items.findIndex(
717
+ (item) => !isGroupHeading(item) && item === highlightedItem
718
+ );
719
+ }
720
+ }, [
721
+ items,
722
+ itemsForDownshift,
723
+ downshiftHighlightedIndex,
724
+ hasGroups,
725
+ selectHeadings
726
+ ]);
727
+ }
728
+
729
+ // src/v2/Common-V2/ComboboxContent.tsx
730
+ var import_react7 = require("react");
731
+ var import_react_virtual = require("@tanstack/react-virtual");
732
+
733
+ // src/MenuContent/styles.tsx
734
+ var import_styled_components7 = __toESM(require("styled-components"));
735
+ var import_styled_system3 = require("styled-system");
736
+ var StyledMenuContent = import_styled_components7.default.ul`
737
+ margin: 0;
738
+ padding: 0;
739
+ overflow: auto;
740
+
741
+ &:focus {
742
+ outline: none;
743
+ box-shadow: none;
744
+ }
745
+
746
+ ${import_styled_system3.border}
747
+ ${import_styled_system3.color}
748
+ ${import_styled_system3.flexbox}
749
+ ${import_styled_system3.grid}
750
+ ${import_styled_system3.layout}
751
+ ${import_styled_system3.space}
752
+ ${import_styled_system3.position}
753
+ `;
754
+
755
+ // src/v2/Common-V2/ComboboxContent.tsx
756
+ var import_jsx_runtime8 = require("react/jsx-runtime");
757
+ var VirtualizedComboboxContent = ({
758
+ items,
759
+ getMenuProps,
760
+ getItemProps,
761
+ selectedItems,
762
+ highlightedIndex,
763
+ renderItem,
764
+ renderGroupHeading,
765
+ EmptyState,
766
+ itemToKey,
767
+ inputType,
768
+ selectHeadings = false,
769
+ onHeadingClick,
770
+ groupBy,
771
+ allData,
772
+ selectAllItem,
773
+ ...rest
774
+ }) => {
775
+ const containerRef = (0, import_react7.useRef)(null);
776
+ const hasItems = items.some((item) => !isGroupHeading(item));
777
+ const rowVirtualizer = (0, import_react_virtual.useVirtualizer)({
778
+ count: items.length,
779
+ getScrollElement: () => containerRef.current,
780
+ estimateSize: (index) => {
781
+ const item = items[index];
782
+ return isGroupHeading(item) ? 30 : 35;
783
+ }
784
+ });
785
+ (0, import_react7.useEffect)(() => {
786
+ if (highlightedIndex !== void 0 && highlightedIndex !== null && highlightedIndex >= 0) {
787
+ rowVirtualizer.scrollToIndex(highlightedIndex);
788
+ }
789
+ }, [highlightedIndex, rowVirtualizer]);
790
+ const virtualItems = rowVirtualizer.getVirtualItems();
791
+ const menuProps = getMenuProps({ ref: containerRef });
792
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ...menuProps, ...rest, children: !hasItems && EmptyState ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "16px" }, children: EmptyState }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
793
+ StyledMenuContent,
794
+ {
795
+ style: {
796
+ height: `${rowVirtualizer.getTotalSize()}px`,
797
+ position: "relative"
798
+ },
799
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
800
+ "div",
801
+ {
802
+ style: {
803
+ position: "absolute",
804
+ top: 0,
805
+ left: 0,
806
+ width: "100%",
807
+ transform: `translateY(${virtualItems[0]?.start ?? 0}px)`
808
+ },
809
+ children: virtualItems.map((virtualItem) => {
810
+ const item = items[virtualItem.index];
811
+ if (isGroupHeading(item)) {
812
+ const groupItems2 = groupBy && allData ? allData.filter(
813
+ (dataItem2) => groupBy(dataItem2) === item.label
814
+ ) : [];
815
+ const allSelected = groupItems2.length > 0 && groupItems2.every(
816
+ (groupItem) => selectedItems.includes(groupItem)
817
+ );
818
+ const headingItemProps = selectHeadings ? getItemProps({ index: virtualItem.index }) : {};
819
+ const handleHeadingClick = (e) => {
820
+ headingItemProps.onClick?.(e);
821
+ if (onHeadingClick) {
822
+ onHeadingClick(item.label, allSelected);
823
+ }
824
+ };
825
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
826
+ MenuHeading,
827
+ {
828
+ ...headingItemProps,
829
+ $highlighted: highlightedIndex === virtualItem.index,
830
+ label: item.label,
831
+ renderGroupHeading,
832
+ selectable: selectHeadings,
833
+ selected: allSelected,
834
+ id: item.id,
835
+ onClick: selectHeadings ? handleHeadingClick : void 0,
836
+ style: {
837
+ width: "100%"
838
+ }
839
+ },
840
+ virtualItem.key
841
+ );
842
+ }
843
+ if (isToggleItem(item)) {
844
+ const toggleItem = item;
845
+ const isItemSelected2 = selectAllItem && toggleItem.id === selectAllItem.id ? allData && allData.length > 0 && allData.every((item2) => selectedItems.includes(item2)) : false;
846
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
847
+ MenuItem,
848
+ {
849
+ inputType,
850
+ selected: isItemSelected2,
851
+ id: toggleItem.id,
852
+ ...getItemProps({ index: virtualItem.index }),
853
+ style: {
854
+ width: "100%"
855
+ },
856
+ $highlighted: highlightedIndex === virtualItem.index,
857
+ $active: false,
858
+ children: toggleItem.label
859
+ },
860
+ virtualItem.key
861
+ );
862
+ }
863
+ const dataItem = item;
864
+ const isItemSelected = selectedItems.includes(dataItem);
865
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
866
+ MenuItem,
867
+ {
868
+ inputType,
869
+ selected: isItemSelected,
870
+ id: itemToKey(dataItem),
871
+ ...getItemProps({ index: virtualItem.index }),
872
+ style: {
873
+ width: "100%"
874
+ },
875
+ $highlighted: highlightedIndex === virtualItem.index,
876
+ $active: false,
877
+ children: renderItem(dataItem)
878
+ },
879
+ virtualItem.key
880
+ );
881
+ })
882
+ }
883
+ )
884
+ }
885
+ ) });
886
+ };
887
+ var NormalComboboxContent = ({
888
+ items,
889
+ getMenuProps,
890
+ getItemProps,
891
+ selectedItems,
892
+ highlightedIndex,
893
+ renderItem,
894
+ renderGroupHeading,
895
+ EmptyState,
896
+ itemToKey,
897
+ inputType,
898
+ selectHeadings = false,
899
+ onHeadingClick,
900
+ groupBy,
901
+ allData,
902
+ selectAllItem,
903
+ ...rest
904
+ }) => {
905
+ const hasItems = items.some((item) => !isGroupHeading(item));
906
+ const menuProps = getMenuProps();
907
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ...menuProps, ...rest, children: !hasItems && EmptyState ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "16px" }, children: EmptyState }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
908
+ StyledMenuContent,
909
+ {
910
+ style: {
911
+ position: "relative"
912
+ },
913
+ children: items.map((item, index) => {
914
+ if (isGroupHeading(item)) {
915
+ const groupItems2 = groupBy && allData ? allData.filter(
916
+ (dataItem2) => groupBy(dataItem2) === item.label
917
+ ) : [];
918
+ const allSelected = groupItems2.length > 0 && groupItems2.every(
919
+ (groupItem) => selectedItems.includes(groupItem)
920
+ );
921
+ const headingItemProps = selectHeadings ? getItemProps({ index }) : {};
922
+ const handleHeadingClick = (e) => {
923
+ headingItemProps.onClick?.(e);
924
+ if (onHeadingClick) {
925
+ onHeadingClick(item.label, allSelected);
926
+ }
927
+ };
928
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
929
+ MenuHeading,
930
+ {
931
+ ...headingItemProps,
932
+ $highlighted: highlightedIndex === index,
933
+ label: item.label,
934
+ renderGroupHeading,
935
+ selectable: selectHeadings,
936
+ selected: allSelected,
937
+ id: item.id,
938
+ onClick: selectHeadings ? handleHeadingClick : void 0
939
+ },
940
+ index
941
+ );
942
+ }
943
+ if (isToggleItem(item)) {
944
+ const toggleItem = item;
945
+ const isItemSelected2 = selectAllItem && toggleItem.id === selectAllItem.id ? allData && allData.length > 0 && allData.every((item2) => selectedItems.includes(item2)) : false;
946
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
947
+ MenuItem,
948
+ {
949
+ ...getItemProps({ index }),
950
+ $highlighted: highlightedIndex === index,
951
+ $active: false,
952
+ inputType,
953
+ selected: isItemSelected2,
954
+ id: toggleItem.id,
955
+ children: toggleItem.label
956
+ },
957
+ index
958
+ );
959
+ }
960
+ const dataItem = item;
961
+ const isItemSelected = selectedItems.includes(dataItem);
962
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
963
+ MenuItem,
964
+ {
965
+ ...getItemProps({ index }),
966
+ $highlighted: highlightedIndex === index,
967
+ $active: false,
968
+ inputType,
969
+ selected: isItemSelected,
970
+ id: itemToKey(dataItem),
971
+ children: renderItem(dataItem)
972
+ },
973
+ index
974
+ );
975
+ })
976
+ }
977
+ ) });
978
+ };
979
+ var GroupedComboboxContent = ({
980
+ items,
981
+ getMenuProps,
982
+ getItemProps,
983
+ highlightedIndex,
984
+ selectedItems,
985
+ renderItem,
986
+ renderGroupHeading,
987
+ EmptyState,
988
+ itemToKey,
989
+ itemToString,
990
+ inputType,
991
+ onHeadingClick,
992
+ groupBy,
993
+ allData,
994
+ selectAllItem,
995
+ placeholderItem,
996
+ ...rest
997
+ }) => {
998
+ const hasItems = items.some((item) => !isGroupHeading(item));
999
+ const menuProps = getMenuProps();
1000
+ const groupedItems = groupItems(
1001
+ items,
1002
+ groupBy,
1003
+ allData
1004
+ );
1005
+ let actualItemIndex = placeholderItem ? 1 : 0;
1006
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ...menuProps, ...rest, children: !hasItems && EmptyState ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { padding: "16px" }, children: EmptyState }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(StyledMenuContent, { style: { position: "relative" }, children: [
1007
+ placeholderItem && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1008
+ MenuItem,
1009
+ {
1010
+ ...getItemProps({ index: 0 }),
1011
+ $highlighted: highlightedIndex === 0,
1012
+ $active: false,
1013
+ inputType,
1014
+ selected: selectedItems.length === 0,
1015
+ id: placeholderItem.id,
1016
+ "data-item-index": 0,
1017
+ children: placeholderItem.label
1018
+ },
1019
+ "placeholder-item"
1020
+ ),
1021
+ Array.from(groupedItems.keys()).map((group, groupIndex) => {
1022
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1023
+ MenuGroup,
1024
+ {
1025
+ id: `menu-group-${group}`,
1026
+ title: renderGroupHeading ? renderGroupHeading(group) : group,
1027
+ children: groupedItems.get(group)?.map((item) => {
1028
+ const isItemSelected = selectedItems.includes(item);
1029
+ const itemIndex = actualItemIndex;
1030
+ actualItemIndex += 1;
1031
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1032
+ MenuItem,
1033
+ {
1034
+ ...getItemProps({ index: itemIndex }),
1035
+ $highlighted: highlightedIndex === itemIndex,
1036
+ $active: false,
1037
+ inputType,
1038
+ selected: isItemSelected,
1039
+ id: itemToKey(item),
1040
+ "data-item-index": itemIndex,
1041
+ children: renderItem(item)
1042
+ },
1043
+ itemIndex
1044
+ );
1045
+ })
1046
+ },
1047
+ groupIndex
1048
+ );
1049
+ })
1050
+ ] }) });
1051
+ };
1052
+ var ComboboxContent = ({
1053
+ isVirtualized = false,
1054
+ groupBy,
1055
+ selectHeadings = false,
1056
+ ...props
1057
+ }) => {
1058
+ if (isVirtualized) {
1059
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1060
+ VirtualizedComboboxContent,
1061
+ {
1062
+ groupBy,
1063
+ selectHeadings,
1064
+ ...props
1065
+ }
1066
+ );
1067
+ }
1068
+ if (groupBy && !selectHeadings) {
1069
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1070
+ GroupedComboboxContent,
1071
+ {
1072
+ groupBy,
1073
+ selectHeadings,
1074
+ ...props
1075
+ }
1076
+ );
1077
+ }
1078
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1079
+ NormalComboboxContent,
1080
+ {
1081
+ selectHeadings,
1082
+ groupBy,
1083
+ ...props
1084
+ }
1085
+ );
1086
+ };
1087
+
1088
+ // src/v2/Select/SingleSelect.tsx
1089
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1090
+ function defaultReducer(state, actionAndChanges) {
1091
+ const { changes, type } = actionAndChanges;
1092
+ switch (type) {
1093
+ case import_downshift.useSelect.stateChangeTypes.ItemClick:
1094
+ return {
1095
+ ...changes,
1096
+ isOpen: false,
1097
+ // close the menu after selection for single select
1098
+ highlightedIndex: 0
1099
+ // reset highlight
1100
+ };
1101
+ default:
1102
+ return changes;
1103
+ }
1104
+ }
1105
+ function SingleSelect({
1106
+ id,
1107
+ data,
1108
+ selectedItemId: controlledSelectedItemId,
1109
+ isOpen: controlledIsOpen,
1110
+ itemToKey = (item) => item?.id,
1111
+ itemToString,
1112
+ itemToSelection,
1113
+ renderSelection,
1114
+ renderItem,
1115
+ groupBy,
1116
+ renderGroupHeading,
1117
+ isVirtualized = false,
1118
+ placeholder,
1119
+ onSelectedItemIdChange,
1120
+ onIsOpenChange,
1121
+ stateReducer = defaultReducer,
1122
+ triggerButtonProps,
1123
+ menuProps,
1124
+ inputType = "icon",
1125
+ removePlaceholderItem = false
1126
+ }) {
1127
+ const [uncontrolledSelectedItemId, setUncontrolledSelectedItemId] = (0, import_react8.useState)(null);
1128
+ const [uncontrolledIsOpen, setUncontrolledIsOpen] = (0, import_react8.useState)(false);
1129
+ const isSelectedItemIdControlled = controlledSelectedItemId !== void 0;
1130
+ const selectedItemId = isSelectedItemIdControlled ? controlledSelectedItemId : uncontrolledSelectedItemId;
1131
+ const selectedItem = (0, import_react8.useMemo)(() => {
1132
+ if (selectedItemId === null || selectedItemId === void 0) {
1133
+ return null;
1134
+ }
1135
+ return data.find((item) => itemToKey(item) === selectedItemId) ?? null;
1136
+ }, [selectedItemId, data, itemToKey]);
1137
+ const isIsOpenControlled = controlledIsOpen !== void 0;
1138
+ const isOpen = isIsOpenControlled ? controlledIsOpen : uncontrolledIsOpen;
1139
+ const updateSelectedItem = (newSelectedItem) => {
1140
+ const newSelectedItemId = newSelectedItem ? itemToKey(newSelectedItem) : null;
1141
+ if (!isSelectedItemIdControlled) {
1142
+ setUncontrolledSelectedItemId(newSelectedItemId);
1143
+ }
1144
+ onSelectedItemIdChange?.(newSelectedItemId);
1145
+ };
1146
+ const updateIsOpen = (newIsOpen) => {
1147
+ if (!isIsOpenControlled) {
1148
+ setUncontrolledIsOpen(newIsOpen);
1149
+ }
1150
+ onIsOpenChange?.(newIsOpen);
1151
+ };
1152
+ const items = (0, import_react8.useMemo)(() => {
1153
+ let groupedItems;
1154
+ const placeholderItem = {
1155
+ id: "clear-selection",
1156
+ label: placeholder
1157
+ };
1158
+ if (groupBy) {
1159
+ groupedItems = groupItemsWithHeadings(data, groupBy, data, true);
1160
+ } else {
1161
+ groupedItems = data;
1162
+ }
1163
+ if (!removePlaceholderItem) {
1164
+ groupedItems = [placeholderItem, ...groupedItems];
1165
+ }
1166
+ return groupedItems;
1167
+ }, [data, groupBy, placeholder]);
1168
+ const itemsForSelect = (0, import_react8.useMemo)(() => {
1169
+ return items.filter((item) => !isGroupHeading(item));
1170
+ }, [items]);
1171
+ const itemToStringForDownshift = (0, import_react8.useMemo)(
1172
+ () => createItemToStringForDownshift(itemToString),
1173
+ [itemToString]
1174
+ );
1175
+ const selectProps = (0, import_downshift.useSelect)({
1176
+ toggleButtonId: id,
1177
+ items: itemsForSelect,
1178
+ itemToString: itemToStringForDownshift,
1179
+ // defaultHighlightedIndex: 0,
1180
+ selectedItem,
1181
+ isOpen,
1182
+ stateReducer,
1183
+ onStateChange({ type, selectedItem: newSelectedItem, isOpen: newIsOpen }) {
1184
+ if (newIsOpen !== void 0) {
1185
+ updateIsOpen(newIsOpen);
1186
+ }
1187
+ const isSelectionEvent = type === import_downshift.useSelect.stateChangeTypes.ItemClick || type === import_downshift.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter;
1188
+ if (isSelectionEvent && newSelectedItem && newSelectedItem !== null) {
1189
+ if (newSelectedItem.id === "clear-selection") {
1190
+ updateSelectedItem(null);
1191
+ } else {
1192
+ updateSelectedItem(newSelectedItem);
1193
+ }
1194
+ }
1195
+ }
1196
+ });
1197
+ const {
1198
+ isOpen: selectIsOpen,
1199
+ getToggleButtonProps,
1200
+ getLabelProps,
1201
+ getMenuProps,
1202
+ highlightedIndex: selectHighlightedIndex,
1203
+ getItemProps
1204
+ } = selectProps;
1205
+ const highlightedIndex = useHighlightedIndex(
1206
+ items,
1207
+ itemsForSelect,
1208
+ selectHighlightedIndex,
1209
+ !!groupBy,
1210
+ false
1211
+ // Single select components hardcode selectHeadings to false
1212
+ );
1213
+ const buttonContent = renderSelection ? renderSelection(selectedItem) : selectedItem ? itemToSelection ? itemToSelection(selectedItem) : itemToString(selectedItem) : placeholder;
1214
+ const toggleButtonProps = getToggleButtonProps();
1215
+ toggleButtonProps["aria-labelledby"] = void 0;
1216
+ if (!selectIsOpen) {
1217
+ toggleButtonProps["aria-controls"] = void 0;
1218
+ }
1219
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1220
+ Popout,
1221
+ {
1222
+ open: selectIsOpen,
1223
+ onOpenChange: updateIsOpen,
1224
+ animationConfig: menuAnimationConfig,
1225
+ onOpenAutoFocus: (e) => {
1226
+ e.preventDefault();
1227
+ },
1228
+ onCloseAutoFocus: (e) => {
1229
+ e.preventDefault();
1230
+ },
1231
+ content: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1232
+ ComboboxContent,
1233
+ {
1234
+ items,
1235
+ getMenuProps,
1236
+ getItemProps: (props) => {
1237
+ const item = items[props.index];
1238
+ if (isToggleItem(item)) {
1239
+ return {
1240
+ onClick: () => {
1241
+ if (item.id === "clear-selection") {
1242
+ updateSelectedItem(null);
1243
+ }
1244
+ }
1245
+ };
1246
+ }
1247
+ const dataItem = item;
1248
+ const itemIndex = itemsForSelect.indexOf(dataItem);
1249
+ if (itemIndex === -1) {
1250
+ return {};
1251
+ }
1252
+ return getItemProps({ item: dataItem, index: itemIndex });
1253
+ },
1254
+ selectedItems: selectedItem ? [selectedItem] : [],
1255
+ highlightedIndex: highlightedIndex ?? -1,
1256
+ renderItem,
1257
+ renderGroupHeading,
1258
+ itemToKey,
1259
+ itemToString,
1260
+ inputType,
1261
+ isVirtualized,
1262
+ groupBy,
1263
+ selectHeadings: false,
1264
+ ...menuProps
1265
+ }
1266
+ ),
1267
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1268
+ SelectToggleButton,
1269
+ {
1270
+ ...toggleButtonProps,
1271
+ ...triggerButtonProps,
1272
+ isOpen: selectIsOpen,
1273
+ children: buttonContent
1274
+ }
1275
+ )
1276
+ }
1277
+ );
1278
+ }
1279
+
1280
+ // src/v2/Select/MultiSelect.tsx
1281
+ var import_react9 = require("react");
1282
+ var import_downshift2 = require("downshift");
1283
+ var import_seeds_react_label2 = require("@sproutsocial/seeds-react-label");
1284
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1285
+ function defaultReducer2(state, actionAndChanges) {
1286
+ const { changes, type } = actionAndChanges;
1287
+ switch (type) {
1288
+ case import_downshift2.useSelect.stateChangeTypes.ItemClick:
1289
+ return {
1290
+ ...changes,
1291
+ isOpen: true,
1292
+ // keep the menu open after selection.
1293
+ highlightedIndex: 0
1294
+ // with the first option highlighted.
1295
+ };
1296
+ default:
1297
+ if (changes.selectedItem && changes.isOpen === false) {
1298
+ return {
1299
+ ...changes,
1300
+ isOpen: true,
1301
+ // keep the menu open after keyboard selection.
1302
+ highlightedIndex: 0
1303
+ // with the first option highlighted.
1304
+ };
1305
+ }
1306
+ return changes;
1307
+ }
1308
+ }
1309
+ function MultiSelect({
1310
+ id,
1311
+ data,
1312
+ selectedItemIds: controlledSelectedItemIds,
1313
+ isOpen: controlledIsOpen,
1314
+ itemToKey = (item) => item?.id,
1315
+ itemToString,
1316
+ renderSelections,
1317
+ renderItem,
1318
+ groupBy,
1319
+ renderGroupHeading,
1320
+ isVirtualized = false,
1321
+ showSelectedItems = false,
1322
+ selectHeadings = false,
1323
+ selectAllItem,
1324
+ placeholder,
1325
+ onSelectedItemIdsChange,
1326
+ onIsOpenChange,
1327
+ stateReducer = defaultReducer2,
1328
+ triggerButtonProps,
1329
+ menuProps,
1330
+ inputType = "checkbox",
1331
+ shouldOverflow
1332
+ }) {
1333
+ const [uncontrolledSelectedItemIds, setUncontrolledSelectedItemIds] = (0, import_react9.useState)([]);
1334
+ const [uncontrolledIsOpen, setUncontrolledIsOpen] = (0, import_react9.useState)(false);
1335
+ const isSelectedItemIdsControlled = controlledSelectedItemIds !== void 0;
1336
+ const selectedItemIds = isSelectedItemIdsControlled ? controlledSelectedItemIds : uncontrolledSelectedItemIds;
1337
+ const selectedItems = (0, import_react9.useMemo)(() => {
1338
+ return data.filter((item) => selectedItemIds.includes(itemToKey(item)));
1339
+ }, [selectedItemIds, data, itemToKey]);
1340
+ const isIsOpenControlled = controlledIsOpen !== void 0;
1341
+ const isOpen = isIsOpenControlled ? controlledIsOpen : uncontrolledIsOpen;
1342
+ const updateSelectedItems = (newSelectedItems) => {
1343
+ const newSelectedItemIds = newSelectedItems.map((item) => itemToKey(item));
1344
+ if (!isSelectedItemIdsControlled) {
1345
+ setUncontrolledSelectedItemIds(newSelectedItemIds);
1346
+ }
1347
+ onSelectedItemIdsChange?.(newSelectedItemIds);
1348
+ };
1349
+ const updateIsOpen = (newIsOpen) => {
1350
+ if (!isIsOpenControlled) {
1351
+ setUncontrolledIsOpen(newIsOpen);
1352
+ }
1353
+ onIsOpenChange?.(newIsOpen);
1354
+ };
1355
+ const filteredData = (0, import_react9.useMemo)(() => {
1356
+ if (showSelectedItems) {
1357
+ return data;
1358
+ }
1359
+ return data.filter((item) => !selectedItems.includes(item));
1360
+ }, [data, selectedItems, showSelectedItems]);
1361
+ const items = (0, import_react9.useMemo)(() => {
1362
+ let groupedItems;
1363
+ if (groupBy) {
1364
+ groupedItems = groupItemsWithHeadings(filteredData, groupBy, data, true);
1365
+ } else {
1366
+ groupedItems = filteredData;
1367
+ }
1368
+ if (selectAllItem) {
1369
+ return [selectAllItem, ...groupedItems];
1370
+ }
1371
+ return groupedItems;
1372
+ }, [filteredData, groupBy, data, selectAllItem, selectHeadings]);
1373
+ const handleHeadingClick = (0, import_react9.useMemo)(() => {
1374
+ if (!selectHeadings || !groupBy) {
1375
+ return void 0;
1376
+ }
1377
+ return (groupLabel, allSelected) => {
1378
+ const groupItems2 = data.filter((item) => groupBy(item) === groupLabel);
1379
+ if (allSelected) {
1380
+ const newSelectedItems = selectedItems.filter(
1381
+ (item) => !groupItems2.includes(item)
1382
+ );
1383
+ updateSelectedItems(newSelectedItems);
1384
+ } else {
1385
+ const newSelectedItems = [...selectedItems];
1386
+ for (const groupItem of groupItems2) {
1387
+ if (!newSelectedItems.includes(groupItem)) {
1388
+ newSelectedItems.push(groupItem);
1389
+ }
1390
+ }
1391
+ updateSelectedItems(newSelectedItems);
1392
+ }
1393
+ };
1394
+ }, [selectHeadings, groupBy, data, selectedItems, updateSelectedItems]);
1395
+ const { getSelectedItemProps, getDropdownProps, removeSelectedItem } = (0, import_downshift2.useMultipleSelection)({
1396
+ selectedItems,
1397
+ onStateChange({ selectedItems: newSelectedItems, type }) {
1398
+ switch (type) {
1399
+ case import_downshift2.useMultipleSelection.stateChangeTypes.SelectedItemKeyDownBackspace:
1400
+ case import_downshift2.useMultipleSelection.stateChangeTypes.SelectedItemKeyDownDelete:
1401
+ case import_downshift2.useMultipleSelection.stateChangeTypes.DropdownKeyDownBackspace:
1402
+ case import_downshift2.useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem:
1403
+ if (newSelectedItems !== void 0) {
1404
+ updateSelectedItems(newSelectedItems);
1405
+ }
1406
+ break;
1407
+ default:
1408
+ break;
1409
+ }
1410
+ }
1411
+ });
1412
+ const itemsForSelect = (0, import_react9.useMemo)(() => {
1413
+ if (selectHeadings) {
1414
+ return items;
1415
+ }
1416
+ return items.filter(
1417
+ (item) => !isGroupHeading(item)
1418
+ );
1419
+ }, [items, selectHeadings]);
1420
+ const itemToStringForDownshift = (0, import_react9.useMemo)(
1421
+ () => createItemToStringForDownshift(itemToString),
1422
+ [itemToString]
1423
+ );
1424
+ const selectProps = (0, import_downshift2.useSelect)({
1425
+ toggleButtonId: id,
1426
+ items: itemsForSelect,
1427
+ itemToString: itemToStringForDownshift,
1428
+ // defaultHighlightedIndex: 0, // after selection, highlight the first item.
1429
+ selectedItem: null,
1430
+ isOpen,
1431
+ stateReducer,
1432
+ // Could maybe let devs override this too?
1433
+ onStateChange({ type, selectedItem: newSelectedItem, isOpen: newIsOpen }) {
1434
+ if (newIsOpen !== void 0) {
1435
+ updateIsOpen(newIsOpen);
1436
+ }
1437
+ if (newSelectedItem && newSelectedItem !== null) {
1438
+ const isSelectionEvent = type === import_downshift2.useSelect.stateChangeTypes.ItemClick || type === import_downshift2.useSelect.stateChangeTypes.ToggleButtonKeyDownEnter;
1439
+ if (isSelectionEvent) {
1440
+ if (selectAllItem && isToggleItem(newSelectedItem) && newSelectedItem.id === selectAllItem.id) {
1441
+ const allSelected = data.length > 0 && data.every((item) => selectedItems.includes(item));
1442
+ if (allSelected) {
1443
+ updateSelectedItems([]);
1444
+ } else {
1445
+ updateSelectedItems([...data]);
1446
+ }
1447
+ } else if (selectHeadings && groupBy && isGroupHeading(newSelectedItem)) {
1448
+ const groupLabel = newSelectedItem.label;
1449
+ const groupItems2 = data.filter(
1450
+ (item) => groupBy(item) === groupLabel
1451
+ );
1452
+ const allSelected = groupItems2.length > 0 && groupItems2.every((item) => selectedItems.includes(item));
1453
+ if (allSelected) {
1454
+ updateSelectedItems(
1455
+ selectedItems.filter((item) => !groupItems2.includes(item))
1456
+ );
1457
+ } else {
1458
+ const newItems = [
1459
+ ...selectedItems.filter((item) => !groupItems2.includes(item)),
1460
+ ...groupItems2
1461
+ ];
1462
+ updateSelectedItems(newItems);
1463
+ }
1464
+ } else if (!isGroupHeading(newSelectedItem) && !isToggleItem(newSelectedItem)) {
1465
+ const itemIndex = selectedItems.findIndex(
1466
+ (item) => itemToKey(item) === itemToKey(newSelectedItem)
1467
+ );
1468
+ if (itemIndex >= 0) {
1469
+ updateSelectedItems(
1470
+ selectedItems.filter((_, index) => index !== itemIndex)
1471
+ );
1472
+ } else {
1473
+ updateSelectedItems([...selectedItems, newSelectedItem]);
1474
+ }
1475
+ }
1476
+ }
1477
+ }
1478
+ }
1479
+ });
1480
+ const {
1481
+ isOpen: selectIsOpen,
1482
+ getToggleButtonProps,
1483
+ getLabelProps,
1484
+ getMenuProps,
1485
+ highlightedIndex: selectHighlightedIndex,
1486
+ getItemProps
1487
+ } = selectProps;
1488
+ const highlightedIndex = useHighlightedIndex(
1489
+ items,
1490
+ itemsForSelect,
1491
+ selectHighlightedIndex,
1492
+ !!groupBy,
1493
+ selectHeadings ?? false
1494
+ );
1495
+ const buttonText = renderSelections ? renderSelections(selectedItems) : selectedItems.length > 0 ? selectedItems.map((item) => itemToString(item)).join(", ") : placeholder;
1496
+ const toggleButtonIdProps = getToggleButtonProps();
1497
+ toggleButtonIdProps["aria-labelledby"] = void 0;
1498
+ if (!selectIsOpen) {
1499
+ toggleButtonIdProps["aria-controls"] = void 0;
1500
+ }
1501
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1502
+ Popout,
1503
+ {
1504
+ open: selectIsOpen,
1505
+ onOpenChange: updateIsOpen,
1506
+ onOpenAutoFocus: (e) => {
1507
+ e.preventDefault();
1508
+ },
1509
+ onCloseAutoFocus: (e) => {
1510
+ e.preventDefault();
1511
+ },
1512
+ animationConfig: menuAnimationConfig,
1513
+ content: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1514
+ ComboboxContent,
1515
+ {
1516
+ items,
1517
+ getMenuProps,
1518
+ getItemProps: (props) => {
1519
+ const item = items[props.index];
1520
+ if (isToggleItem(item)) {
1521
+ return {
1522
+ onClick: () => {
1523
+ const allSelected = data.length > 0 && data.every((item2) => selectedItems.includes(item2));
1524
+ if (allSelected) {
1525
+ updateSelectedItems([]);
1526
+ } else {
1527
+ updateSelectedItems([...data]);
1528
+ }
1529
+ }
1530
+ };
1531
+ }
1532
+ const dataItem = item;
1533
+ const itemIndex = itemsForSelect.indexOf(dataItem);
1534
+ if (itemIndex === -1) {
1535
+ return {};
1536
+ }
1537
+ return getItemProps({ item: dataItem, index: itemIndex });
1538
+ },
1539
+ selectedItems,
1540
+ highlightedIndex: highlightedIndex ?? -1,
1541
+ renderItem,
1542
+ renderGroupHeading,
1543
+ itemToKey,
1544
+ itemToString,
1545
+ inputType,
1546
+ selectHeadings,
1547
+ onHeadingClick: handleHeadingClick,
1548
+ groupBy,
1549
+ allData: data,
1550
+ selectAllItem,
1551
+ isVirtualized,
1552
+ ...menuProps
1553
+ }
1554
+ ),
1555
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1556
+ SelectToggleButton,
1557
+ {
1558
+ ...toggleButtonIdProps,
1559
+ ...triggerButtonProps,
1560
+ isOpen: selectIsOpen,
1561
+ shouldOverflow,
1562
+ children: buttonText
1563
+ }
1564
+ )
1565
+ }
1566
+ );
1567
+ }
1568
+
1569
+ // src/v2/Autocomplete/SingleAutocomplete.tsx
1570
+ var import_react10 = require("react");
1571
+ var import_downshift3 = require("downshift");
1572
+ var import_seeds_react_label3 = require("@sproutsocial/seeds-react-label");
1573
+ var import_seeds_react_input = require("@sproutsocial/seeds-react-input");
1574
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1575
+ function defaultReducer3(state, actionAndChanges) {
1576
+ const { changes, type } = actionAndChanges;
1577
+ switch (type) {
1578
+ case import_downshift3.useCombobox.stateChangeTypes.InputKeyDownEnter:
1579
+ case import_downshift3.useCombobox.stateChangeTypes.ItemClick:
1580
+ return {
1581
+ ...changes,
1582
+ isOpen: false,
1583
+ // close the menu after selection for single select
1584
+ highlightedIndex: 0
1585
+ // reset highlight
1586
+ };
1587
+ default:
1588
+ return changes;
1589
+ }
1590
+ }
1591
+ function SingleAutocomplete({
1592
+ id,
1593
+ data,
1594
+ selectedItemId: controlledSelectedItemId,
1595
+ inputValue: controlledInputValue,
1596
+ isOpen: controlledIsOpen,
1597
+ itemToKey = (item) => item?.id,
1598
+ itemToString,
1599
+ itemToSearchString,
1600
+ renderItem,
1601
+ groupBy,
1602
+ renderGroupHeading,
1603
+ isVirtualized = false,
1604
+ EmptyState,
1605
+ placeholder,
1606
+ onSelectedItemIdChange,
1607
+ onInputValueChange,
1608
+ onIsOpenChange,
1609
+ stateReducer = defaultReducer3,
1610
+ menuProps,
1611
+ inputType = "icon",
1612
+ includePlaceholderItem = false
1613
+ }) {
1614
+ const [uncontrolledInputValue, setUncontrolledInputValue] = (0, import_react10.useState)("");
1615
+ const [uncontrolledSelectedItemId, setUncontrolledSelectedItemId] = (0, import_react10.useState)(null);
1616
+ const [uncontrolledIsOpen, setUncontrolledIsOpen] = (0, import_react10.useState)(false);
1617
+ const isSelectedItemIdControlled = controlledSelectedItemId !== void 0;
1618
+ const selectedItemId = isSelectedItemIdControlled ? controlledSelectedItemId : uncontrolledSelectedItemId;
1619
+ const selectedItem = (0, import_react10.useMemo)(() => {
1620
+ if (selectedItemId === null || selectedItemId === void 0) {
1621
+ return null;
1622
+ }
1623
+ return data.find((item) => itemToKey(item) === selectedItemId) ?? null;
1624
+ }, [selectedItemId, data, itemToKey]);
1625
+ const isInputValueControlled = controlledInputValue !== void 0;
1626
+ const inputValue = isInputValueControlled ? controlledInputValue : uncontrolledInputValue;
1627
+ const isIsOpenControlled = controlledIsOpen !== void 0;
1628
+ const isOpen = isIsOpenControlled ? controlledIsOpen : uncontrolledIsOpen;
1629
+ (0, import_react10.useEffect)(() => {
1630
+ if (selectedItem && !isOpen) {
1631
+ const selectedItemString = itemToString(selectedItem);
1632
+ if (!isInputValueControlled && uncontrolledInputValue !== selectedItemString) {
1633
+ setUncontrolledInputValue(selectedItemString);
1634
+ } else if (isInputValueControlled && inputValue !== selectedItemString) {
1635
+ updateInputValue(selectedItemString);
1636
+ }
1637
+ }
1638
+ }, [
1639
+ selectedItem,
1640
+ isOpen,
1641
+ isInputValueControlled,
1642
+ itemToString,
1643
+ uncontrolledInputValue
1644
+ ]);
1645
+ const updateSelectedItem = (newSelectedItem) => {
1646
+ const newSelectedItemId = newSelectedItem ? itemToKey(newSelectedItem) : null;
1647
+ if (!isSelectedItemIdControlled) {
1648
+ setUncontrolledSelectedItemId(newSelectedItemId);
1649
+ }
1650
+ onSelectedItemIdChange?.(newSelectedItemId);
1651
+ };
1652
+ const updateInputValue = (newInputValue) => {
1653
+ if (!isInputValueControlled) {
1654
+ setUncontrolledInputValue(newInputValue);
1655
+ }
1656
+ onInputValueChange?.(newInputValue);
1657
+ };
1658
+ const updateIsOpen = (newIsOpen) => {
1659
+ if (!isIsOpenControlled) {
1660
+ setUncontrolledIsOpen(newIsOpen);
1661
+ }
1662
+ onIsOpenChange?.(newIsOpen);
1663
+ };
1664
+ const searchStringFn = itemToSearchString ?? ((item) => itemToString(item));
1665
+ const filteredItems = (0, import_react10.useMemo)(
1666
+ () => getFilteredItems(data, inputValue, searchStringFn, itemToString, {
1667
+ selectedItem
1668
+ }),
1669
+ [data, selectedItem, inputValue, searchStringFn, itemToString]
1670
+ );
1671
+ const placeholderItem = {
1672
+ id: "clear-selection",
1673
+ label: placeholder
1674
+ };
1675
+ const items = (0, import_react10.useMemo)(() => {
1676
+ let groupedItems;
1677
+ if (groupBy) {
1678
+ groupedItems = groupItemsWithHeadings(
1679
+ filteredItems,
1680
+ groupBy,
1681
+ data,
1682
+ isVirtualized
1683
+ );
1684
+ } else {
1685
+ groupedItems = filteredItems;
1686
+ }
1687
+ groupedItems = includePlaceholderItem ? [placeholderItem, ...groupedItems] : groupedItems;
1688
+ return groupedItems;
1689
+ }, [
1690
+ filteredItems,
1691
+ placeholder,
1692
+ groupBy,
1693
+ data,
1694
+ includePlaceholderItem,
1695
+ isVirtualized
1696
+ ]);
1697
+ const itemsForCombobox = (0, import_react10.useMemo)(() => {
1698
+ return items.filter(
1699
+ (item) => !isGroupHeading(item)
1700
+ );
1701
+ }, [items]);
1702
+ const itemToStringForDownshift = (0, import_react10.useMemo)(
1703
+ () => createItemToStringForDownshift(itemToString),
1704
+ [itemToString]
1705
+ );
1706
+ const comboboxProps = (0, import_downshift3.useCombobox)({
1707
+ inputId: id,
1708
+ items: itemsForCombobox,
1709
+ itemToString: itemToStringForDownshift,
1710
+ defaultHighlightedIndex: 0,
1711
+ selectedItem,
1712
+ inputValue,
1713
+ isOpen,
1714
+ stateReducer,
1715
+ onStateChange({
1716
+ inputValue: newInputValue,
1717
+ type,
1718
+ selectedItem: newSelectedItem,
1719
+ isOpen: newIsOpen
1720
+ }) {
1721
+ if (newIsOpen !== void 0 && type !== import_downshift3.useCombobox.stateChangeTypes.InputBlur) {
1722
+ updateIsOpen(newIsOpen);
1723
+ }
1724
+ switch (type) {
1725
+ case import_downshift3.useCombobox.stateChangeTypes.InputKeyDownEnter:
1726
+ case import_downshift3.useCombobox.stateChangeTypes.ItemClick:
1727
+ if (newSelectedItem) {
1728
+ updateSelectedItem(newSelectedItem);
1729
+ if (newSelectedItem.id === "clear-selection") {
1730
+ updateInputValue("");
1731
+ return;
1732
+ }
1733
+ updateInputValue(itemToString(newSelectedItem));
1734
+ }
1735
+ break;
1736
+ case import_downshift3.useCombobox.stateChangeTypes.InputChange:
1737
+ updateInputValue(newInputValue ?? "");
1738
+ if (newInputValue === "" && selectedItem && !isInputValueControlled) {
1739
+ updateSelectedItem(null);
1740
+ }
1741
+ break;
1742
+ default:
1743
+ break;
1744
+ }
1745
+ }
1746
+ });
1747
+ const {
1748
+ isOpen: comboboxIsOpen,
1749
+ getToggleButtonProps,
1750
+ getLabelProps,
1751
+ getMenuProps,
1752
+ getInputProps,
1753
+ highlightedIndex: comboboxHighlightedIndex,
1754
+ getItemProps,
1755
+ selectedItem: comboboxSelectedItem
1756
+ } = comboboxProps;
1757
+ const highlightedIndex = useHighlightedIndex(
1758
+ items,
1759
+ itemsForCombobox,
1760
+ comboboxHighlightedIndex,
1761
+ !!groupBy,
1762
+ false
1763
+ // Single select components hardcode selectHeadings to false
1764
+ );
1765
+ const inputProps = getInputProps();
1766
+ inputProps["aria-labelledby"] = void 0;
1767
+ if (!comboboxIsOpen) {
1768
+ inputProps["aria-controls"] = void 0;
1769
+ }
1770
+ const { ref, id: inputId, ...restProps } = inputProps;
1771
+ const handleBlur = (e) => {
1772
+ if (inputProps.onBlur) {
1773
+ inputProps.onBlur(e);
1774
+ }
1775
+ updateIsOpen(false);
1776
+ };
1777
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1778
+ Popout,
1779
+ {
1780
+ open: comboboxIsOpen,
1781
+ onOpenChange: updateIsOpen,
1782
+ animationConfig: menuAnimationConfig,
1783
+ onOpenAutoFocus: (e) => {
1784
+ e.preventDefault();
1785
+ },
1786
+ onCloseAutoFocus: (e) => {
1787
+ e.preventDefault();
1788
+ },
1789
+ content: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1790
+ ComboboxContent,
1791
+ {
1792
+ items,
1793
+ getMenuProps,
1794
+ getItemProps: (props) => {
1795
+ const item = items[props.index];
1796
+ const dataItem = item;
1797
+ const itemIndex = itemsForCombobox.indexOf(dataItem);
1798
+ if (itemIndex === -1) {
1799
+ return {};
1800
+ }
1801
+ return getItemProps({ item: dataItem, index: itemIndex });
1802
+ },
1803
+ selectedItems: selectedItem ? [selectedItem] : [],
1804
+ highlightedIndex: highlightedIndex ?? -1,
1805
+ renderItem,
1806
+ renderGroupHeading,
1807
+ EmptyState,
1808
+ itemToKey,
1809
+ itemToString,
1810
+ inputType,
1811
+ selectHeadings: false,
1812
+ groupBy,
1813
+ isVirtualized,
1814
+ placeholderItem: includePlaceholderItem ? placeholderItem : void 0,
1815
+ ...menuProps
1816
+ }
1817
+ ),
1818
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1819
+ import_seeds_react_input.Input,
1820
+ {
1821
+ id,
1822
+ inputProps: {
1823
+ ...restProps,
1824
+ autoComplete: "off",
1825
+ onBlur: handleBlur
1826
+ },
1827
+ innerRef: ref,
1828
+ placeholder,
1829
+ elemAfter: !includePlaceholderItem ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_seeds_react_input.Input.ClearButton, {}) : void 0,
1830
+ clearButtonLabel: "Clear selection",
1831
+ onClear: () => {
1832
+ updateSelectedItem(null);
1833
+ updateInputValue("");
1834
+ },
1835
+ ...restProps,
1836
+ onBlur: handleBlur
1837
+ }
1838
+ )
1839
+ }
1840
+ );
1841
+ }
1842
+
1843
+ // src/v2/Autocomplete/MultiAutocomplete.tsx
1844
+ var import_react11 = require("react");
1845
+ var import_downshift4 = require("downshift");
1846
+ var import_seeds_react_label4 = require("@sproutsocial/seeds-react-label");
1847
+ var import_seeds_react_token_input = require("@sproutsocial/seeds-react-token-input");
1848
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1849
+ function defaultReducer4(state, actionAndChanges) {
1850
+ const { changes, type } = actionAndChanges;
1851
+ switch (type) {
1852
+ case import_downshift4.useCombobox.stateChangeTypes.InputKeyDownEnter:
1853
+ case import_downshift4.useCombobox.stateChangeTypes.ItemClick:
1854
+ return {
1855
+ ...changes,
1856
+ isOpen: true,
1857
+ // keep the menu open after selection.
1858
+ highlightedIndex: 0
1859
+ // with the first option highlighted.
1860
+ };
1861
+ default:
1862
+ return changes;
1863
+ }
1864
+ }
1865
+ function MultiAutocomplete({
1866
+ id,
1867
+ data,
1868
+ selectedItemIds: controlledSelectedItemIds,
1869
+ inputValue: controlledInputValue,
1870
+ isOpen: controlledIsOpen,
1871
+ itemToKey = (item) => item?.id,
1872
+ itemToString,
1873
+ itemToSearchString,
1874
+ renderItem,
1875
+ groupBy,
1876
+ renderGroupHeading,
1877
+ isVirtualized = false,
1878
+ showSelectedItems = false,
1879
+ selectHeadings = false,
1880
+ selectAllItem,
1881
+ EmptyState,
1882
+ placeholder,
1883
+ onSelectedItemIdsChange,
1884
+ onInputValueChange,
1885
+ onIsOpenChange,
1886
+ stateReducer = defaultReducer4,
1887
+ menuProps,
1888
+ inputType = "checkbox"
1889
+ }) {
1890
+ const [uncontrolledInputValue, setUncontrolledInputValue] = (0, import_react11.useState)("");
1891
+ const [uncontrolledSelectedItemIds, setUncontrolledSelectedItemIds] = (0, import_react11.useState)([]);
1892
+ const [uncontrolledIsOpen, setUncontrolledIsOpen] = (0, import_react11.useState)(false);
1893
+ const isSelectedItemIdsControlled = controlledSelectedItemIds !== void 0;
1894
+ const selectedItemIds = isSelectedItemIdsControlled ? controlledSelectedItemIds : uncontrolledSelectedItemIds;
1895
+ const selectedItems = (0, import_react11.useMemo)(() => {
1896
+ return data.filter((item) => selectedItemIds.includes(itemToKey(item)));
1897
+ }, [selectedItemIds, data, itemToKey]);
1898
+ const isInputValueControlled = controlledInputValue !== void 0;
1899
+ const inputValue = isInputValueControlled ? controlledInputValue : uncontrolledInputValue;
1900
+ const isIsOpenControlled = controlledIsOpen !== void 0;
1901
+ const isOpen = isIsOpenControlled ? controlledIsOpen : uncontrolledIsOpen;
1902
+ const updateSelectedItems = (newSelectedItems) => {
1903
+ const newSelectedItemIds = newSelectedItems.map((item) => itemToKey(item));
1904
+ if (!isSelectedItemIdsControlled) {
1905
+ setUncontrolledSelectedItemIds(newSelectedItemIds);
1906
+ }
1907
+ onSelectedItemIdsChange?.(newSelectedItemIds);
1908
+ };
1909
+ const updateInputValue = (newInputValue) => {
1910
+ if (!isInputValueControlled) {
1911
+ setUncontrolledInputValue(newInputValue);
1912
+ }
1913
+ onInputValueChange?.(newInputValue);
1914
+ };
1915
+ const updateIsOpen = (newIsOpen) => {
1916
+ if (!isIsOpenControlled) {
1917
+ setUncontrolledIsOpen(newIsOpen);
1918
+ }
1919
+ onIsOpenChange?.(newIsOpen);
1920
+ };
1921
+ const searchStringFn = itemToSearchString ?? ((item) => itemToString(item));
1922
+ const filteredItems = (0, import_react11.useMemo)(
1923
+ () => getFilteredItems(data, inputValue, searchStringFn, itemToString, {
1924
+ selectedItems,
1925
+ showSelectedItems
1926
+ }),
1927
+ [data, selectedItems, inputValue, searchStringFn, showSelectedItems]
1928
+ );
1929
+ const items = (0, import_react11.useMemo)(() => {
1930
+ let listItems;
1931
+ if (groupBy) {
1932
+ listItems = groupItemsWithHeadings(
1933
+ filteredItems,
1934
+ groupBy,
1935
+ data,
1936
+ selectHeadings
1937
+ );
1938
+ } else {
1939
+ listItems = filteredItems;
1940
+ }
1941
+ if (selectAllItem) {
1942
+ return [selectAllItem, ...listItems];
1943
+ }
1944
+ return listItems;
1945
+ }, [filteredItems, groupBy, selectAllItem, selectHeadings, data]);
1946
+ const handleHeadingClick = (0, import_react11.useMemo)(() => {
1947
+ if (!selectHeadings || !groupBy) {
1948
+ return void 0;
1949
+ }
1950
+ return (groupLabel, allSelected) => {
1951
+ const groupItems2 = data.filter((item) => groupBy(item) === groupLabel);
1952
+ if (allSelected) {
1953
+ const newSelectedItems = selectedItems.filter(
1954
+ (item) => !groupItems2.includes(item)
1955
+ );
1956
+ updateSelectedItems(newSelectedItems);
1957
+ } else {
1958
+ const newSelectedItems = [...selectedItems];
1959
+ for (const groupItem of groupItems2) {
1960
+ if (!newSelectedItems.includes(groupItem)) {
1961
+ newSelectedItems.push(groupItem);
1962
+ }
1963
+ }
1964
+ updateSelectedItems(newSelectedItems);
1965
+ }
1966
+ };
1967
+ }, [selectHeadings, groupBy, data, selectedItems, updateSelectedItems]);
1968
+ const { getSelectedItemProps, getDropdownProps, removeSelectedItem } = (0, import_downshift4.useMultipleSelection)({
1969
+ selectedItems,
1970
+ onStateChange({ selectedItems: newSelectedItems, type }) {
1971
+ switch (type) {
1972
+ case import_downshift4.useMultipleSelection.stateChangeTypes.SelectedItemKeyDownBackspace:
1973
+ case import_downshift4.useMultipleSelection.stateChangeTypes.SelectedItemKeyDownDelete:
1974
+ case import_downshift4.useMultipleSelection.stateChangeTypes.DropdownKeyDownBackspace:
1975
+ case import_downshift4.useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem:
1976
+ if (newSelectedItems !== void 0) {
1977
+ updateSelectedItems(newSelectedItems);
1978
+ }
1979
+ break;
1980
+ default:
1981
+ break;
1982
+ }
1983
+ }
1984
+ });
1985
+ const itemsForCombobox = (0, import_react11.useMemo)(() => {
1986
+ if (selectHeadings) {
1987
+ return items;
1988
+ }
1989
+ return items.filter(
1990
+ (item) => !isGroupHeading(item)
1991
+ );
1992
+ }, [items, selectHeadings]);
1993
+ const itemToStringForDownshift = (0, import_react11.useMemo)(
1994
+ () => createItemToStringForDownshift(itemToString),
1995
+ [itemToString]
1996
+ );
1997
+ const comboboxProps = (0, import_downshift4.useCombobox)({
1998
+ inputId: id,
1999
+ items: itemsForCombobox,
2000
+ itemToString: itemToStringForDownshift,
2001
+ defaultHighlightedIndex: 0,
2002
+ // after selection, highlight the first item.
2003
+ selectedItem: null,
2004
+ inputValue,
2005
+ isOpen,
2006
+ stateReducer,
2007
+ // Could maybe let devs override this too?
2008
+ onStateChange({
2009
+ inputValue: newInputValue,
2010
+ type,
2011
+ selectedItem: newSelectedItem,
2012
+ isOpen: newIsOpen
2013
+ }) {
2014
+ if (newIsOpen !== void 0) {
2015
+ updateIsOpen(newIsOpen);
2016
+ }
2017
+ switch (type) {
2018
+ case import_downshift4.useCombobox.stateChangeTypes.InputKeyDownEnter:
2019
+ case import_downshift4.useCombobox.stateChangeTypes.ItemClick:
2020
+ if (newSelectedItem) {
2021
+ if (selectAllItem && isToggleItem(newSelectedItem) && newSelectedItem.id === selectAllItem.id) {
2022
+ const allSelected = data.length > 0 && data.every((item) => selectedItems.includes(item));
2023
+ if (allSelected) {
2024
+ updateSelectedItems([]);
2025
+ } else {
2026
+ updateSelectedItems([...data]);
2027
+ }
2028
+ updateInputValue("");
2029
+ } else if (selectHeadings && groupBy && isGroupHeading(newSelectedItem)) {
2030
+ const groupLabel = newSelectedItem.label;
2031
+ const groupItems2 = data.filter(
2032
+ (item) => groupBy(item) === groupLabel
2033
+ );
2034
+ const allSelected = groupItems2.length > 0 && groupItems2.every((item) => selectedItems.includes(item));
2035
+ if (allSelected) {
2036
+ updateSelectedItems(
2037
+ selectedItems.filter((item) => !groupItems2.includes(item))
2038
+ );
2039
+ } else {
2040
+ const newItems = [
2041
+ ...selectedItems.filter((item) => !groupItems2.includes(item)),
2042
+ ...groupItems2
2043
+ ];
2044
+ updateSelectedItems(newItems);
2045
+ }
2046
+ updateInputValue("");
2047
+ } else if (!isGroupHeading(newSelectedItem) && !isToggleItem(newSelectedItem)) {
2048
+ const itemIndex = selectedItems.findIndex(
2049
+ (item) => itemToKey(item) === itemToKey(newSelectedItem)
2050
+ );
2051
+ if (itemIndex >= 0) {
2052
+ updateSelectedItems(
2053
+ selectedItems.filter((_, index) => index !== itemIndex)
2054
+ );
2055
+ } else {
2056
+ updateSelectedItems([...selectedItems, newSelectedItem]);
2057
+ }
2058
+ updateInputValue("");
2059
+ }
2060
+ }
2061
+ break;
2062
+ case import_downshift4.useCombobox.stateChangeTypes.InputChange:
2063
+ updateInputValue(newInputValue ?? "");
2064
+ break;
2065
+ default:
2066
+ break;
2067
+ }
2068
+ }
2069
+ });
2070
+ const {
2071
+ isOpen: comboboxIsOpen,
2072
+ getToggleButtonProps,
2073
+ getLabelProps,
2074
+ getMenuProps,
2075
+ getInputProps,
2076
+ highlightedIndex: comboboxHighlightedIndex,
2077
+ getItemProps,
2078
+ selectedItem
2079
+ } = comboboxProps;
2080
+ const highlightedIndex = useHighlightedIndex(
2081
+ items,
2082
+ itemsForCombobox,
2083
+ comboboxHighlightedIndex,
2084
+ !!groupBy,
2085
+ selectHeadings ?? false
2086
+ );
2087
+ const inputProps = getInputProps({ preventKeyAction: isOpen });
2088
+ inputProps["aria-labelledby"] = void 0;
2089
+ if (!comboboxIsOpen) {
2090
+ inputProps["aria-controls"] = void 0;
2091
+ }
2092
+ const handleBlur = (e) => {
2093
+ if (inputProps.onBlur) {
2094
+ inputProps.onBlur(e);
2095
+ }
2096
+ };
2097
+ const inputPropsToSpread = { ...inputProps };
2098
+ delete inputPropsToSpread.onBlur;
2099
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2100
+ Popout,
2101
+ {
2102
+ open: comboboxIsOpen,
2103
+ onOpenChange: updateIsOpen,
2104
+ onOpenAutoFocus: (e) => {
2105
+ e.preventDefault();
2106
+ },
2107
+ onCloseAutoFocus: (e) => {
2108
+ e.preventDefault();
2109
+ },
2110
+ animationConfig: menuAnimationConfig,
2111
+ content: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2112
+ ComboboxContent,
2113
+ {
2114
+ items,
2115
+ getMenuProps,
2116
+ getItemProps: (props) => {
2117
+ const item = items[props.index];
2118
+ if (isToggleItem(item)) {
2119
+ return {
2120
+ onClick: () => {
2121
+ const allSelected = data.length > 0 && data.every((item2) => selectedItems.includes(item2));
2122
+ if (allSelected) {
2123
+ updateSelectedItems([]);
2124
+ } else {
2125
+ updateSelectedItems([...data]);
2126
+ }
2127
+ }
2128
+ };
2129
+ }
2130
+ const dataItem = item;
2131
+ const itemIndex = itemsForCombobox.indexOf(dataItem);
2132
+ if (itemIndex === -1) {
2133
+ return {};
2134
+ }
2135
+ return getItemProps({ item: dataItem, index: itemIndex });
2136
+ },
2137
+ selectedItems,
2138
+ highlightedIndex: highlightedIndex ?? -1,
2139
+ renderItem,
2140
+ renderGroupHeading,
2141
+ EmptyState,
2142
+ itemToKey,
2143
+ itemToString,
2144
+ inputType,
2145
+ selectHeadings,
2146
+ onHeadingClick: handleHeadingClick,
2147
+ groupBy,
2148
+ allData: data,
2149
+ selectAllItem,
2150
+ isVirtualized,
2151
+ ...menuProps
2152
+ }
2153
+ ),
2154
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2155
+ import_seeds_react_token_input.TokenInput,
2156
+ {
2157
+ placeholder,
2158
+ inputProps: {
2159
+ ...inputPropsToSpread,
2160
+ autoComplete: "off"
2161
+ // Override with "off" to prevent browser autocomplete
2162
+ },
2163
+ tokens: selectedItems.map((item) => ({
2164
+ id: String(itemToKey(item)),
2165
+ value: itemToString(item)
2166
+ })),
2167
+ onRemoveToken: (tokenId) => {
2168
+ const itemToRemove = selectedItems.find(
2169
+ (item) => String(itemToKey(item)) === tokenId
2170
+ );
2171
+ if (itemToRemove) {
2172
+ removeSelectedItem(itemToRemove);
2173
+ }
2174
+ },
2175
+ onClickToken: (e) => {
2176
+ e.stopPropagation();
2177
+ },
2178
+ onBlur: handleBlur
2179
+ }
2180
+ )
2181
+ }
2182
+ );
2183
+ }
2184
+ // Annotate the CommonJS export names for ESM import in node:
2185
+ 0 && (module.exports = {
2186
+ MultiAutocomplete,
2187
+ MultiSelect,
2188
+ SingleAutocomplete,
2189
+ SingleSelect
2190
+ });
2191
+ //# sourceMappingURL=index.js.map