@sproutsocial/seeds-react-menu 1.12.3 → 1.15.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +12 -12
- package/CHANGELOG.md +193 -0
- package/dist/esm/v3/index.js +726 -186
- package/dist/esm/v3/index.js.map +1 -1
- package/dist/index.d.mts +22 -22
- package/dist/index.d.ts +22 -22
- package/dist/v3/index.d.mts +199 -50
- package/dist/v3/index.d.ts +199 -50
- package/dist/v3/index.js +732 -185
- package/dist/v3/index.js.map +1 -1
- package/package.json +14 -14
- package/src/v3/ActionMenu.stories.tsx +260 -0
- package/src/v3/ActionMenu.tsx +345 -0
- package/src/v3/ActionMenuStyles.tsx +154 -0
- package/src/v3/Common/ComboboxStyles.tsx +41 -7
- package/src/v3/Common/SelectStyles.tsx +20 -6
- package/src/v3/Common/useSuppressEscapeClear.ts +20 -0
- package/src/v3/MenuButton.stories.tsx +118 -0
- package/src/v3/MenuButton.tsx +68 -0
- package/src/v3/MenuButtonStyles.tsx +38 -0
- package/src/v3/ModalStories.stories.tsx +159 -0
- package/src/v3/MultiCombobox.stories.tsx +157 -0
- package/src/v3/MultiCombobox.tsx +28 -8
- package/src/v3/MultiSearchableSelect.stories.tsx +42 -0
- package/src/v3/MultiSearchableSelect.tsx +11 -6
- package/src/v3/MultiSelect.stories.tsx +40 -0
- package/src/v3/MultiSelect.tsx +12 -3
- package/src/v3/SingleCombobox.stories.tsx +36 -0
- package/src/v3/SingleCombobox.tsx +17 -7
- package/src/v3/SingleSearchableSelect.stories.tsx +38 -0
- package/src/v3/SingleSearchableSelect.tsx +15 -7
- package/src/v3/SingleSelect.stories.tsx +36 -0
- package/src/v3/SingleSelect.tsx +12 -3
- package/src/v3/__tests__/MenuButton.test.tsx +80 -0
- package/src/v3/index.ts +2 -0
package/dist/esm/v3/index.js
CHANGED
|
@@ -134,20 +134,50 @@ function groupItems(data, groupBy) {
|
|
|
134
134
|
|
|
135
135
|
// src/v3/Common/SelectStyles.tsx
|
|
136
136
|
import { Select as Select2 } from "@base-ui/react/select";
|
|
137
|
-
import
|
|
137
|
+
import styled3, { css } from "styled-components";
|
|
138
138
|
import { focusRing } from "@sproutsocial/seeds-react-mixins";
|
|
139
|
-
|
|
139
|
+
|
|
140
|
+
// src/v3/Common/SelectIcons.tsx
|
|
141
|
+
import "react";
|
|
142
|
+
import styled2 from "styled-components";
|
|
143
|
+
import { Icon as Icon2 } from "@sproutsocial/seeds-react-icon";
|
|
144
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
145
|
+
var StyledChevron = styled2.div`
|
|
140
146
|
display: flex;
|
|
147
|
+
align-items: center;
|
|
148
|
+
transition: transform 0.15s;
|
|
149
|
+
${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
|
|
150
|
+
`;
|
|
151
|
+
function ChevronIcon() {
|
|
152
|
+
return /* @__PURE__ */ jsx2(Icon2, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
|
|
153
|
+
}
|
|
154
|
+
function ClearIcon() {
|
|
155
|
+
return /* @__PURE__ */ jsx2(Icon2, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
|
|
156
|
+
}
|
|
157
|
+
function CheckIcon2() {
|
|
158
|
+
return /* @__PURE__ */ jsx2(Icon2, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/v3/Common/SelectStyles.tsx
|
|
162
|
+
var invalidStyles = css`
|
|
163
|
+
border-color: ${({ theme }) => theme.colors.form.border.error};
|
|
164
|
+
|
|
165
|
+
${StyledChevron} {
|
|
166
|
+
color: ${({ theme }) => theme.colors.icon.error};
|
|
167
|
+
}
|
|
168
|
+
`;
|
|
169
|
+
var Field = styled3.div`
|
|
170
|
+
display: ${({ $fullWidth }) => $fullWidth === false ? "inline-flex" : "flex"};
|
|
141
171
|
flex-direction: column;
|
|
142
172
|
gap: ${({ theme }) => theme.space[200]};
|
|
143
|
-
width: 100%;
|
|
173
|
+
${({ $fullWidth }) => $fullWidth !== false && "width: 100%;"}
|
|
144
174
|
`;
|
|
145
|
-
var SelectLabel =
|
|
175
|
+
var SelectLabel = styled3(Select2.Label)`
|
|
146
176
|
font-size: ${({ theme }) => theme.typography[200].fontSize};
|
|
147
177
|
font-weight: ${({ theme }) => theme.fontWeights.semibold};
|
|
148
178
|
color: ${({ theme }) => theme.colors.text.body};
|
|
149
179
|
`;
|
|
150
|
-
var SelectTrigger =
|
|
180
|
+
var SelectTrigger = styled3(Select2.Trigger)`
|
|
151
181
|
display: flex;
|
|
152
182
|
align-items: center;
|
|
153
183
|
justify-content: space-between;
|
|
@@ -182,21 +212,23 @@ var SelectTrigger = styled2(Select2.Trigger)`
|
|
|
182
212
|
opacity: 0.4;
|
|
183
213
|
cursor: not-allowed;
|
|
184
214
|
}
|
|
215
|
+
|
|
216
|
+
${({ $isInvalid }) => $isInvalid && invalidStyles}
|
|
185
217
|
`;
|
|
186
|
-
var SelectValue =
|
|
218
|
+
var SelectValue = styled3(Select2.Value)`
|
|
187
219
|
min-width: 0;
|
|
188
220
|
overflow: hidden;
|
|
189
221
|
`;
|
|
190
|
-
var SelectIcon =
|
|
222
|
+
var SelectIcon = styled3(Select2.Icon)`
|
|
191
223
|
display: flex;
|
|
192
224
|
align-items: center;
|
|
193
225
|
color: ${({ theme }) => theme.colors.icon.base};
|
|
194
226
|
flex-shrink: 0;
|
|
195
227
|
`;
|
|
196
|
-
var SelectGroup =
|
|
228
|
+
var SelectGroup = styled3(Select2.Group)`
|
|
197
229
|
display: block;
|
|
198
230
|
`;
|
|
199
|
-
var SelectGroupLabel =
|
|
231
|
+
var SelectGroupLabel = styled3(Select2.GroupLabel)`
|
|
200
232
|
padding: ${({ theme }) => `${theme.space[300]} ${theme.space[300]} ${theme.space[200]}`};
|
|
201
233
|
font-size: ${({ theme }) => theme.typography[100].fontSize};
|
|
202
234
|
font-weight: ${({ theme }) => theme.fontWeights.semibold};
|
|
@@ -204,23 +236,23 @@ var SelectGroupLabel = styled2(Select2.GroupLabel)`
|
|
|
204
236
|
letter-spacing: 0.05em;
|
|
205
237
|
color: ${({ theme }) => theme.colors.text.subtext};
|
|
206
238
|
`;
|
|
207
|
-
var SelectSeparator =
|
|
239
|
+
var SelectSeparator = styled3(Select2.Separator)`
|
|
208
240
|
height: 1px;
|
|
209
241
|
margin: ${({ theme }) => `${theme.space[200]} ${theme.space[300]}`};
|
|
210
242
|
background: ${({ theme }) => theme.colors.container.border.base};
|
|
211
243
|
`;
|
|
212
|
-
var SelectPositioner =
|
|
244
|
+
var SelectPositioner = styled3(Select2.Positioner)`
|
|
213
245
|
width: var(--anchor-width);
|
|
214
246
|
z-index: 7;
|
|
215
247
|
`;
|
|
216
|
-
var SelectPopup =
|
|
248
|
+
var SelectPopup = styled3(Select2.Popup)`
|
|
217
249
|
font-family: ${({ theme }) => theme.fontFamily};
|
|
218
250
|
background: ${({ theme }) => theme.colors.container.background.base};
|
|
219
251
|
border: 1px solid ${({ theme }) => theme.colors.container.border.base};
|
|
220
252
|
border-radius: ${({ theme }) => theme.radii[500]};
|
|
221
253
|
box-shadow: ${({ theme }) => theme.shadows.low};
|
|
222
254
|
outline: none;
|
|
223
|
-
max-height: min(var(--
|
|
255
|
+
max-height: min(var(--available-height, 400px), 400px);
|
|
224
256
|
overflow-y: auto;
|
|
225
257
|
padding: ${({ theme }) => theme.space[200]};
|
|
226
258
|
|
|
@@ -255,27 +287,6 @@ var SelectPopup = styled2(Select2.Popup)`
|
|
|
255
287
|
}
|
|
256
288
|
`;
|
|
257
289
|
|
|
258
|
-
// src/v3/Common/SelectIcons.tsx
|
|
259
|
-
import "react";
|
|
260
|
-
import styled3 from "styled-components";
|
|
261
|
-
import { Icon as Icon2 } from "@sproutsocial/seeds-react-icon";
|
|
262
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
263
|
-
var StyledChevron = styled3.div`
|
|
264
|
-
display: flex;
|
|
265
|
-
align-items: center;
|
|
266
|
-
transition: transform 0.15s;
|
|
267
|
-
${({ $isOpen }) => $isOpen && "transform: rotate(-180deg);"}
|
|
268
|
-
`;
|
|
269
|
-
function ChevronIcon() {
|
|
270
|
-
return /* @__PURE__ */ jsx2(Icon2, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true });
|
|
271
|
-
}
|
|
272
|
-
function ClearIcon() {
|
|
273
|
-
return /* @__PURE__ */ jsx2(Icon2, { name: "circle-x-outline", fixedWidth: true, "aria-hidden": true, size: "mini" });
|
|
274
|
-
}
|
|
275
|
-
function CheckIcon2() {
|
|
276
|
-
return /* @__PURE__ */ jsx2(Icon2, { name: "check-outline", fixedWidth: true, "aria-hidden": true });
|
|
277
|
-
}
|
|
278
|
-
|
|
279
290
|
// src/v3/SingleSelect.tsx
|
|
280
291
|
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
281
292
|
var StyledValue = styled4(Select3.Value)`
|
|
@@ -290,8 +301,9 @@ var StyledValue = styled4(Select3.Value)`
|
|
|
290
301
|
}
|
|
291
302
|
`;
|
|
292
303
|
function SingleSelect(props) {
|
|
293
|
-
const { id, placeholder, includePlaceholderItem } = props;
|
|
304
|
+
const { id, placeholder, includePlaceholderItem, fullWidth = true } = props;
|
|
294
305
|
const ariaDescribedBy = props["aria-describedby"];
|
|
306
|
+
const isInvalid = props.isInvalid;
|
|
295
307
|
const isChildrenMode = "children" in props && props.children != null;
|
|
296
308
|
const selectedItemId = props.selectedItemId;
|
|
297
309
|
const defaultSelectedItemId = props.defaultSelectedItemId;
|
|
@@ -338,7 +350,7 @@ function SingleSelect(props) {
|
|
|
338
350
|
}
|
|
339
351
|
}
|
|
340
352
|
}
|
|
341
|
-
return /* @__PURE__ */ jsxs2(Field, { children: [
|
|
353
|
+
return /* @__PURE__ */ jsxs2(Field, { $fullWidth: fullWidth, children: [
|
|
342
354
|
/* @__PURE__ */ jsx3("div", { ref: containerRef, style: { position: "relative" } }),
|
|
343
355
|
/* @__PURE__ */ jsxs2(
|
|
344
356
|
Select3.Root,
|
|
@@ -349,10 +361,19 @@ function SingleSelect(props) {
|
|
|
349
361
|
onValueChange: handleValueChange,
|
|
350
362
|
id,
|
|
351
363
|
children: [
|
|
352
|
-
/* @__PURE__ */ jsxs2(
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
364
|
+
/* @__PURE__ */ jsxs2(
|
|
365
|
+
SelectTrigger,
|
|
366
|
+
{
|
|
367
|
+
"aria-describedby": ariaDescribedBy,
|
|
368
|
+
"aria-invalid": isInvalid || void 0,
|
|
369
|
+
"aria-required": props.required || void 0,
|
|
370
|
+
$isInvalid: isInvalid,
|
|
371
|
+
children: [
|
|
372
|
+
/* @__PURE__ */ jsx3(StyledValue, { placeholder, children: renderSelection && selectedItem ? renderSelection(selectedItem) : void 0 }),
|
|
373
|
+
/* @__PURE__ */ jsx3(SelectIcon, { children: /* @__PURE__ */ jsx3(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx3(ChevronIcon, {}) }) })
|
|
374
|
+
]
|
|
375
|
+
}
|
|
376
|
+
),
|
|
356
377
|
/* @__PURE__ */ jsx3(Select3.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx3(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ jsxs2(SelectPopup, { children: [
|
|
357
378
|
/* @__PURE__ */ jsx3(Select3.ScrollUpArrow, {}),
|
|
358
379
|
/* @__PURE__ */ jsx3(Select3.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ jsxs2(React4.Fragment, { children: [
|
|
@@ -420,8 +441,9 @@ var Placeholder = styled5.div`
|
|
|
420
441
|
margin: 2px 8px 0px 0px;
|
|
421
442
|
`;
|
|
422
443
|
function MultiSelect(props) {
|
|
423
|
-
const { id, placeholder = "Select..." } = props;
|
|
444
|
+
const { id, placeholder = "Select...", fullWidth = true } = props;
|
|
424
445
|
const ariaDescribedBy = props["aria-describedby"];
|
|
446
|
+
const isInvalid = props.isInvalid;
|
|
425
447
|
const isChildrenMode = "children" in props && props.children != null;
|
|
426
448
|
const data = isChildrenMode ? [] : props.data;
|
|
427
449
|
const itemToString = isChildrenMode ? () => "" : props.itemToString;
|
|
@@ -466,7 +488,7 @@ function MultiSelect(props) {
|
|
|
466
488
|
onSelectedItemIdsChange(ids);
|
|
467
489
|
}
|
|
468
490
|
}
|
|
469
|
-
return /* @__PURE__ */ jsxs3(Field, { children: [
|
|
491
|
+
return /* @__PURE__ */ jsxs3(Field, { $fullWidth: fullWidth, children: [
|
|
470
492
|
/* @__PURE__ */ jsx4("div", { ref: containerRef, style: { position: "relative" } }),
|
|
471
493
|
/* @__PURE__ */ jsxs3(
|
|
472
494
|
Select4.Root,
|
|
@@ -478,23 +500,32 @@ function MultiSelect(props) {
|
|
|
478
500
|
disabled: props.disabled,
|
|
479
501
|
id,
|
|
480
502
|
children: [
|
|
481
|
-
/* @__PURE__ */ jsxs3(
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
503
|
+
/* @__PURE__ */ jsxs3(
|
|
504
|
+
SelectTrigger,
|
|
505
|
+
{
|
|
506
|
+
"aria-describedby": ariaDescribedBy,
|
|
507
|
+
"aria-invalid": isInvalid || void 0,
|
|
508
|
+
"aria-required": props.required || void 0,
|
|
509
|
+
$isInvalid: isInvalid,
|
|
510
|
+
children: [
|
|
511
|
+
/* @__PURE__ */ jsx4(SelectValue, { children: () => {
|
|
512
|
+
if (renderSelection) return renderSelection(selectedItems);
|
|
513
|
+
if (selectedItems.length === 0)
|
|
514
|
+
return /* @__PURE__ */ jsx4(Placeholder, { children: placeholder });
|
|
515
|
+
const visibleItems = maxSelections != null ? selectedItems.slice(0, maxSelections) : selectedItems;
|
|
516
|
+
const overflowCount = maxSelections != null && selectedItems.length > maxSelections ? selectedItems.length - maxSelections : 0;
|
|
517
|
+
const text = visibleItems.map(
|
|
518
|
+
(item) => customRenderSelections ? customRenderSelections(item) : itemToString(item)
|
|
519
|
+
).join(", ");
|
|
520
|
+
return /* @__PURE__ */ jsxs3(SelectionText, { children: [
|
|
521
|
+
text,
|
|
522
|
+
overflowCount > 0 ? `, +${overflowCount}` : ""
|
|
523
|
+
] });
|
|
524
|
+
} }),
|
|
525
|
+
/* @__PURE__ */ jsx4(SelectIcon, { children: /* @__PURE__ */ jsx4(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx4(ChevronIcon, {}) }) })
|
|
526
|
+
]
|
|
527
|
+
}
|
|
528
|
+
),
|
|
498
529
|
/* @__PURE__ */ jsx4(Select4.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx4(SelectPositioner, { sideOffset: 8, alignItemWithTrigger: false, children: /* @__PURE__ */ jsxs3(SelectPopup, { children: [
|
|
499
530
|
/* @__PURE__ */ jsx4(Select4.ScrollUpArrow, {}),
|
|
500
531
|
/* @__PURE__ */ jsx4(Select4.List, { children: children ? children : groupBy ? groupItems(data, groupBy).map((group, index, arr) => /* @__PURE__ */ jsxs3(React5.Fragment, { children: [
|
|
@@ -535,21 +566,41 @@ function MultiSelect(props) {
|
|
|
535
566
|
}
|
|
536
567
|
|
|
537
568
|
// src/v3/SingleCombobox.tsx
|
|
538
|
-
import * as
|
|
569
|
+
import * as React9 from "react";
|
|
539
570
|
import { Combobox as Combobox3 } from "@base-ui/react/combobox";
|
|
540
571
|
import "@tanstack/react-virtual";
|
|
541
572
|
|
|
542
|
-
// src/v3/Common/
|
|
573
|
+
// src/v3/Common/useSuppressEscapeClear.ts
|
|
543
574
|
import * as React6 from "react";
|
|
575
|
+
function useSuppressEscapeClear(open) {
|
|
576
|
+
return React6.useCallback(
|
|
577
|
+
(event) => {
|
|
578
|
+
if (event.key === "Escape" && !open) {
|
|
579
|
+
event.stopPropagation();
|
|
580
|
+
}
|
|
581
|
+
},
|
|
582
|
+
[open]
|
|
583
|
+
);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/v3/Common/ComboboxItem.tsx
|
|
587
|
+
import * as React7 from "react";
|
|
544
588
|
import Radio2 from "@sproutsocial/seeds-react-radio";
|
|
545
589
|
import Checkbox3 from "@sproutsocial/seeds-react-checkbox";
|
|
546
590
|
|
|
547
591
|
// src/v3/Common/ComboboxStyles.tsx
|
|
548
592
|
import { Combobox } from "@base-ui/react/combobox";
|
|
549
|
-
import styled6 from "styled-components";
|
|
593
|
+
import styled6, { css as css2 } from "styled-components";
|
|
550
594
|
import { focusRing as focusRing2 } from "@sproutsocial/seeds-react-mixins";
|
|
551
595
|
import Checkbox2 from "@sproutsocial/seeds-react-checkbox";
|
|
552
596
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
597
|
+
var invalidStyles2 = css2`
|
|
598
|
+
border-color: ${({ theme }) => theme.colors.form.border.error};
|
|
599
|
+
|
|
600
|
+
${StyledChevron} {
|
|
601
|
+
color: ${({ theme }) => theme.colors.icon.error};
|
|
602
|
+
}
|
|
603
|
+
`;
|
|
553
604
|
var ComboboxLabel = styled6.label`
|
|
554
605
|
font-size: ${({ theme }) => theme.typography[200].fontSize};
|
|
555
606
|
font-weight: ${({ theme }) => theme.fontWeights.semibold};
|
|
@@ -576,6 +627,8 @@ var ComboboxInputGroup = styled6(Combobox.InputGroup)`
|
|
|
576
627
|
opacity: 0.4;
|
|
577
628
|
cursor: not-allowed;
|
|
578
629
|
}
|
|
630
|
+
|
|
631
|
+
${({ $isInvalid }) => $isInvalid && invalidStyles2}
|
|
579
632
|
`;
|
|
580
633
|
var ComboboxInput = styled6(Combobox.Input)`
|
|
581
634
|
flex: 1;
|
|
@@ -623,7 +676,7 @@ var ComboboxActionButtons = styled6.div`
|
|
|
623
676
|
margin-left: auto;
|
|
624
677
|
gap: ${({ theme }) => theme.space[100]};
|
|
625
678
|
`;
|
|
626
|
-
var ComboboxClear = styled6(Combobox.Clear)`
|
|
679
|
+
var ComboboxClear = styled6(Combobox.Clear).attrs({ tabIndex: 0 })`
|
|
627
680
|
display: flex;
|
|
628
681
|
align-items: center;
|
|
629
682
|
justify-content: center;
|
|
@@ -640,6 +693,10 @@ var ComboboxClear = styled6(Combobox.Clear)`
|
|
|
640
693
|
color: ${({ theme }) => theme.colors.text.body};
|
|
641
694
|
}
|
|
642
695
|
|
|
696
|
+
&:focus-visible {
|
|
697
|
+
${focusRing2}
|
|
698
|
+
}
|
|
699
|
+
|
|
643
700
|
&[data-empty] {
|
|
644
701
|
display: none;
|
|
645
702
|
}
|
|
@@ -672,7 +729,7 @@ var ComboboxPopup = styled6(Combobox.Popup)`
|
|
|
672
729
|
box-shadow: ${({ theme }) => theme.shadows.medium};
|
|
673
730
|
outline: none;
|
|
674
731
|
width: 100%;
|
|
675
|
-
max-height: min(var(--
|
|
732
|
+
max-height: min(var(--available-height, 400px), 400px);
|
|
676
733
|
overflow-y: auto;
|
|
677
734
|
padding: 0;
|
|
678
735
|
|
|
@@ -839,6 +896,7 @@ var ComboboxToken = styled6(Combobox.Chips)`
|
|
|
839
896
|
display: flex;
|
|
840
897
|
width: 100%;
|
|
841
898
|
flex-wrap: wrap;
|
|
899
|
+
gap: ${({ theme }) => theme.space[200]};
|
|
842
900
|
`;
|
|
843
901
|
var ComboboxTokenInputGroup = styled6(Combobox.InputGroup)`
|
|
844
902
|
display: flex;
|
|
@@ -863,6 +921,8 @@ var ComboboxTokenInputGroup = styled6(Combobox.InputGroup)`
|
|
|
863
921
|
opacity: 0.4;
|
|
864
922
|
cursor: not-allowed;
|
|
865
923
|
}
|
|
924
|
+
|
|
925
|
+
${({ $isInvalid }) => $isInvalid && invalidStyles2}
|
|
866
926
|
`;
|
|
867
927
|
var Token = styled6.span`
|
|
868
928
|
display: inline-flex;
|
|
@@ -895,6 +955,10 @@ var TokenRemove = styled6.button`
|
|
|
895
955
|
cursor: pointer;
|
|
896
956
|
padding: 0;
|
|
897
957
|
line-height: 1;
|
|
958
|
+
|
|
959
|
+
&:focus-visible {
|
|
960
|
+
${focusRing2}
|
|
961
|
+
}
|
|
898
962
|
`;
|
|
899
963
|
var SearchableSelectTrigger = styled6(Combobox.Trigger)`
|
|
900
964
|
display: flex;
|
|
@@ -928,6 +992,8 @@ var SearchableSelectTrigger = styled6(Combobox.Trigger)`
|
|
|
928
992
|
opacity: 0.4;
|
|
929
993
|
cursor: not-allowed;
|
|
930
994
|
}
|
|
995
|
+
|
|
996
|
+
${({ $isInvalid }) => $isInvalid && invalidStyles2}
|
|
931
997
|
`;
|
|
932
998
|
var SearchableSelectTriggerIcon = styled6(Combobox.Icon)`
|
|
933
999
|
display: flex;
|
|
@@ -1010,6 +1076,8 @@ var SearchableSelectTokenTrigger = styled6(Combobox.Trigger)`
|
|
|
1010
1076
|
opacity: 0.4;
|
|
1011
1077
|
cursor: not-allowed;
|
|
1012
1078
|
}
|
|
1079
|
+
|
|
1080
|
+
${({ $isInvalid }) => $isInvalid && invalidStyles2}
|
|
1013
1081
|
`;
|
|
1014
1082
|
|
|
1015
1083
|
// src/v3/Common/ComboboxItem.tsx
|
|
@@ -1074,11 +1142,11 @@ function ComboboxItemInner({
|
|
|
1074
1142
|
}
|
|
1075
1143
|
);
|
|
1076
1144
|
}
|
|
1077
|
-
var ComboboxItem2 =
|
|
1145
|
+
var ComboboxItem2 = React7.forwardRef(ComboboxItemInner);
|
|
1078
1146
|
var ComboboxItem_default = ComboboxItem2;
|
|
1079
1147
|
|
|
1080
1148
|
// src/v3/Common/VirtualizedComboboxList.tsx
|
|
1081
|
-
import * as
|
|
1149
|
+
import * as React8 from "react";
|
|
1082
1150
|
import { Combobox as Combobox2 } from "@base-ui/react/combobox";
|
|
1083
1151
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
1084
1152
|
|
|
@@ -1118,7 +1186,7 @@ function VirtualizedComboboxList({
|
|
|
1118
1186
|
renderCreatableItem
|
|
1119
1187
|
}) {
|
|
1120
1188
|
const filteredItems = Combobox2.useFilteredItems();
|
|
1121
|
-
const scrollElementRef =
|
|
1189
|
+
const scrollElementRef = React8.useRef(null);
|
|
1122
1190
|
const virtualizer = useVirtualizer({
|
|
1123
1191
|
enabled: open,
|
|
1124
1192
|
count: filteredItems.length,
|
|
@@ -1130,8 +1198,8 @@ function VirtualizedComboboxList({
|
|
|
1130
1198
|
scrollPaddingStart: 4,
|
|
1131
1199
|
scrollPaddingEnd: 4
|
|
1132
1200
|
});
|
|
1133
|
-
|
|
1134
|
-
const handleScrollRef =
|
|
1201
|
+
React8.useImperativeHandle(virtualizerRef, () => virtualizer);
|
|
1202
|
+
const handleScrollRef = React8.useCallback(
|
|
1135
1203
|
(el) => {
|
|
1136
1204
|
scrollElementRef.current = el;
|
|
1137
1205
|
if (el) requestAnimationFrame(() => virtualizer.measure());
|
|
@@ -1275,9 +1343,11 @@ function SingleCombobox(props) {
|
|
|
1275
1343
|
id,
|
|
1276
1344
|
placeholder = "Search...",
|
|
1277
1345
|
emptyText = "No results found.",
|
|
1278
|
-
filter
|
|
1346
|
+
filter,
|
|
1347
|
+
fullWidth = true
|
|
1279
1348
|
} = props;
|
|
1280
1349
|
const ariaDescribedBy = props["aria-describedby"];
|
|
1350
|
+
const isInvalid = props.isInvalid;
|
|
1281
1351
|
const isChildrenMode = "children" in props && props.children != null;
|
|
1282
1352
|
const data = isChildrenMode ? [] : props.data;
|
|
1283
1353
|
const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
|
|
@@ -1291,17 +1361,18 @@ function SingleCombobox(props) {
|
|
|
1291
1361
|
const defaultSelectedItemId = props.defaultSelectedItemId;
|
|
1292
1362
|
const onSelectedItemIdChange = props.onSelectedItemIdChange;
|
|
1293
1363
|
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
1294
|
-
const [open, setOpen] =
|
|
1295
|
-
const virtualizerRef =
|
|
1364
|
+
const [open, setOpen] = React9.useState(false);
|
|
1365
|
+
const virtualizerRef = React9.useRef(null);
|
|
1366
|
+
const onInputKeyDownCapture = useSuppressEscapeClear(open);
|
|
1296
1367
|
const isControlled = selectedItemId !== void 0;
|
|
1297
|
-
const idToItem =
|
|
1368
|
+
const idToItem = React9.useCallback(
|
|
1298
1369
|
(id2) => {
|
|
1299
1370
|
if (id2 == null) return null;
|
|
1300
1371
|
return data.find((d) => String(d.id) === String(id2)) ?? null;
|
|
1301
1372
|
},
|
|
1302
1373
|
[data]
|
|
1303
1374
|
);
|
|
1304
|
-
const [internalValue, setInternalValue] =
|
|
1375
|
+
const [internalValue, setInternalValue] = React9.useState(
|
|
1305
1376
|
() => idToItem(defaultSelectedItemId)
|
|
1306
1377
|
);
|
|
1307
1378
|
const value = isControlled ? idToItem(selectedItemId) : internalValue;
|
|
@@ -1313,11 +1384,11 @@ function SingleCombobox(props) {
|
|
|
1313
1384
|
onSelectedItemIdChange(newItem ? newItem.id : null);
|
|
1314
1385
|
}
|
|
1315
1386
|
}
|
|
1316
|
-
const groups =
|
|
1387
|
+
const groups = React9.useMemo(
|
|
1317
1388
|
() => groupBy ? groupItems(data, groupBy) : null,
|
|
1318
1389
|
[data, groupBy]
|
|
1319
1390
|
);
|
|
1320
|
-
return /* @__PURE__ */ jsxs6(Field, { children: [
|
|
1391
|
+
return /* @__PURE__ */ jsxs6(Field, { $fullWidth: fullWidth, children: [
|
|
1321
1392
|
/* @__PURE__ */ jsx8("div", { ref: containerRef, style: { position: "relative" } }),
|
|
1322
1393
|
/* @__PURE__ */ jsxs6(
|
|
1323
1394
|
Combobox3.Root,
|
|
@@ -1338,29 +1409,38 @@ function SingleCombobox(props) {
|
|
|
1338
1409
|
if (!item || !virt) return;
|
|
1339
1410
|
const isStart = index === 0;
|
|
1340
1411
|
const isEnd = index === virt.options.count - 1;
|
|
1341
|
-
if (reason === "
|
|
1412
|
+
if (reason === "keyboard" && (isStart || isEnd)) {
|
|
1342
1413
|
queueMicrotask(() => {
|
|
1343
1414
|
virt.scrollToIndex(index, {
|
|
1344
|
-
align:
|
|
1415
|
+
align: isStart ? "start" : "end"
|
|
1345
1416
|
});
|
|
1346
1417
|
});
|
|
1347
1418
|
}
|
|
1348
1419
|
} : void 0,
|
|
1349
1420
|
children: [
|
|
1350
|
-
/* @__PURE__ */ jsxs6(
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1421
|
+
/* @__PURE__ */ jsxs6(
|
|
1422
|
+
ComboboxInputGroup,
|
|
1423
|
+
{
|
|
1424
|
+
$isInvalid: isInvalid,
|
|
1425
|
+
onKeyDownCapture: onInputKeyDownCapture,
|
|
1426
|
+
children: [
|
|
1427
|
+
/* @__PURE__ */ jsx8(
|
|
1428
|
+
ComboboxInput,
|
|
1429
|
+
{
|
|
1430
|
+
placeholder,
|
|
1431
|
+
id,
|
|
1432
|
+
"aria-describedby": ariaDescribedBy,
|
|
1433
|
+
"aria-invalid": isInvalid || void 0,
|
|
1434
|
+
"aria-required": props.required || void 0
|
|
1435
|
+
}
|
|
1436
|
+
),
|
|
1437
|
+
/* @__PURE__ */ jsxs6(ComboboxActionButtons, { children: [
|
|
1438
|
+
/* @__PURE__ */ jsx8(ComboboxClear, { "aria-label": "Clear selection", children: /* @__PURE__ */ jsx8(ClearIcon, {}) }),
|
|
1439
|
+
/* @__PURE__ */ jsx8(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx8(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx8(ChevronIcon, {}) }) })
|
|
1440
|
+
] })
|
|
1441
|
+
]
|
|
1442
|
+
}
|
|
1443
|
+
),
|
|
1364
1444
|
/* @__PURE__ */ jsx8(Combobox3.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx8(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs6(
|
|
1365
1445
|
ComboboxPopup,
|
|
1366
1446
|
{
|
|
@@ -1390,7 +1470,7 @@ function SingleCombobox(props) {
|
|
|
1390
1470
|
renderItem,
|
|
1391
1471
|
renderGroupHeading
|
|
1392
1472
|
}
|
|
1393
|
-
) : children ? children : groups ? (group, index) => /* @__PURE__ */ jsxs6(
|
|
1473
|
+
) : children ? children : groups ? ((group, index) => /* @__PURE__ */ jsxs6(React9.Fragment, { children: [
|
|
1394
1474
|
/* @__PURE__ */ jsxs6(ComboboxGroup, { items: group.items, children: [
|
|
1395
1475
|
/* @__PURE__ */ jsx8(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
|
|
1396
1476
|
/* @__PURE__ */ jsx8(Combobox3.Collection, { children: (item) => /* @__PURE__ */ jsx8(
|
|
@@ -1407,7 +1487,7 @@ function SingleCombobox(props) {
|
|
|
1407
1487
|
) })
|
|
1408
1488
|
] }),
|
|
1409
1489
|
index < groups.length - 1 && /* @__PURE__ */ jsx8(ComboboxSeparator, {})
|
|
1410
|
-
] }, group.value) : (item) => /* @__PURE__ */ jsx8(
|
|
1490
|
+
] }, group.value)) : ((item) => /* @__PURE__ */ jsx8(
|
|
1411
1491
|
ComboboxItem_default,
|
|
1412
1492
|
{
|
|
1413
1493
|
value: item,
|
|
@@ -1418,7 +1498,7 @@ function SingleCombobox(props) {
|
|
|
1418
1498
|
renderItem: renderItem ? () => renderItem(item) : () => itemToString(item)
|
|
1419
1499
|
},
|
|
1420
1500
|
item.id
|
|
1421
|
-
)
|
|
1501
|
+
))
|
|
1422
1502
|
}
|
|
1423
1503
|
)
|
|
1424
1504
|
]
|
|
@@ -1431,7 +1511,7 @@ function SingleCombobox(props) {
|
|
|
1431
1511
|
}
|
|
1432
1512
|
|
|
1433
1513
|
// src/v3/MultiCombobox.tsx
|
|
1434
|
-
import * as
|
|
1514
|
+
import * as React10 from "react";
|
|
1435
1515
|
import { Combobox as Combobox4 } from "@base-ui/react/combobox";
|
|
1436
1516
|
import "@tanstack/react-virtual";
|
|
1437
1517
|
import Icon3 from "@sproutsocial/seeds-react-icon";
|
|
@@ -1455,9 +1535,11 @@ function MultiCombobox(props) {
|
|
|
1455
1535
|
loadingText = "Loading...",
|
|
1456
1536
|
filter,
|
|
1457
1537
|
inputValue,
|
|
1458
|
-
onInputValueChange
|
|
1538
|
+
onInputValueChange,
|
|
1539
|
+
fullWidth = true
|
|
1459
1540
|
} = props;
|
|
1460
1541
|
const ariaDescribedBy = props["aria-describedby"];
|
|
1542
|
+
const isInvalid = props.isInvalid;
|
|
1461
1543
|
const isChildrenMode = "children" in props && props.children != null;
|
|
1462
1544
|
const data = isChildrenMode ? [] : props.data;
|
|
1463
1545
|
const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
|
|
@@ -1481,29 +1563,31 @@ function MultiCombobox(props) {
|
|
|
1481
1563
|
const defaultSelectedItemIds = props.defaultSelectedItemIds;
|
|
1482
1564
|
const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
|
|
1483
1565
|
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
1484
|
-
const [open, setOpen] =
|
|
1485
|
-
const [internalInputValue, setInternalInputValue] =
|
|
1486
|
-
const skipNextInputChangeRef =
|
|
1487
|
-
const virtualizerRef =
|
|
1566
|
+
const [open, setOpen] = React10.useState(false);
|
|
1567
|
+
const [internalInputValue, setInternalInputValue] = React10.useState("");
|
|
1568
|
+
const skipNextInputChangeRef = React10.useRef(false);
|
|
1569
|
+
const virtualizerRef = React10.useRef(null);
|
|
1570
|
+
const inputRef = React10.useRef(null);
|
|
1571
|
+
const onInputKeyDownCapture = useSuppressEscapeClear(open);
|
|
1488
1572
|
const isControlled = selectedItemIds !== void 0;
|
|
1489
|
-
const idsToItems =
|
|
1573
|
+
const idsToItems = React10.useCallback(
|
|
1490
1574
|
(ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
|
|
1491
1575
|
[data]
|
|
1492
1576
|
);
|
|
1493
|
-
const [internalValue, setInternalValue] =
|
|
1577
|
+
const [internalValue, setInternalValue] = React10.useState(
|
|
1494
1578
|
() => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
|
|
1495
1579
|
);
|
|
1496
1580
|
const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
|
|
1497
|
-
const visibleData =
|
|
1581
|
+
const visibleData = React10.useMemo(
|
|
1498
1582
|
() => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
|
|
1499
1583
|
[data, value, removeSelectedItems]
|
|
1500
1584
|
);
|
|
1501
|
-
const groups =
|
|
1585
|
+
const groups = React10.useMemo(
|
|
1502
1586
|
() => groupBy ? groupItems(visibleData, groupBy) : null,
|
|
1503
1587
|
[visibleData, groupBy]
|
|
1504
1588
|
);
|
|
1505
1589
|
const currentInputValue = inputValue ?? internalInputValue;
|
|
1506
|
-
const creatableSentinel =
|
|
1590
|
+
const creatableSentinel = React10.useMemo(() => {
|
|
1507
1591
|
if (!creatableProp) return null;
|
|
1508
1592
|
const trimmed = currentInputValue.trim();
|
|
1509
1593
|
if (!trimmed) return null;
|
|
@@ -1514,7 +1598,7 @@ function MultiCombobox(props) {
|
|
|
1514
1598
|
if (exactExists) return null;
|
|
1515
1599
|
return makeCreatableSentinel(trimmed);
|
|
1516
1600
|
}, [creatableProp, currentInputValue, data, itemToString]);
|
|
1517
|
-
const flatItems =
|
|
1601
|
+
const flatItems = React10.useMemo(() => {
|
|
1518
1602
|
if (!selectHeadings && !selectAll) return null;
|
|
1519
1603
|
if (!groups && !selectAll) return null;
|
|
1520
1604
|
const rows = [];
|
|
@@ -1600,6 +1684,7 @@ function MultiCombobox(props) {
|
|
|
1600
1684
|
e.preventDefault();
|
|
1601
1685
|
e.stopPropagation();
|
|
1602
1686
|
setSelectedItems(value.filter((v) => v.id !== item.id));
|
|
1687
|
+
inputRef.current?.focus();
|
|
1603
1688
|
}
|
|
1604
1689
|
function renderSentinelRow(row) {
|
|
1605
1690
|
if (isSelectAllSentinel2(row)) {
|
|
@@ -1670,7 +1755,7 @@ function MultiCombobox(props) {
|
|
|
1670
1755
|
const rootItems = creatableSentinel && Array.isArray(baseItems) ? [...baseItems, creatableSentinel] : baseItems;
|
|
1671
1756
|
const hasSentinels = selectAll || selectHeadings;
|
|
1672
1757
|
const rootValue = hasSentinels ? [...value] : value;
|
|
1673
|
-
return /* @__PURE__ */ jsxs7(Field, { children: [
|
|
1758
|
+
return /* @__PURE__ */ jsxs7(Field, { $fullWidth: fullWidth, children: [
|
|
1674
1759
|
/* @__PURE__ */ jsx9("div", { ref: containerRef, style: { position: "relative" } }),
|
|
1675
1760
|
/* @__PURE__ */ jsxs7(
|
|
1676
1761
|
Combobox4.Root,
|
|
@@ -1681,7 +1766,10 @@ function MultiCombobox(props) {
|
|
|
1681
1766
|
open,
|
|
1682
1767
|
disabled: props.disabled,
|
|
1683
1768
|
onOpenChange: (nextOpen, eventDetails) => {
|
|
1684
|
-
if (!nextOpen && eventDetails.reason === "item-press")
|
|
1769
|
+
if (!nextOpen && eventDetails.reason === "item-press") {
|
|
1770
|
+
eventDetails.cancel();
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1685
1773
|
setOpen(nextOpen);
|
|
1686
1774
|
},
|
|
1687
1775
|
filter: creatableProp ? (item, query) => {
|
|
@@ -1714,10 +1802,10 @@ function MultiCombobox(props) {
|
|
|
1714
1802
|
if (!item || !virt) return;
|
|
1715
1803
|
const isStart = index === 0;
|
|
1716
1804
|
const isEnd = index === virt.options.count - 1;
|
|
1717
|
-
if (reason === "
|
|
1805
|
+
if (reason === "keyboard" && (isStart || isEnd)) {
|
|
1718
1806
|
queueMicrotask(() => {
|
|
1719
1807
|
virt.scrollToIndex(index, {
|
|
1720
|
-
align:
|
|
1808
|
+
align: isStart ? "start" : "end"
|
|
1721
1809
|
});
|
|
1722
1810
|
});
|
|
1723
1811
|
}
|
|
@@ -1744,42 +1832,52 @@ function MultiCombobox(props) {
|
|
|
1744
1832
|
},
|
|
1745
1833
|
items: rootItems,
|
|
1746
1834
|
children: [
|
|
1747
|
-
/* @__PURE__ */ jsx9(
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1835
|
+
/* @__PURE__ */ jsx9(
|
|
1836
|
+
ComboboxTokenInputGroup,
|
|
1837
|
+
{
|
|
1838
|
+
$isInvalid: isInvalid,
|
|
1839
|
+
onKeyDownCapture: onInputKeyDownCapture,
|
|
1840
|
+
children: /* @__PURE__ */ jsxs7(ComboboxToken, { children: [
|
|
1841
|
+
renderSelection ? renderSelection(value) : (() => {
|
|
1842
|
+
const visibleTokens = maxTokens != null ? value.slice(0, maxTokens) : value;
|
|
1843
|
+
const overflow = maxTokens != null ? value.length - maxTokens : 0;
|
|
1844
|
+
return /* @__PURE__ */ jsxs7(Fragment6, { children: [
|
|
1845
|
+
visibleTokens.map((item) => /* @__PURE__ */ jsxs7(Token, { children: [
|
|
1846
|
+
renderToken ? renderToken(item) : itemToString(item),
|
|
1847
|
+
/* @__PURE__ */ jsx9(
|
|
1848
|
+
TokenRemove,
|
|
1849
|
+
{
|
|
1850
|
+
"aria-label": `Remove ${itemToString(item)}`,
|
|
1851
|
+
onPointerDown: (e) => e.preventDefault(),
|
|
1852
|
+
onClick: (e) => removeItem(item, e),
|
|
1853
|
+
children: /* @__PURE__ */ jsx9(Icon3, { name: "x-outline", size: "mini" })
|
|
1854
|
+
}
|
|
1855
|
+
)
|
|
1856
|
+
] }, item.id)),
|
|
1857
|
+
overflow > 0 && /* @__PURE__ */ jsxs7(Token, { children: [
|
|
1858
|
+
"+",
|
|
1859
|
+
overflow
|
|
1860
|
+
] }, "__overflow")
|
|
1861
|
+
] });
|
|
1862
|
+
})(),
|
|
1863
|
+
/* @__PURE__ */ jsx9(
|
|
1864
|
+
ComboboxTokenInput,
|
|
1865
|
+
{
|
|
1866
|
+
ref: inputRef,
|
|
1867
|
+
id,
|
|
1868
|
+
placeholder: value.length > 0 ? "" : placeholder,
|
|
1869
|
+
"aria-describedby": ariaDescribedBy,
|
|
1870
|
+
"aria-invalid": isInvalid || void 0,
|
|
1871
|
+
"aria-required": props.required || void 0
|
|
1872
|
+
}
|
|
1873
|
+
),
|
|
1874
|
+
/* @__PURE__ */ jsxs7(ComboboxActionButtons, { children: [
|
|
1875
|
+
/* @__PURE__ */ jsx9(ComboboxClear, { "aria-label": "Clear all", children: /* @__PURE__ */ jsx9(ClearIcon, {}) }),
|
|
1876
|
+
/* @__PURE__ */ jsx9(ComboboxTrigger, { "aria-label": "Open popup", children: /* @__PURE__ */ jsx9(StyledChevron, { $isOpen: open, children: /* @__PURE__ */ jsx9(ChevronIcon, {}) }) })
|
|
1877
|
+
] })
|
|
1878
|
+
] })
|
|
1879
|
+
}
|
|
1880
|
+
),
|
|
1783
1881
|
/* @__PURE__ */ jsx9(Combobox4.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx9(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs7(
|
|
1784
1882
|
ComboboxPopup,
|
|
1785
1883
|
{
|
|
@@ -1817,12 +1915,12 @@ function MultiCombobox(props) {
|
|
|
1817
1915
|
measureRef
|
|
1818
1916
|
) : void 0
|
|
1819
1917
|
}
|
|
1820
|
-
) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
|
|
1918
|
+
) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
|
|
1821
1919
|
if (isCreatableSentinel(group)) {
|
|
1822
1920
|
return renderCreatableItem(group);
|
|
1823
1921
|
}
|
|
1824
1922
|
const g = group;
|
|
1825
|
-
return /* @__PURE__ */ jsxs7(
|
|
1923
|
+
return /* @__PURE__ */ jsxs7(React10.Fragment, { children: [
|
|
1826
1924
|
/* @__PURE__ */ jsxs7(ComboboxGroup, { items: g.items, children: [
|
|
1827
1925
|
/* @__PURE__ */ jsx9(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
|
|
1828
1926
|
/* @__PURE__ */ jsx9(Combobox4.Collection, { children: (item) => /* @__PURE__ */ jsx9(
|
|
@@ -1840,7 +1938,7 @@ function MultiCombobox(props) {
|
|
|
1840
1938
|
] }),
|
|
1841
1939
|
index < groups.length - 1 && /* @__PURE__ */ jsx9(ComboboxSeparator, {})
|
|
1842
1940
|
] }, g.value);
|
|
1843
|
-
} : (item) => {
|
|
1941
|
+
}) : ((item) => {
|
|
1844
1942
|
if (isCreatableSentinel(item)) {
|
|
1845
1943
|
return renderCreatableItem(item);
|
|
1846
1944
|
}
|
|
@@ -1857,7 +1955,7 @@ function MultiCombobox(props) {
|
|
|
1857
1955
|
},
|
|
1858
1956
|
dataItem.id
|
|
1859
1957
|
);
|
|
1860
|
-
}
|
|
1958
|
+
})
|
|
1861
1959
|
}
|
|
1862
1960
|
)
|
|
1863
1961
|
]
|
|
@@ -1870,7 +1968,7 @@ function MultiCombobox(props) {
|
|
|
1870
1968
|
}
|
|
1871
1969
|
|
|
1872
1970
|
// src/v3/SingleSearchableSelect.tsx
|
|
1873
|
-
import * as
|
|
1971
|
+
import * as React11 from "react";
|
|
1874
1972
|
import { Combobox as Combobox5 } from "@base-ui/react/combobox";
|
|
1875
1973
|
import "@tanstack/react-virtual";
|
|
1876
1974
|
import { Fragment as Fragment8, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -1883,9 +1981,11 @@ function SingleSearchableSelect(props) {
|
|
|
1883
1981
|
emptyText = "No results found.",
|
|
1884
1982
|
isLoading = false,
|
|
1885
1983
|
loadingText = "Loading...",
|
|
1886
|
-
filter
|
|
1984
|
+
filter,
|
|
1985
|
+
fullWidth = true
|
|
1887
1986
|
} = props;
|
|
1888
1987
|
const ariaDescribedBy = props["aria-describedby"];
|
|
1988
|
+
const isInvalid = props.isInvalid;
|
|
1889
1989
|
const isChildrenMode = "children" in props && props.children != null;
|
|
1890
1990
|
const data = isChildrenMode ? [] : props.data;
|
|
1891
1991
|
const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
|
|
@@ -1900,17 +2000,17 @@ function SingleSearchableSelect(props) {
|
|
|
1900
2000
|
const defaultSelectedItemId = props.defaultSelectedItemId;
|
|
1901
2001
|
const onSelectedItemIdChange = props.onSelectedItemIdChange;
|
|
1902
2002
|
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
1903
|
-
const [open, setOpen] =
|
|
1904
|
-
const virtualizerRef =
|
|
2003
|
+
const [open, setOpen] = React11.useState(false);
|
|
2004
|
+
const virtualizerRef = React11.useRef(null);
|
|
1905
2005
|
const isControlled = selectedItemId !== void 0;
|
|
1906
|
-
const idToItem =
|
|
2006
|
+
const idToItem = React11.useCallback(
|
|
1907
2007
|
(id2) => {
|
|
1908
2008
|
if (id2 == null) return null;
|
|
1909
2009
|
return data.find((d) => String(d.id) === String(id2)) ?? null;
|
|
1910
2010
|
},
|
|
1911
2011
|
[data]
|
|
1912
2012
|
);
|
|
1913
|
-
const [internalValue, setInternalValue] =
|
|
2013
|
+
const [internalValue, setInternalValue] = React11.useState(
|
|
1914
2014
|
() => idToItem(defaultSelectedItemId)
|
|
1915
2015
|
);
|
|
1916
2016
|
const value = isControlled ? idToItem(selectedItemId) : internalValue;
|
|
@@ -1921,11 +2021,11 @@ function SingleSearchableSelect(props) {
|
|
|
1921
2021
|
onSelectedItemIdChange(realItem ? realItem.id : null);
|
|
1922
2022
|
}
|
|
1923
2023
|
}
|
|
1924
|
-
const groups =
|
|
2024
|
+
const groups = React11.useMemo(
|
|
1925
2025
|
() => groupBy ? groupItems(data, groupBy) : null,
|
|
1926
2026
|
[data, groupBy]
|
|
1927
2027
|
);
|
|
1928
|
-
return /* @__PURE__ */ jsxs8(Field, { children: [
|
|
2028
|
+
return /* @__PURE__ */ jsxs8(Field, { $fullWidth: fullWidth, children: [
|
|
1929
2029
|
/* @__PURE__ */ jsx10("div", { ref: containerRef, style: { position: "relative" } }),
|
|
1930
2030
|
/* @__PURE__ */ jsxs8(
|
|
1931
2031
|
Combobox5.Root,
|
|
@@ -1951,19 +2051,29 @@ function SingleSearchableSelect(props) {
|
|
|
1951
2051
|
if (!item || !virt) return;
|
|
1952
2052
|
const isStart = index === 0;
|
|
1953
2053
|
const isEnd = index === virt.options.count - 1;
|
|
1954
|
-
if (reason === "
|
|
2054
|
+
if (reason === "keyboard" && (isStart || isEnd)) {
|
|
1955
2055
|
queueMicrotask(() => {
|
|
1956
2056
|
virt.scrollToIndex(index, {
|
|
1957
|
-
align:
|
|
2057
|
+
align: isStart ? "start" : "end"
|
|
1958
2058
|
});
|
|
1959
2059
|
});
|
|
1960
2060
|
}
|
|
1961
2061
|
} : void 0,
|
|
1962
2062
|
children: [
|
|
1963
|
-
/* @__PURE__ */ jsxs8(
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
2063
|
+
/* @__PURE__ */ jsxs8(
|
|
2064
|
+
SearchableSelectTrigger,
|
|
2065
|
+
{
|
|
2066
|
+
id,
|
|
2067
|
+
"aria-describedby": ariaDescribedBy,
|
|
2068
|
+
"aria-invalid": isInvalid || void 0,
|
|
2069
|
+
"aria-required": props.required || void 0,
|
|
2070
|
+
$isInvalid: isInvalid,
|
|
2071
|
+
children: [
|
|
2072
|
+
/* @__PURE__ */ jsx10(SearchableSelectPlaceholder, { children: /* @__PURE__ */ jsx10(Combobox5.Value, { placeholder, children: value ? renderSelection ? renderSelection(value) : itemToString(value) : placeholder }) }),
|
|
2073
|
+
/* @__PURE__ */ jsx10(SearchableSelectTriggerIcon, { children: /* @__PURE__ */ jsx10(StyledChevron, { "data-chevron": true, children: /* @__PURE__ */ jsx10(ChevronIcon, {}) }) })
|
|
2074
|
+
]
|
|
2075
|
+
}
|
|
2076
|
+
),
|
|
1967
2077
|
/* @__PURE__ */ jsx10(Combobox5.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx10(ComboboxPositioner, { sideOffset: 4, children: /* @__PURE__ */ jsxs8(
|
|
1968
2078
|
SearchableSelectPopup,
|
|
1969
2079
|
{
|
|
@@ -2001,7 +2111,7 @@ function SingleSearchableSelect(props) {
|
|
|
2001
2111
|
inputType,
|
|
2002
2112
|
renderItem
|
|
2003
2113
|
}
|
|
2004
|
-
) : children ? children : groups ? (group, index) => /* @__PURE__ */ jsxs8(
|
|
2114
|
+
) : children ? children : groups ? ((group, index) => /* @__PURE__ */ jsxs8(React11.Fragment, { children: [
|
|
2005
2115
|
/* @__PURE__ */ jsxs8(ComboboxGroup, { items: group.items, children: [
|
|
2006
2116
|
/* @__PURE__ */ jsx10(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(group.value) : group.value }),
|
|
2007
2117
|
/* @__PURE__ */ jsx10(Combobox5.Collection, { children: (item) => /* @__PURE__ */ jsx10(
|
|
@@ -2018,7 +2128,7 @@ function SingleSearchableSelect(props) {
|
|
|
2018
2128
|
) })
|
|
2019
2129
|
] }),
|
|
2020
2130
|
index < groups.length - 1 && /* @__PURE__ */ jsx10(ComboboxSeparator, {})
|
|
2021
|
-
] }, group.value) : /* @__PURE__ */ jsxs8(Fragment8, { children: [
|
|
2131
|
+
] }, group.value)) : /* @__PURE__ */ jsxs8(Fragment8, { children: [
|
|
2022
2132
|
includePlaceholderItem && /* @__PURE__ */ jsx10(
|
|
2023
2133
|
ComboboxItem_default,
|
|
2024
2134
|
{
|
|
@@ -2054,7 +2164,7 @@ function SingleSearchableSelect(props) {
|
|
|
2054
2164
|
}
|
|
2055
2165
|
|
|
2056
2166
|
// src/v3/MultiSearchableSelect.tsx
|
|
2057
|
-
import * as
|
|
2167
|
+
import * as React12 from "react";
|
|
2058
2168
|
import { Combobox as Combobox6 } from "@base-ui/react/combobox";
|
|
2059
2169
|
import "@tanstack/react-virtual";
|
|
2060
2170
|
import Icon4 from "@sproutsocial/seeds-react-icon";
|
|
@@ -2084,9 +2194,11 @@ function MultiSearchableSelect(props) {
|
|
|
2084
2194
|
emptyText = "No results found.",
|
|
2085
2195
|
isLoading = false,
|
|
2086
2196
|
loadingText = "Loading...",
|
|
2087
|
-
filter
|
|
2197
|
+
filter,
|
|
2198
|
+
fullWidth = true
|
|
2088
2199
|
} = props;
|
|
2089
2200
|
const ariaDescribedBy = props["aria-describedby"];
|
|
2201
|
+
const isInvalid = props.isInvalid;
|
|
2090
2202
|
const isChildrenMode = "children" in props && props.children != null;
|
|
2091
2203
|
const data = isChildrenMode ? [] : props.data;
|
|
2092
2204
|
const itemToString = isChildrenMode ? (_item) => "" : props.itemToString;
|
|
@@ -2108,29 +2220,29 @@ function MultiSearchableSelect(props) {
|
|
|
2108
2220
|
const defaultSelectedItemIds = props.defaultSelectedItemIds;
|
|
2109
2221
|
const onSelectedItemIdsChange = props.onSelectedItemIdsChange;
|
|
2110
2222
|
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
2111
|
-
const [open, setOpen] =
|
|
2112
|
-
const [internalInputValue, setInternalInputValue] =
|
|
2113
|
-
const skipNextInputChangeRef =
|
|
2114
|
-
const virtualizerRef =
|
|
2223
|
+
const [open, setOpen] = React12.useState(false);
|
|
2224
|
+
const [internalInputValue, setInternalInputValue] = React12.useState("");
|
|
2225
|
+
const skipNextInputChangeRef = React12.useRef(false);
|
|
2226
|
+
const virtualizerRef = React12.useRef(null);
|
|
2115
2227
|
const isControlled = selectedItemIds !== void 0;
|
|
2116
|
-
const idsToItems =
|
|
2228
|
+
const idsToItems = React12.useCallback(
|
|
2117
2229
|
(ids) => ids.map((id2) => data.find((d) => d.id === id2)).filter((d) => d != null),
|
|
2118
2230
|
[data]
|
|
2119
2231
|
);
|
|
2120
|
-
const [internalValue, setInternalValue] =
|
|
2232
|
+
const [internalValue, setInternalValue] = React12.useState(
|
|
2121
2233
|
() => defaultSelectedItemIds ? idsToItems(defaultSelectedItemIds) : []
|
|
2122
2234
|
);
|
|
2123
2235
|
const value = isControlled ? idsToItems(selectedItemIds) : internalValue;
|
|
2124
|
-
const visibleData =
|
|
2236
|
+
const visibleData = React12.useMemo(
|
|
2125
2237
|
() => removeSelectedItems ? data.filter((item) => !value.some((v) => v.id === item.id)) : data,
|
|
2126
2238
|
[data, value, removeSelectedItems]
|
|
2127
2239
|
);
|
|
2128
|
-
const groups =
|
|
2240
|
+
const groups = React12.useMemo(
|
|
2129
2241
|
() => groupBy ? groupItems(visibleData, groupBy) : null,
|
|
2130
2242
|
[visibleData, groupBy]
|
|
2131
2243
|
);
|
|
2132
2244
|
const currentInputValue = internalInputValue;
|
|
2133
|
-
const creatableSentinel =
|
|
2245
|
+
const creatableSentinel = React12.useMemo(() => {
|
|
2134
2246
|
if (!creatableProp) return null;
|
|
2135
2247
|
const trimmed = currentInputValue.trim();
|
|
2136
2248
|
if (!trimmed) return null;
|
|
@@ -2141,7 +2253,7 @@ function MultiSearchableSelect(props) {
|
|
|
2141
2253
|
if (exactExists) return null;
|
|
2142
2254
|
return makeCreatableSentinel(trimmed);
|
|
2143
2255
|
}, [creatableProp, currentInputValue, data, itemToString]);
|
|
2144
|
-
const flatItems =
|
|
2256
|
+
const flatItems = React12.useMemo(() => {
|
|
2145
2257
|
if (!groups || !selectHeadings && !selectAll) return null;
|
|
2146
2258
|
const rows = [];
|
|
2147
2259
|
if (selectAll) rows.push(SELECT_ALL_SENTINEL2);
|
|
@@ -2285,7 +2397,7 @@ function MultiSearchableSelect(props) {
|
|
|
2285
2397
|
const rootItems = creatableSentinel && Array.isArray(baseItems) ? [...baseItems, creatableSentinel] : baseItems;
|
|
2286
2398
|
const hasSentinels = selectAll || selectHeadings;
|
|
2287
2399
|
const rootValue = hasSentinels ? [...value] : value;
|
|
2288
|
-
return /* @__PURE__ */ jsxs9(Field, { children: [
|
|
2400
|
+
return /* @__PURE__ */ jsxs9(Field, { $fullWidth: fullWidth, children: [
|
|
2289
2401
|
/* @__PURE__ */ jsx11("div", { ref: containerRef, style: { position: "relative" } }),
|
|
2290
2402
|
/* @__PURE__ */ jsxs9(
|
|
2291
2403
|
Combobox6.Root,
|
|
@@ -2318,10 +2430,10 @@ function MultiSearchableSelect(props) {
|
|
|
2318
2430
|
if (!item || !virt) return;
|
|
2319
2431
|
const isStart = index === 0;
|
|
2320
2432
|
const isEnd = index === virt.options.count - 1;
|
|
2321
|
-
if (reason === "
|
|
2433
|
+
if (reason === "keyboard" && (isStart || isEnd)) {
|
|
2322
2434
|
queueMicrotask(() => {
|
|
2323
2435
|
virt.scrollToIndex(index, {
|
|
2324
|
-
align:
|
|
2436
|
+
align: isStart ? "start" : "end"
|
|
2325
2437
|
});
|
|
2326
2438
|
});
|
|
2327
2439
|
}
|
|
@@ -2353,6 +2465,9 @@ function MultiSearchableSelect(props) {
|
|
|
2353
2465
|
{
|
|
2354
2466
|
id,
|
|
2355
2467
|
"aria-describedby": ariaDescribedBy,
|
|
2468
|
+
"aria-invalid": isInvalid || void 0,
|
|
2469
|
+
"aria-required": props.required || void 0,
|
|
2470
|
+
$isInvalid: isInvalid,
|
|
2356
2471
|
children: [
|
|
2357
2472
|
renderSelection ? renderSelection(value) : value.length > 0 ? (() => {
|
|
2358
2473
|
const visibleItems = maxSelections != null ? value.slice(0, maxSelections) : value;
|
|
@@ -2413,12 +2528,12 @@ function MultiSearchableSelect(props) {
|
|
|
2413
2528
|
measureRef
|
|
2414
2529
|
) : void 0
|
|
2415
2530
|
}
|
|
2416
|
-
) : children ? children : flatItems ? (row) => renderSentinelRow(row) : groups ? (group, index) => {
|
|
2531
|
+
) : children ? children : flatItems ? ((row) => renderSentinelRow(row)) : groups ? ((group, index) => {
|
|
2417
2532
|
if (isCreatableSentinel(group)) {
|
|
2418
2533
|
return renderCreatableItem(group);
|
|
2419
2534
|
}
|
|
2420
2535
|
const g = group;
|
|
2421
|
-
return /* @__PURE__ */ jsxs9(
|
|
2536
|
+
return /* @__PURE__ */ jsxs9(React12.Fragment, { children: [
|
|
2422
2537
|
/* @__PURE__ */ jsxs9(ComboboxGroup, { items: g.items, children: [
|
|
2423
2538
|
/* @__PURE__ */ jsx11(ComboboxGroupLabel, { children: renderGroupHeading ? renderGroupHeading(g.value) : g.value }),
|
|
2424
2539
|
/* @__PURE__ */ jsx11(Combobox6.Collection, { children: (item) => /* @__PURE__ */ jsx11(
|
|
@@ -2436,7 +2551,7 @@ function MultiSearchableSelect(props) {
|
|
|
2436
2551
|
] }),
|
|
2437
2552
|
index < groups.length - 1 && /* @__PURE__ */ jsx11(ComboboxSeparator, {})
|
|
2438
2553
|
] }, g.value);
|
|
2439
|
-
} : (item) => {
|
|
2554
|
+
}) : ((item) => {
|
|
2440
2555
|
if (isCreatableSentinel(item)) {
|
|
2441
2556
|
return renderCreatableItem(item);
|
|
2442
2557
|
}
|
|
@@ -2453,7 +2568,7 @@ function MultiSearchableSelect(props) {
|
|
|
2453
2568
|
},
|
|
2454
2569
|
dataItem.id
|
|
2455
2570
|
);
|
|
2456
|
-
}
|
|
2571
|
+
})
|
|
2457
2572
|
}
|
|
2458
2573
|
)
|
|
2459
2574
|
]
|
|
@@ -2464,7 +2579,426 @@ function MultiSearchableSelect(props) {
|
|
|
2464
2579
|
)
|
|
2465
2580
|
] });
|
|
2466
2581
|
}
|
|
2582
|
+
|
|
2583
|
+
// src/v3/ActionMenu.tsx
|
|
2584
|
+
import * as React13 from "react";
|
|
2585
|
+
import { Menu as Menu2 } from "@base-ui/react/menu";
|
|
2586
|
+
import Radio3 from "@sproutsocial/seeds-react-radio";
|
|
2587
|
+
import Checkbox4 from "@sproutsocial/seeds-react-checkbox";
|
|
2588
|
+
import { Icon as Icon5 } from "@sproutsocial/seeds-react-icon";
|
|
2589
|
+
|
|
2590
|
+
// src/v3/ActionMenuStyles.tsx
|
|
2591
|
+
import { Menu } from "@base-ui/react/menu";
|
|
2592
|
+
import styled8, { css as css3 } from "styled-components";
|
|
2593
|
+
import "@sproutsocial/seeds-react-mixins";
|
|
2594
|
+
var ActionMenuTrigger = styled8(Menu.Trigger)``;
|
|
2595
|
+
var ActionMenuPositioner = styled8(Menu.Positioner)`
|
|
2596
|
+
min-width: var(--anchor-width);
|
|
2597
|
+
z-index: 7;
|
|
2598
|
+
`;
|
|
2599
|
+
var ActionMenuPopup = styled8(Menu.Popup).attrs({
|
|
2600
|
+
"data-base-ui-swipe-ignore": ""
|
|
2601
|
+
})`
|
|
2602
|
+
font-family: ${({ theme }) => theme.fontFamily};
|
|
2603
|
+
background: ${({ theme }) => theme.colors.container.background.base};
|
|
2604
|
+
border: 1px solid ${({ theme }) => theme.colors.container.border.base};
|
|
2605
|
+
border-radius: ${({ theme }) => theme.radii[500]};
|
|
2606
|
+
box-shadow: ${({ theme }) => theme.shadows.low};
|
|
2607
|
+
outline: none;
|
|
2608
|
+
max-height: min(var(--available-height, 400px), 400px);
|
|
2609
|
+
overflow-y: auto;
|
|
2610
|
+
padding: ${({ theme }) => theme.space[300]};
|
|
2611
|
+
|
|
2612
|
+
&[data-open] {
|
|
2613
|
+
animation: action-menu-popup-in 120ms ease-out;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
&[data-closed] {
|
|
2617
|
+
animation: action-menu-popup-out 100ms ease-in;
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2620
|
+
@keyframes action-menu-popup-in {
|
|
2621
|
+
from {
|
|
2622
|
+
opacity: 0;
|
|
2623
|
+
transform: scale(0.95);
|
|
2624
|
+
}
|
|
2625
|
+
to {
|
|
2626
|
+
opacity: 1;
|
|
2627
|
+
transform: scale(1);
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
@keyframes action-menu-popup-out {
|
|
2632
|
+
from {
|
|
2633
|
+
opacity: 1;
|
|
2634
|
+
transform: scale(1);
|
|
2635
|
+
}
|
|
2636
|
+
to {
|
|
2637
|
+
opacity: 0;
|
|
2638
|
+
transform: scale(0.95);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
`;
|
|
2642
|
+
var ActionMenuGroup = styled8(Menu.Group)`
|
|
2643
|
+
display: block;
|
|
2644
|
+
`;
|
|
2645
|
+
var ActionMenuGroupLabel = styled8(Menu.GroupLabel)`
|
|
2646
|
+
padding: ${({ theme }) => `${theme.space[300]}`};
|
|
2647
|
+
font-size: ${({ theme }) => theme.typography[100].fontSize};
|
|
2648
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
2649
|
+
`;
|
|
2650
|
+
var ActionMenuSeparator = styled8(Menu.Separator)`
|
|
2651
|
+
height: 1px;
|
|
2652
|
+
margin: ${({ theme }) => `${theme.space[300]} -${theme.space[300]}`};
|
|
2653
|
+
background: ${({ theme }) => theme.colors.container.border.base};
|
|
2654
|
+
`;
|
|
2655
|
+
var menuItemStyles = css3`
|
|
2656
|
+
box-sizing: border-box;
|
|
2657
|
+
display: block;
|
|
2658
|
+
width: 100%;
|
|
2659
|
+
border-radius: ${({ theme }) => theme.radii[500]};
|
|
2660
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.base};
|
|
2661
|
+
border: 1px solid ${({ theme }) => theme.colors.listItem.background.base};
|
|
2662
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
2663
|
+
font-family: ${({ theme }) => theme.fontFamily};
|
|
2664
|
+
font-weight: ${({ theme }) => theme.fontWeights.normal};
|
|
2665
|
+
text-align: left;
|
|
2666
|
+
text-decoration: none;
|
|
2667
|
+
padding: ${({ theme }) => theme.space[300]};
|
|
2668
|
+
outline: 0;
|
|
2669
|
+
${({ theme }) => theme.typography[200]};
|
|
2670
|
+
transition: all ${({ theme }) => theme.duration.fast};
|
|
2671
|
+
cursor: pointer;
|
|
2672
|
+
user-select: none;
|
|
2673
|
+
|
|
2674
|
+
&[data-highlighted] {
|
|
2675
|
+
border-color: ${({ theme }) => theme.colors.listItem.border.base};
|
|
2676
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.hover};
|
|
2677
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
2678
|
+
text-decoration: none;
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
&[data-disabled] {
|
|
2682
|
+
cursor: not-allowed;
|
|
2683
|
+
opacity: 0.4;
|
|
2684
|
+
}
|
|
2685
|
+
`;
|
|
2686
|
+
var StyledMenuItem = styled8(Menu.Item)`
|
|
2687
|
+
${menuItemStyles}
|
|
2688
|
+
`;
|
|
2689
|
+
var StyledCheckboxItem = styled8(Menu.CheckboxItem)`
|
|
2690
|
+
${menuItemStyles}
|
|
2691
|
+
display: flex;
|
|
2692
|
+
align-items: center;
|
|
2693
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
2694
|
+
`;
|
|
2695
|
+
var StyledRadioItem = styled8(Menu.RadioItem)`
|
|
2696
|
+
${menuItemStyles}
|
|
2697
|
+
display: flex;
|
|
2698
|
+
align-items: center;
|
|
2699
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
2700
|
+
`;
|
|
2701
|
+
var StyledCheckboxItemIndicator = styled8(Menu.CheckboxItemIndicator)`
|
|
2702
|
+
display: flex;
|
|
2703
|
+
align-items: center;
|
|
2704
|
+
width: 16px;
|
|
2705
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
2706
|
+
`;
|
|
2707
|
+
var StyledRadioItemIndicator = styled8(Menu.RadioItemIndicator)`
|
|
2708
|
+
display: flex;
|
|
2709
|
+
align-items: center;
|
|
2710
|
+
width: 16px;
|
|
2711
|
+
color: ${({ theme }) => theme.colors.text.body};
|
|
2712
|
+
`;
|
|
2713
|
+
var StyledSubmenuTrigger = styled8(Menu.SubmenuTrigger)`
|
|
2714
|
+
${menuItemStyles}
|
|
2715
|
+
display: flex;
|
|
2716
|
+
align-items: center;
|
|
2717
|
+
gap: ${({ theme }) => theme.space[300]};
|
|
2718
|
+
justify-content: space-between;
|
|
2719
|
+
|
|
2720
|
+
&[data-popup-open] {
|
|
2721
|
+
border-color: ${({ theme }) => theme.colors.listItem.border.base};
|
|
2722
|
+
background-color: ${({ theme }) => theme.colors.listItem.background.hover};
|
|
2723
|
+
}
|
|
2724
|
+
`;
|
|
2725
|
+
var StyledLinkItem = styled8(Menu.LinkItem)`
|
|
2726
|
+
${menuItemStyles}
|
|
2727
|
+
`;
|
|
2728
|
+
|
|
2729
|
+
// src/v3/ActionMenu.tsx
|
|
2730
|
+
import { Fragment as Fragment11, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2731
|
+
function ActionMenu({
|
|
2732
|
+
trigger,
|
|
2733
|
+
children,
|
|
2734
|
+
open,
|
|
2735
|
+
defaultOpen,
|
|
2736
|
+
onOpenChange,
|
|
2737
|
+
disabled
|
|
2738
|
+
}) {
|
|
2739
|
+
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
2740
|
+
return /* @__PURE__ */ jsxs10(
|
|
2741
|
+
Menu2.Root,
|
|
2742
|
+
{
|
|
2743
|
+
open,
|
|
2744
|
+
defaultOpen,
|
|
2745
|
+
onOpenChange,
|
|
2746
|
+
children: [
|
|
2747
|
+
/* @__PURE__ */ jsx12("div", { ref: containerRef, style: { position: "relative" } }),
|
|
2748
|
+
/* @__PURE__ */ jsx12(ActionMenuTrigger, { render: trigger, disabled }),
|
|
2749
|
+
/* @__PURE__ */ jsx12(Menu2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx12(ActionMenuPositioner, { sideOffset: 8, children: /* @__PURE__ */ jsx12(ActionMenuPopup, { children }) }) })
|
|
2750
|
+
]
|
|
2751
|
+
}
|
|
2752
|
+
);
|
|
2753
|
+
}
|
|
2754
|
+
function MenuGroup({
|
|
2755
|
+
children,
|
|
2756
|
+
label,
|
|
2757
|
+
showSeparator = false
|
|
2758
|
+
}) {
|
|
2759
|
+
return /* @__PURE__ */ jsxs10(Fragment11, { children: [
|
|
2760
|
+
/* @__PURE__ */ jsxs10(ActionMenuGroup, { children: [
|
|
2761
|
+
label && /* @__PURE__ */ jsx12(ActionMenuGroupLabel, { children: label }),
|
|
2762
|
+
children
|
|
2763
|
+
] }),
|
|
2764
|
+
showSeparator && /* @__PURE__ */ jsx12(ActionMenuSeparator, {})
|
|
2765
|
+
] });
|
|
2766
|
+
}
|
|
2767
|
+
function MenuRadioGroup({
|
|
2768
|
+
children,
|
|
2769
|
+
value,
|
|
2770
|
+
defaultValue,
|
|
2771
|
+
onValueChange
|
|
2772
|
+
}) {
|
|
2773
|
+
return /* @__PURE__ */ jsx12(
|
|
2774
|
+
Menu2.RadioGroup,
|
|
2775
|
+
{
|
|
2776
|
+
value,
|
|
2777
|
+
defaultValue,
|
|
2778
|
+
onValueChange,
|
|
2779
|
+
children
|
|
2780
|
+
}
|
|
2781
|
+
);
|
|
2782
|
+
}
|
|
2783
|
+
function MenuItem(props) {
|
|
2784
|
+
const generatedId = React13.useId();
|
|
2785
|
+
if (props.type === "checkbox") {
|
|
2786
|
+
const {
|
|
2787
|
+
children: children2,
|
|
2788
|
+
checked,
|
|
2789
|
+
defaultChecked,
|
|
2790
|
+
onCheckedChange,
|
|
2791
|
+
disabled: disabled2,
|
|
2792
|
+
closeOnClick: closeOnClick2 = false,
|
|
2793
|
+
id
|
|
2794
|
+
} = props;
|
|
2795
|
+
const itemId = id ?? `checkbox-menu-item-${generatedId}`;
|
|
2796
|
+
return /* @__PURE__ */ jsxs10(
|
|
2797
|
+
StyledCheckboxItem,
|
|
2798
|
+
{
|
|
2799
|
+
checked,
|
|
2800
|
+
defaultChecked,
|
|
2801
|
+
onCheckedChange,
|
|
2802
|
+
disabled: disabled2,
|
|
2803
|
+
closeOnClick: closeOnClick2,
|
|
2804
|
+
children: [
|
|
2805
|
+
/* @__PURE__ */ jsx12(
|
|
2806
|
+
StyledCheckboxItemIndicator,
|
|
2807
|
+
{
|
|
2808
|
+
keepMounted: true,
|
|
2809
|
+
render: (_indicatorProps, state) => /* @__PURE__ */ jsx12(
|
|
2810
|
+
Checkbox4,
|
|
2811
|
+
{
|
|
2812
|
+
checked: state.checked,
|
|
2813
|
+
onChange: () => {
|
|
2814
|
+
},
|
|
2815
|
+
tabIndex: -1,
|
|
2816
|
+
id: itemId,
|
|
2817
|
+
name: "menu-checkbox-item"
|
|
2818
|
+
}
|
|
2819
|
+
)
|
|
2820
|
+
}
|
|
2821
|
+
),
|
|
2822
|
+
children2
|
|
2823
|
+
]
|
|
2824
|
+
}
|
|
2825
|
+
);
|
|
2826
|
+
}
|
|
2827
|
+
if (props.type === "radio") {
|
|
2828
|
+
const { children: children2, value, disabled: disabled2, closeOnClick: closeOnClick2 = false } = props;
|
|
2829
|
+
return /* @__PURE__ */ jsxs10(
|
|
2830
|
+
StyledRadioItem,
|
|
2831
|
+
{
|
|
2832
|
+
value,
|
|
2833
|
+
disabled: disabled2,
|
|
2834
|
+
closeOnClick: closeOnClick2,
|
|
2835
|
+
children: [
|
|
2836
|
+
/* @__PURE__ */ jsx12(
|
|
2837
|
+
StyledRadioItemIndicator,
|
|
2838
|
+
{
|
|
2839
|
+
keepMounted: true,
|
|
2840
|
+
render: (_indicatorProps, state) => /* @__PURE__ */ jsx12(
|
|
2841
|
+
Radio3,
|
|
2842
|
+
{
|
|
2843
|
+
checked: state.checked,
|
|
2844
|
+
onChange: () => {
|
|
2845
|
+
},
|
|
2846
|
+
tabIndex: -1,
|
|
2847
|
+
id: `radio-menu-item-${value}`,
|
|
2848
|
+
name: "menu-radio-item"
|
|
2849
|
+
}
|
|
2850
|
+
)
|
|
2851
|
+
}
|
|
2852
|
+
),
|
|
2853
|
+
children2
|
|
2854
|
+
]
|
|
2855
|
+
}
|
|
2856
|
+
);
|
|
2857
|
+
}
|
|
2858
|
+
const {
|
|
2859
|
+
children,
|
|
2860
|
+
onClick,
|
|
2861
|
+
disabled,
|
|
2862
|
+
closeOnClick = true,
|
|
2863
|
+
href,
|
|
2864
|
+
target
|
|
2865
|
+
} = props;
|
|
2866
|
+
if (href) {
|
|
2867
|
+
return /* @__PURE__ */ jsx12(StyledLinkItem, { href, target, closeOnClick, children });
|
|
2868
|
+
}
|
|
2869
|
+
return /* @__PURE__ */ jsx12(
|
|
2870
|
+
StyledMenuItem,
|
|
2871
|
+
{
|
|
2872
|
+
onClick,
|
|
2873
|
+
disabled,
|
|
2874
|
+
closeOnClick,
|
|
2875
|
+
children
|
|
2876
|
+
}
|
|
2877
|
+
);
|
|
2878
|
+
}
|
|
2879
|
+
function MenuSub({
|
|
2880
|
+
trigger,
|
|
2881
|
+
children,
|
|
2882
|
+
open,
|
|
2883
|
+
defaultOpen,
|
|
2884
|
+
onOpenChange,
|
|
2885
|
+
closeParentOnEsc = false
|
|
2886
|
+
}) {
|
|
2887
|
+
const { containerRef, portalContainer } = useSeedsPortalContainer();
|
|
2888
|
+
return /* @__PURE__ */ jsxs10(
|
|
2889
|
+
Menu2.SubmenuRoot,
|
|
2890
|
+
{
|
|
2891
|
+
open,
|
|
2892
|
+
defaultOpen,
|
|
2893
|
+
onOpenChange,
|
|
2894
|
+
closeParentOnEsc,
|
|
2895
|
+
children: [
|
|
2896
|
+
/* @__PURE__ */ jsx12("div", { ref: containerRef, style: { position: "relative" } }),
|
|
2897
|
+
trigger,
|
|
2898
|
+
/* @__PURE__ */ jsx12(Menu2.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx12(ActionMenuPositioner, { sideOffset: getOffset, alignOffset: getOffset, children: /* @__PURE__ */ jsx12(ActionMenuPopup, { children }) }) })
|
|
2899
|
+
]
|
|
2900
|
+
}
|
|
2901
|
+
);
|
|
2902
|
+
}
|
|
2903
|
+
function getOffset({ side }) {
|
|
2904
|
+
return side === "top" || side === "bottom" ? 4 : -8;
|
|
2905
|
+
}
|
|
2906
|
+
function MenuSubTrigger({
|
|
2907
|
+
children,
|
|
2908
|
+
disabled,
|
|
2909
|
+
label,
|
|
2910
|
+
openOnHover = true
|
|
2911
|
+
}) {
|
|
2912
|
+
return /* @__PURE__ */ jsxs10(
|
|
2913
|
+
StyledSubmenuTrigger,
|
|
2914
|
+
{
|
|
2915
|
+
disabled,
|
|
2916
|
+
label,
|
|
2917
|
+
openOnHover,
|
|
2918
|
+
children: [
|
|
2919
|
+
children,
|
|
2920
|
+
/* @__PURE__ */ jsx12(Icon5, { name: "chevron-right-outline", fixedWidth: true, "aria-hidden": true })
|
|
2921
|
+
]
|
|
2922
|
+
}
|
|
2923
|
+
);
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
// src/v3/MenuButton.tsx
|
|
2927
|
+
import "react";
|
|
2928
|
+
import "@sproutsocial/seeds-react-button";
|
|
2929
|
+
import { Icon as Icon6 } from "@sproutsocial/seeds-react-icon";
|
|
2930
|
+
|
|
2931
|
+
// src/v3/MenuButtonStyles.tsx
|
|
2932
|
+
import styled9 from "styled-components";
|
|
2933
|
+
import { Button } from "@sproutsocial/seeds-react-button";
|
|
2934
|
+
var MenuButtonContainer = styled9.div`
|
|
2935
|
+
display: inline-flex;
|
|
2936
|
+
gap: 1px;
|
|
2937
|
+
`;
|
|
2938
|
+
var MainButton = styled9(Button)`
|
|
2939
|
+
&& {
|
|
2940
|
+
border-top-right-radius: 0;
|
|
2941
|
+
border-bottom-right-radius: 0;
|
|
2942
|
+
}
|
|
2943
|
+
`;
|
|
2944
|
+
var TriggerButton = styled9(Button)`
|
|
2945
|
+
&& {
|
|
2946
|
+
border-top-left-radius: 0;
|
|
2947
|
+
border-bottom-left-radius: 0;
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
.Icon-svg {
|
|
2951
|
+
transition: transform ${({ theme }) => theme.duration.fast} ease;
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
&[data-popup-open] .Icon-svg {
|
|
2955
|
+
transform: rotate(180deg);
|
|
2956
|
+
}
|
|
2957
|
+
`;
|
|
2958
|
+
|
|
2959
|
+
// src/v3/MenuButton.tsx
|
|
2960
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2961
|
+
function MenuButton({
|
|
2962
|
+
actionMenu,
|
|
2963
|
+
appearance = "primary",
|
|
2964
|
+
size,
|
|
2965
|
+
disabled,
|
|
2966
|
+
menuButtonAriaLabel,
|
|
2967
|
+
children,
|
|
2968
|
+
...rest
|
|
2969
|
+
}) {
|
|
2970
|
+
return /* @__PURE__ */ jsxs11(MenuButtonContainer, { children: [
|
|
2971
|
+
/* @__PURE__ */ jsx13(
|
|
2972
|
+
MainButton,
|
|
2973
|
+
{
|
|
2974
|
+
appearance,
|
|
2975
|
+
size,
|
|
2976
|
+
disabled,
|
|
2977
|
+
...rest,
|
|
2978
|
+
children
|
|
2979
|
+
}
|
|
2980
|
+
),
|
|
2981
|
+
/* @__PURE__ */ jsx13(
|
|
2982
|
+
ActionMenu,
|
|
2983
|
+
{
|
|
2984
|
+
disabled,
|
|
2985
|
+
trigger: /* @__PURE__ */ jsx13(
|
|
2986
|
+
TriggerButton,
|
|
2987
|
+
{
|
|
2988
|
+
appearance,
|
|
2989
|
+
size,
|
|
2990
|
+
disabled,
|
|
2991
|
+
ariaLabel: menuButtonAriaLabel,
|
|
2992
|
+
children: /* @__PURE__ */ jsx13(Icon6, { name: "chevron-down-outline", fixedWidth: true, "aria-hidden": true })
|
|
2993
|
+
}
|
|
2994
|
+
),
|
|
2995
|
+
children: actionMenu
|
|
2996
|
+
}
|
|
2997
|
+
)
|
|
2998
|
+
] });
|
|
2999
|
+
}
|
|
2467
3000
|
export {
|
|
3001
|
+
ActionMenu,
|
|
2468
3002
|
ComboboxActionButtons,
|
|
2469
3003
|
ComboboxClear,
|
|
2470
3004
|
ComboboxEmpty,
|
|
@@ -2487,6 +3021,12 @@ export {
|
|
|
2487
3021
|
ComboboxTokenInput,
|
|
2488
3022
|
ComboboxTokenInputGroup,
|
|
2489
3023
|
ComboboxTrigger,
|
|
3024
|
+
MenuButton,
|
|
3025
|
+
MenuGroup,
|
|
3026
|
+
MenuItem,
|
|
3027
|
+
MenuRadioGroup,
|
|
3028
|
+
MenuSub,
|
|
3029
|
+
MenuSubTrigger,
|
|
2490
3030
|
MultiCombobox,
|
|
2491
3031
|
MultiSearchableSelect,
|
|
2492
3032
|
MultiSelect,
|