@mirohq/design-system-dropdown-menu 3.3.0-dropdown.0 → 3.3.0-dropdown.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/dist/module.js CHANGED
@@ -1,118 +1,320 @@
1
- import React, { useState } from 'react';
1
+ import React, { createContext, useState, useRef, useCallback, useContext, useEffect, useMemo } from 'react';
2
2
  import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';
3
3
  import { Portal as Portal$1 } from '@radix-ui/react-dropdown-menu';
4
- import { IconProhibit, IconCheckMark } from '@mirohq/design-system-icons';
4
+ import { IconProhibit, IconCheckMark, IconChevronRight } from '@mirohq/design-system-icons';
5
+ import { addPropsToChildren, booleanify } from '@mirohq/design-system-utils';
5
6
  import { Primitive } from '@mirohq/design-system-primitive';
6
7
  import { styled, theme } from '@mirohq/design-system-stitches';
7
8
  import { focus, animations } from '@mirohq/design-system-styles';
8
- import { Switch } from '@mirohq/design-system-switch';
9
+ import { ScrollArea } from '@mirohq/design-system-scroll-area';
10
+ import { styles, Thumb } from '@mirohq/design-system-base-switch';
11
+ import { styles as styles$1, isIconComponent } from '@mirohq/design-system-base-icon';
12
+
13
+ const ItemDescription = styled(Primitive.div, {
14
+ display: "-webkit-box",
15
+ width: "100%",
16
+ WebkitBoxOrient: "vertical",
17
+ WebkitLineClamp: 2,
18
+ overflow: "hidden",
19
+ gridArea: "item-description",
20
+ fontSize: "$150",
21
+ color: "$text-neutrals-subtle"
22
+ });
23
+
24
+ const LeftSlot = styled(Primitive.div, {
25
+ display: "flex",
26
+ alignItems: "center",
27
+ justifyContent: "center",
28
+ marginRight: "$100",
29
+ gridArea: "left-slot"
30
+ });
31
+
32
+ const StyledIllustrationSlot = styled(LeftSlot, {
33
+ width: "$13"
34
+ });
35
+
36
+ const Context$1 = createContext({
37
+ rightSlotMount: () => 0,
38
+ rightSlotDestroy: () => {
39
+ },
40
+ containerSpacing: "medium"
41
+ });
42
+ const ContentProvider = ({
43
+ children,
44
+ containerSpacing = "medium"
45
+ }) => {
46
+ const [maxWidth, setMaxWidth] = useState(0);
47
+ const maxRef = useRef(0);
48
+ const indexRef = useRef(0);
49
+ const widthMapRef = useRef(/* @__PURE__ */ new Map());
50
+ const updateMaxWith = useCallback((value) => {
51
+ maxRef.current = value;
52
+ setMaxWidth(value);
53
+ }, []);
54
+ const rightSlotMount = useCallback(
55
+ (width) => {
56
+ indexRef.current++;
57
+ widthMapRef.current.set(indexRef.current, width);
58
+ if (width > maxRef.current) {
59
+ updateMaxWith(width);
60
+ }
61
+ return indexRef.current;
62
+ },
63
+ [updateMaxWith]
64
+ );
65
+ const rightSlotDestroy = useCallback(
66
+ (index) => {
67
+ widthMapRef.current.delete(index);
68
+ if (widthMapRef.current.size === 0) {
69
+ updateMaxWith(0);
70
+ } else {
71
+ const maximum = Math.max(...Array.from(widthMapRef.current.values()));
72
+ updateMaxWith(maximum);
73
+ }
74
+ },
75
+ [updateMaxWith]
76
+ );
77
+ const formattedChildren = addPropsToChildren(children, () => true, {
78
+ UNSAFE_style: {
79
+ "--right-slot-max-width": `${Math.ceil(maxWidth)}px`
80
+ }
81
+ });
82
+ return /* @__PURE__ */ React.createElement(Context$1.Provider, {
83
+ value: {
84
+ rightSlotMount,
85
+ rightSlotDestroy,
86
+ containerSpacing
87
+ }
88
+ }, formattedChildren);
89
+ };
90
+ const useContent = () => useContext(Context$1);
91
+
92
+ const StyledRightSlot = styled(Primitive.div, {
93
+ display: "flex",
94
+ alignItems: "center",
95
+ justifyContent: "center",
96
+ marginLeft: "auto",
97
+ paddingLeft: "$200",
98
+ gridArea: "right-slot",
99
+ height: "$5",
100
+ width: "$7",
101
+ minWidth: "max-content",
102
+ textAlign: "right",
103
+ "&:empty": {
104
+ paddingLeft: "$none"
105
+ }
106
+ });
107
+
108
+ const RightSlot = (props) => {
109
+ const { rightSlotMount, rightSlotDestroy } = useContent();
110
+ const ref = useRef(null);
111
+ useEffect(() => {
112
+ if (ref.current !== null) {
113
+ const width = ref.current.getBoundingClientRect().width;
114
+ const index = rightSlotMount(width);
115
+ return () => rightSlotDestroy(index);
116
+ }
117
+ return () => {
118
+ };
119
+ }, [rightSlotMount, rightSlotDestroy, ref]);
120
+ return /* @__PURE__ */ React.createElement(StyledRightSlot, {
121
+ ref,
122
+ ...props
123
+ });
124
+ };
125
+
126
+ const HotkeySlot = styled(RightSlot, {
127
+ color: "$text-neutrals-subtle"
128
+ });
9
129
 
