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