10
130
  const itemDefaults = {
11
131
  all: "unset",
12
132
  boxSizing: "border-box",
13
133
  fontSize: 14,
14
134
  lineHeight: "20px",
15
- color: "rgba(5, 0, 56, 1)",
135
+ color: "$text-neutrals",
16
136
  borderRadius: "$50",
17
- display: "flex",
18
- alignItems: "center",
19
- height: "$11",
20
- padding: "$100 $150",
137
+ display: "grid",
138
+ gridTemplateColumns: "auto 1fr minmax(auto, var(--right-slot-max-width))",
139
+ gridTemplateRows: "1fr auto",
140
+ gridTemplateAreas: `'left-slot item-text right-slot'
141
+ 'left-slot item-description right-slot'`,
142
+ alignItems: "start",
143
+ minHeight: "$10",
144
+ padding: "$100 $100",
21
145
  position: "relative",
22
146
  userSelect: "none",
23
147
  cursor: "pointer",
24
- "&[data-disabled]": {
25
- color: "rgba(9, 9, 9, 0.4)",
26
- pointerEvents: "none"
148
+ "&[data-no-left-slot]": {
149
+ gridTemplateColumns: "1fr minmax(auto, var(--right-slot-max-width))",
150
+ gridTemplateRows: "auto",
151
+ gridTemplateAreas: `'item-text right-slot'
152
+ 'item-description right-slot'`
153
+ },
154
+ "&:not(:last-child)": {
155
+ marginBottom: "$50"
156
+ },
157
+ "&:not(:first-child)": {
158
+ marginTop: "$50"
27
159
  },
28
160
  ...focus.defaults,
29
- "&:hover": {
30
- background: "rgba(232, 236, 255, 1)",
31
- color: "rgba(69, 91, 237, 1)",
32
- boxShadow: "none"
161
+ '&:disabled, &[aria-disabled="true"], &[data-disabled]': {
162
+ cursor: "default",
163
+ [`&, & ${ItemDescription}, & ${HotkeySlot}`]: {
164
+ color: "$text-neutrals-disabled"
165
+ },
166
+ [`& ${StyledIllustrationSlot}`]: {
167
+ filter: "grayscale(1)"
168
+ }
169
+ },
170
+ "&:disabled, &[data-disabled]": {
171
+ pointerEvents: "none"
172
+ },
173
+ '&:hover:not([aria-disabled="true"])': {
174
+ background: "$background-primary-subtle-hover",
175
+ color: "$text-primary-hover",
176
+ '&:not([aria-disabled="true"])': {
177
+ boxShadow: "none"
178
+ }
179
+ },
180
+ '&:active:not([aria-disabled="true"])': {
181
+ background: "$background-primary-subtle-active",
182
+ boxShadow: "none",
183
+ color: "$text-primary-active"
33
184
  },
34
185
  '&[tabindex="0"]': {
35
186
  zIndex: "1"
36
187
  }
37
188
  };
38
189
 
39
- const StyledIndicator = styled(Primitive.span, {});
40
- const checkboxItemStyles = {
190
+ const StyledIndicator = styled(Primitive.span, {
191
+ display: "flex",
192
+ alignItems: "center",
193
+ justifyContent: "center"
194
+ });
195
+ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
41
196
  ...itemDefaults,
42
197
  [`&[data-state="checked"] ${StyledIndicator}`]: {
43
198
  color: "$icon-primary"
44
199
  },
45
- [`&[data-state="checked"]:hover ${StyledIndicator}`]: {
200
+ [`&[data-state="checked"]:hover:not([aria-disabled="true"]) ${StyledIndicator}`]: {
46
201
  color: "$icon-primary-hover"
47
202
  },
48
- [`&[data-disabled] ${StyledIndicator}`]: {
203
+ [`
204
+ &[aria-disabled="true"] ${StyledIndicator},
205
+ &[data-disabled] ${StyledIndicator}
206
+ `]: {
49
207
  color: "$icon-neutrals-disabled"
50
208
  }
51
- };
52
- const StyledCheckboxItem = styled(
53
- RadixDropdownMenu.CheckboxItem,
54
- checkboxItemStyles
55
- );
56
-
57
- const IconSlot = styled(Primitive.div, {
58
- display: "flex",
59
- alignItems: "center",
60
- marginRight: "$100",
61
- width: "$6"
62
- });
63
- const RightSlot = styled(Primitive.div, {
64
- display: "flex",
65
- alignItems: "center",
66
- marginLeft: "auto",
67
- paddingLeft: "$200"
68
- });
69
- const ContentSlot = styled(Primitive.div, {
70
- display: "flex",
71
- alignItems: "center"
72
209
  });
73
210
 
74
- const CheckboxItemRoot = ({
75
- disabled = false,
76
- onChange,
211
+ const useAriaDisabled = ({
212
+ "aria-disabled": ariaDisabled,
213
+ onKeyDown,
77
214
  onSelect,
78
- ref,
79
- ...restProps
80
- }) => /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
81
- ...restProps,
82
- ref,
83
- disabled,
84
- onCheckedChange: onChange,
85
- onSelect: (event) => {
86
- event.preventDefault();
87
- onSelect == null ? void 0 : onSelect(event);
215
+ onPointerMove,
216
+ onClick
217
+ }, preventDefault = false) => useMemo(
218
+ () => ({
219
+ "aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
220
+ onKeyDown: (e) => {
221
+ if (booleanify(ariaDisabled) && e.code !== "ArrowUp" && e.code !== "ArrowDown") {
222
+ e.preventDefault();
223
+ e.stopPropagation();
224
+ return;
225
+ }
226
+ onKeyDown == null ? void 0 : onKeyDown(e);
227
+ },
228
+ onSelect: (e) => {
229
+ if (preventDefault) {
230
+ e.preventDefault();
231
+ }
232
+ if (booleanify(ariaDisabled)) {
233
+ e.preventDefault();
234
+ return;
235
+ }
236
+ onSelect == null ? void 0 : onSelect(e);
237
+ },
238
+ onPointerMove: (e) => {
239
+ if (booleanify(ariaDisabled)) {
240
+ e.preventDefault();
241
+ return;
242
+ }
243
+ onPointerMove == null ? void 0 : onPointerMove(e);
244
+ },
245
+ onClick: (e) => {
246
+ if (booleanify(ariaDisabled)) {
247
+ e.preventDefault();
248
+ return;
249
+ }
250
+ onClick == null ? void 0 : onClick(e);
251
+ }
252
+ }),
253
+ [ariaDisabled, onKeyDown, onSelect, onPointerMove, onClick, preventDefault]
254
+ );
255
+
256
+ const Context = createContext({
257
+ leftSlotMount: () => {
258
+ },
259
+ leftSlotDestroy: () => {
88
260
  }
89
261
  });
90
- const CheckboxItem = React.forwardRef(({ children, checked, disabled, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(CheckboxItemRoot, {
91
- ...restProps,
92
- checked,
93
- disabled,
94
- ref: forwardRef
95
- }, /* @__PURE__ */ React.createElement(ContentSlot, null, children), /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, disabled === true && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
96
- size: "small"
97
- }), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
98
- size: "small"
99
- })))));
100
-
101
- const GUTTER_TOKEN = 150;
102
- const CONTENT_GUTTER = parseInt(theme.space[GUTTER_TOKEN]);
262
+ const ItemProvider = ({
263
+ children
264
+ }) => {
265
+ const [hasSlot, setHasSlot] = useState(false);
266
+ const leftSlotMount = useCallback(() => {
267
+ setHasSlot(true);
268
+ }, []);
269
+ const leftSlotDestroy = useCallback(() => {
270
+ setHasSlot(false);
271
+ }, []);
272
+ const formattedChildren = hasSlot ? children : addPropsToChildren(children, () => true, {
273
+ "data-no-left-slot": ""
274
+ });
275
+ return /* @__PURE__ */ React.createElement(Context.Provider, {
276
+ value: {
277
+ leftSlotMount,
278
+ leftSlotDestroy
279
+ }
280
+ }, formattedChildren);
281
+ };
282
+ const useItem = () => useContext(Context);
283
+
284
+ const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled, ...restProps }, forwardRef) => {
285
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
286
+ const { "aria-disabled": ariaDisabled } = ariaDisabledProps;
287
+ return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
288
+ ...restProps,
289
+ ...ariaDisabledProps,
290
+ ref: forwardRef,
291
+ checked,
292
+ disabled,
293
+ onCheckedChange: onChange
294
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, (disabled === true || booleanify(ariaDisabled)) && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
295
+ weight: "thin",
296
+ css: { square: "$3", display: "block" }
297
+ }), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
298
+ css: { square: "$3", display: "block" }
299
+ })))));
300
+ });
301
+
302
+ const CONTENT_GUTTER = parseInt(theme.space[150]);
103
303
  const CONTENT_OFFSET = parseInt(theme.space[50]);
104
- const ITEM_WITHOUT_RIGHT_SLOT = `[role="menuitem"]:not(:has(${RightSlot}))`;
304
+ const CONTENT_BORDER_FOCUS_ITEM = "2px";
305
+ const CONTENT_PADDING = {
306
+ small: "$50 $150",
307
+ medium: "$150",
308
+ large: "$150 $300"
309
+ };
105
310
  const contentDefaults = {
106
311
  maxWidth: "$125",
107
- backgroundColor: "$white",
312
+ backgroundColor: "$background-neutrals-container",
108
313
  borderRadius: "$50",
109
- padding: `$${GUTTER_TOKEN}`,
110
314
  boxShadow: "$50",
111
- [`&:has(${RightSlot}) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
112
- paddingRight: "44px"
113
- },
114
- [`&:has([role="switch"]) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
115
- paddingRight: "56px"
315
+ "& [data-radix-scroll-area-viewport]": {
316
+ padding: `${CONTENT_BORDER_FOCUS_ITEM} $50 ${CONTENT_BORDER_FOCUS_ITEM} ${CONTENT_BORDER_FOCUS_ITEM}`,
317
+ boxSizing: "border-box"
116
318
  },
117
319
  "@media (prefers-reduced-motion: no-preference)": {
118
320
  animationDuration: "150ms",
@@ -145,7 +347,56 @@ const contentDefaults = {
145
347
  zIndex: "$dropdownMenu"
146
348
  };
147
349
 
148
- const StyledContent = styled(RadixDropdownMenu.Content, contentDefaults);
350
+ const StyledContent = styled(RadixDropdownMenu.Content, {
351
+ ...contentDefaults,
352
+ variants: {
353
+ containerSpacing: {
354
+ small: {
355
+ '&, [role="menu"]': {
356
+ padding: CONTENT_PADDING.small
357
+ }
358
+ },
359
+ medium: {
360
+ '&, [role="menu"]': {
361
+ padding: CONTENT_PADDING.medium
362
+ }
363
+ },
364
+ large: {
365
+ '&, [role="menu"]': {
366
+ padding: CONTENT_PADDING.large
367
+ }
368
+ }
369
+ }
370
+ }
371
+ });
372
+
373
+ const ScrollableContent = ({
374
+ children,
375
+ maxHeight,
376
+ overflow,
377
+ containerSpacing
378
+ }) => {
379
+ const getOverflowMaxHeight = useCallback(() => {
380
+ const [top, , bottom] = CONTENT_PADDING[containerSpacing].split(" ").map((value) => value.replace("$", ""));
381
+ const topBottom = top !== void 0 && bottom !== void 0 ? `var(--space-${top}) + var(--space-${bottom})` : `var(--space-${top}) + var(--space-${top})`;
382
+ const overflowMaxHeigh = overflow === "auto" ? `calc(var(--radix-dropdown-menu-content-available-height) - (${topBottom}))` : "auto";
383
+ const newMaxHeight = `calc(${maxHeight} - (${topBottom}))`;
384
+ return {
385
+ maxHeight: maxHeight === void 0 ? overflowMaxHeigh : newMaxHeight
386
+ };
387
+ }, [maxHeight, overflow, containerSpacing]);
388
+ if (overflow === "auto") {
389
+ return /* @__PURE__ */ React.createElement(ScrollArea, {
390
+ css: { margin: `-${CONTENT_BORDER_FOCUS_ITEM}` },
391
+ type: "always"
392
+ }, /* @__PURE__ */ React.createElement(ScrollArea.Viewport, {
393
+ css: { ...getOverflowMaxHeight() }
394
+ }, children), /* @__PURE__ */ React.createElement(ScrollArea.Scrollbar, {
395
+ orientation: "vertical"
396
+ }, /* @__PURE__ */ React.createElement(ScrollArea.Thumb, null)));
397
+ }
398
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, children);
399
+ };
149
400
 
150
401
  const Content = React.forwardRef(
151
402
  ({
@@ -158,8 +409,14 @@ const Content = React.forwardRef(
158
409
  avoidCollisions = true,
159
410
  sticky = "partial",
160
411
  hideWhenDetached = false,
412
+ containerSpacing = "medium",
413
+ overflow = "visible",
414
+ maxHeight,
415
+ children,
161
416
  ...restProps
162
- }, forwardRef) => /* @__PURE__ */ React.createElement(StyledContent, {
417
+ }, forwardRef) => /* @__PURE__ */ React.createElement(ContentProvider, {
418
+ containerSpacing
419
+ }, /* @__PURE__ */ React.createElement(StyledContent, {
163
420
  ...restProps,
164
421
  ref: forwardRef,
165
422
  loop,
@@ -170,29 +427,51 @@ const Content = React.forwardRef(
170
427
  avoidCollisions,
171
428
  collisionPadding,
172
429
  sticky,
173
- hideWhenDetached
174
- })
430
+ hideWhenDetached,
431
+ containerSpacing
432
+ }, /* @__PURE__ */ React.createElement(ScrollableContent, {
433
+ ...{ containerSpacing, maxHeight, overflow }
434
+ }, children)))
175
435
  );
176
436
 
177
- const StyledItem = styled(RadixDropdownMenu.Item, itemDefaults);
437
+ const StyledItem = styled(RadixDropdownMenu.Item, {
438
+ ...itemDefaults,
439
+ variants: {
440
+ hasRightSlot: {
441
+ true: {
442
+ paddingRight: "$600"
443
+ }
444
+ }
445
+ }
446
+ });
178
447
 
179
448
  const Item = React.forwardRef(
180
- ({ disabled = false, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledItem, {
181
- ...restProps,
182
- ref: forwardRef,
183
- disabled
184
- })
449
+ ({ disabled = false, ...restProps }, forwardRef) => {
450
+ const ariaDisabledProps = useAriaDisabled(restProps);
451
+ return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledItem, {
452
+ ...restProps,
453
+ ...ariaDisabledProps,
454
+ disabled,
455
+ ref: forwardRef
456
+ }));
457
+ }
185
458
  );
186
459
 
187
- const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(Item, {
188
- asChild: true,
189
- ref: forwardRef,
190
- ...restProps
191
- }, /* @__PURE__ */ React.createElement("a", {
192
- href
193
- }, children)));
460
+ const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef) => {
461
+ const ariaDisabledProps = useAriaDisabled(restProps);
462
+ return /* @__PURE__ */ React.createElement(Item, {
463
+ asChild: true,
464
+ ref: forwardRef,
465
+ ...restProps,
466
+ ...ariaDisabledProps
467
+ }, /* @__PURE__ */ React.createElement("a", {
468
+ href
469
+ }, children));
470
+ });
194
471
 
195
- const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup);
472
+ const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup, {
473
+ marginY: "$50"
474
+ });
196
475
 
197
476
  const RadioGroup = React.forwardRef((props, forwardRef) => {
198
477
  const { onChange, ...restProps } = props;
@@ -203,7 +482,7 @@ const RadioGroup = React.forwardRef((props, forwardRef) => {
203
482
  });
204
483
  });
205
484
 
206
- const StyledRadioContainer = styled(Primitive.span, {
485
+ const StyledRadioContainer = styled(Primitive.div, {
207
486
  display: "flex",
208
487
  alignItems: "center",
209
488
  justifyContent: "center",
@@ -213,7 +492,7 @@ const StyledRadioContainer = styled(Primitive.span, {
213
492
  border: "1px solid $border-neutrals",
214
493
  borderRadius: "$half"
215
494
  });
216
- const StyledPill = styled(Primitive.span, {
495
+ const StyledPill = styled(Primitive.div, {
217
496
  display: "none",
218
497
  width: "$2",
219
498
  height: "$2",
@@ -221,7 +500,7 @@ const StyledPill = styled(Primitive.span, {
221
500
  });
222
501
  const StyledProhibited = styled(IconProhibit, {
223
502
  display: "none",
224
- width: "$3"
503
+ width: "$3 !important"
225
504
  });
226
505
  const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
227
506
  ...itemDefaults,
@@ -233,37 +512,46 @@ const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
233
512
  backgroundColor: "$background-primary-prominent-selected"
234
513
  }
235
514
  },
236
- [`&:hover ${StyledRadioContainer}`]: {
515
+ [`&:hover:not([aria-disabled="true"]) ${StyledRadioContainer}`]: {
237
516
  borderColor: "$border-primary-hover",
238
517
  [`& ${StyledPill}`]: {
239
518
  backgroundColor: "$background-primary-prominent-hover"
240
519
  }
241
520
  },
242
- [`&[data-disabled] ${StyledRadioContainer}`]: {
521
+ [`
522
+ &[aria-disabled="true"] ${StyledRadioContainer},
523
+ &[data-disabled] ${StyledRadioContainer}
524
+ `]: {
243
525
  color: "$icon-neutrals-disabled",
244
526
  borderColor: "$border-neutrals-disabled",
245
527
  [`& ${StyledPill}`]: {
246
528
  backgroundColor: "$icon-neutrals-disabled"
247
529
  }
248
530
  },
249
- [`&[data-state="unchecked"][data-disabled] ${StyledProhibited}`]: {
250
- display: "block"
531
+ '&[data-state="unchecked"]': {
532
+ [`
533
+ &[aria-disabled="true"] ${StyledProhibited},
534
+ &[data-disabled] ${StyledProhibited}
535
+ `]: {
536
+ display: "flex"
537
+ }
251
538
  }
252
539
  });
253
540
 
254
- const RadioItem = React.forwardRef(({ disabled = false, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledRadioItem, {
255
- ...restProps,
256
- ref: forwardRef,
257
- disabled,
258
- onSelect: (event) => {
259
- event.preventDefault();
260
- onSelect == null ? void 0 : onSelect(event);
261
- }
262
- }, /* @__PURE__ */ React.createElement(ContentSlot, null, children), /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null)))));
541
+ const RadioItem = React.forwardRef(({ disabled = false, children, ...restProps }, forwardRef) => {
542
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
543
+ return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledRadioItem, {
544
+ ...restProps,
545
+ ...ariaDisabledProps,
546
+ disabled,
547
+ ref: forwardRef
548
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, {
549
+ weight: "thin"
550
+ })))));
551
+ });
263
552
 
264
553
  const StyledSeparator = styled(RadixDropdownMenu.Separator, {
265
- borderTop: "1px solid rgba(235, 235, 239, 1)",
266
- marginY: "$100"
554
+ borderTop: "1px solid $border-neutrals-subtle"
267
555
  });
268
556
 
269
557
  const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.createElement(StyledSeparator, {
@@ -271,33 +559,48 @@ const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.
271
559
  ref: forwardRef
272
560
  }));
273
561
 
562
+ const StyledSwitch = styled(Primitive.span, {
563
+ ...styles.default,
564
+ width: "$7",
565
+ height: "$4"
566
+ });
567
+ const StyledSwitchItem = styled(RadixDropdownMenu.CheckboxItem, {
568
+ ...itemDefaults,
569
+ [`&[data-state="checked"] ${StyledSwitch}`]: styles.checked,
570
+ [`&[data-state="checked"]:hover:not([aria-disabled="true"]) ${StyledSwitch}`]: styles.checkedHovered,
571
+ [`&:hover:not([aria-disabled="true"]) ${StyledSwitch}`]: styles.hovered,
572
+ [`
573
+ &[aria-disabled="true"] ${StyledSwitch},
574
+ &[data-disabled] ${StyledSwitch}
575
+ `]: styles.disabled
576
+ });
577
+
274
578
  const SwitchItem = React.forwardRef(
275
- ({ disabled = false, checked, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(CheckboxItemRoot, {
276
- ...restProps,
277
- ref: forwardRef,
278
- disabled,
279
- checked
280
- }, /* @__PURE__ */ React.createElement(ContentSlot, null, children), /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(Switch, {
281
- checked,
282
- disabled,
283
- onChange: (x) => x,
284
- value: ""
285
- })))
579
+ ({ disabled = false, checked, onChange, children, ...restProps }, forwardRef) => {
580
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
581
+ return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledSwitchItem, {
582
+ ...restProps,
583
+ ...ariaDisabledProps,
584
+ disabled,
585
+ checked,
586
+ onCheckedChange: onChange,
587
+ ref: forwardRef
588
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledSwitch, null, /* @__PURE__ */ React.createElement(Thumb, null)))));
589
+ }
286
590
  );
287
591
 
288
- const defaultStyles = {
289
- boxSizing: "border-box",
290
- cursor: "pointer",
291
- ...focus.defaults
292
- };
293
592
  const StyledTrigger = styled(RadixDropdownMenu.Trigger, {
294
593
  variants: {
295
594
  unstyled: {
296
595
  true: {
297
596
  all: "unset",
298
- ...defaultStyles
597
+ boxSizing: "border-box",
598
+ cursor: "pointer",
599
+ ...focus.defaults
299
600
  },
300
- false: defaultStyles
601
+ false: {
602
+ cursor: "pointer"
603
+ }
301
604
  }
302
605
  }
303
606
  });
@@ -310,26 +613,36 @@ const Trigger = React.forwardRef(({ asChild = false, onPress, onClick, ...restPr
310
613
  asChild
311
614
  }));
312
615
 
616
+ const StyledIconContainer = styled(Primitive.span, {
617
+ color: "$icon-neutrals-with-text",
618
+ display: "flex",
619
+ alignItems: "center"
620
+ });
313
621
  const StyledSubTrigger = styled(RadixDropdownMenu.SubTrigger, {
314
622
  ...itemDefaults,
315
- '&[data-state="open"]': itemDefaults["&:hover"]
316
- });
317
-
318
- const ArrowIcon = () => /* @__PURE__ */ React.createElement("svg", {
319
- width: "16",
320
- height: "16",
321
- viewBox: "0 0 16 16",
322
- fill: "currentColor",
323
- xmlns: "http://www.w3.org/2000/svg",
324
- "data-testid": "submenu-arrow-icon"
325
- }, /* @__PURE__ */ React.createElement("path", {
326
- d: "M5.29289 3.29289C5.68342 2.90237 6.31658 2.90237 6.70711 3.29289L11.4142 8L6.70711 12.7071C6.31658 13.0976 5.68342 13.0976 5.29289 12.7071C4.90237 12.3166 4.90237 11.6834 5.29289 11.2929L8.58579 8L5.29289 4.70711C4.90237 4.31658 4.90237 3.68342 5.29289 3.29289Z"
327
- }));
328
- const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledSubTrigger, {
329
- ...restProps,
330
- ref: forwardRef,
331
- disabled
332
- }, /* @__PURE__ */ React.createElement(ContentSlot, null, children), /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(ArrowIcon, null))));
623
+ '&[data-state="open"]': itemDefaults['&:hover:not([aria-disabled="true"])'],
624
+ [`&[data-state="open"] ${StyledIconContainer}, &:hover:not([aria-disabled="true"]) ${StyledIconContainer}`]: {
625
+ color: "$icon-primary-hover"
626
+ }
627
+ });
628
+
629
+ const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => {
630
+ const { onSelect, ...ariaDisabledProps } = useAriaDisabled({
631
+ onKeyDown: restProps.onKeyDown,
632
+ "aria-disabled": restProps["aria-disabled"]
633
+ });
634
+ return /* @__PURE__ */ React.createElement(StyledSubTrigger, {
635
+ ...restProps,
636
+ ...ariaDisabledProps,
637
+ disabled,
638
+ ref: forwardRef
639
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIconContainer, {
640
+ "data-testid": process.env.NODE_ENV === "test" ? "submenu-arrow-icon" : void 0
641
+ }, /* @__PURE__ */ React.createElement(IconChevronRight, {
642
+ size: "small",
643
+ weight: "thin"
644
+ }))));
645
+ });
333
646
 
334
647
  const StyledSubContent = styled(
335
648
  RadixDropdownMenu.SubContent,
@@ -343,19 +656,29 @@ const SubContent = React.forwardRef(
343
656
  alignOffset = -CONTENT_GUTTER,
344
657
  collisionPadding = 0,
345
658
  loop = false,
346
- hideWhenDetached = false,
659
+ hideWhenDetached = true,
347
660
  sticky = "partial",
661
+ overflow = "visible",
662
+ maxHeight,
663
+ children,
348
664
  ...restProps
349
- }, forwardRef) => /* @__PURE__ */ React.createElement(StyledSubContent, {
350
- ...restProps,
351
- ref: forwardRef,
352
- sideOffset,
353
- alignOffset,
354
- collisionPadding,
355
- loop,
356
- hideWhenDetached,
357
- sticky
358
- })
665
+ }, forwardRef) => {
666
+ const { containerSpacing } = useContent();
667
+ return /* @__PURE__ */ React.createElement(ContentProvider, {
668
+ containerSpacing
669
+ }, /* @__PURE__ */ React.createElement(StyledSubContent, {
670
+ ...restProps,
671
+ ref: forwardRef,
672
+ sideOffset,
673
+ alignOffset,
674
+ collisionPadding,
675
+ loop,
676
+ hideWhenDetached,
677
+ sticky
678
+ }, /* @__PURE__ */ React.createElement(ScrollableContent, {
679
+ ...{ containerSpacing, maxHeight, overflow }
680
+ }, children)));
681
+ }
359
682
  );
360
683
 
361
684
  const StyledSub = styled(RadixDropdownMenu.Sub, {});
@@ -381,6 +704,47 @@ const Portal = (props) => /* @__PURE__ */ React.createElement(Portal$1, {
381
704
  ...props
382
705
  });
383
706
 
707
+ const StyledIconSlot = styled(LeftSlot, {
708
+ square: "$5",
709
+ "& svg:not([data-icon-component]), & img:not([data-icon-component])": {
710
+ ...styles$1.size.small,
711
+ ...styles$1.weight.thin
712
+ }
713
+ });
714
+
715
+ const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
716
+ const { leftSlotMount, leftSlotDestroy } = useItem();
717
+ const formattedChildren = addPropsToChildren(
718
+ children,
719
+ isIconComponent,
720
+ {
721
+ "data-icon-component": "",
722
+ size: "small",
723
+ weight: "thin"
724
+ }
725
+ );
726
+ useEffect(() => {
727
+ leftSlotMount();
728
+ return () => leftSlotDestroy();
729
+ }, [leftSlotMount, leftSlotDestroy]);
730
+ return /* @__PURE__ */ React.createElement(StyledIconSlot, {
731
+ ref: forwardRef,
732
+ ...restProps
733
+ }, formattedChildren);
734
+ });
735
+
736
+ const IllustrationSlot = React.forwardRef((props, forwardRef) => {
737
+ const { leftSlotMount, leftSlotDestroy } = useItem();
738
+ useEffect(() => {
739
+ leftSlotMount();
740
+ return () => leftSlotDestroy();
741
+ }, [leftSlotMount, leftSlotDestroy]);
742
+ return /* @__PURE__ */ React.createElement(StyledIllustrationSlot, {
743
+ ref: forwardRef,
744
+ ...props
745
+ });
746
+ });
747
+
384
748
  const DropdownMenu = ({
385
749
  defaultOpen = false,
386
750
  direction = "ltr",
@@ -406,8 +770,11 @@ const DropdownMenu = ({
406
770
  };
407
771
  DropdownMenu.CheckboxItem = CheckboxItem;
408
772
  DropdownMenu.Content = Content;
773
+ DropdownMenu.HotkeySlot = HotkeySlot;
409
774
  DropdownMenu.IconSlot = IconSlot;
775
+ DropdownMenu.IllustrationSlot = IllustrationSlot;
410
776
  DropdownMenu.Item = Item;
777
+ DropdownMenu.ItemDescription = ItemDescription;
411
778
  DropdownMenu.LinkItem = LinkItem;
412
779
  DropdownMenu.Portal = Portal;
413
780
  DropdownMenu.RadioGroup = RadioGroup;