@mirohq/design-system-dropdown-menu 3.3.0-dropdown.1 → 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,11 +1,14 @@
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';
9
12
 
10
13
  const ItemDescription = styled(Primitive.div, {
11
14
  display: "-webkit-box",
@@ -18,6 +21,112 @@ const ItemDescription = styled(Primitive.div, {
18
21
  color: "$text-neutrals-subtle"
19
22
  });
20
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
+ });
129
+
21
130
  const itemDefaults = {
22
131
  all: "unset",
23
132
  boxSizing: "border-box",
@@ -26,115 +135,186 @@ const itemDefaults = {
26
135
  color: "$text-neutrals",
27
136
  borderRadius: "$50",
28
137
  display: "grid",
29
- gridTemplateColumns: "auto 1fr auto",
138
+ gridTemplateColumns: "auto 1fr minmax(auto, var(--right-slot-max-width))",
30
139
  gridTemplateRows: "1fr auto",
31
- gridTemplateAreas: `
32
- 'left-slot item-text right-slot'
33
- 'left-slot item-description right-slot'
34
- `,
35
- alignItems: "center",
36
- minHeight: "$11",
37
- padding: "$100 $150",
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",
38
145
  position: "relative",
39
146
  userSelect: "none",
40
147
  cursor: "pointer",
41
- "&[data-disabled]": {
42
- color: "rgba(9, 9, 9, 0.4)",
43
- 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"
44
159
  },
45
160
  ...focus.defaults,
46
- "&:hover": {
47
- background: "rgba(232, 236, 255, 1)",
48
- boxShadow: "none",
49
- [`&, & ${ItemDescription}`]: {
50
- color: "$text-primary-hover"
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"
51
178
  }
52
179
  },
180
+ '&:active:not([aria-disabled="true"])': {
181
+ background: "$background-primary-subtle-active",
182
+ boxShadow: "none",
183
+ color: "$text-primary-active"
184
+ },
53
185
  '&[tabindex="0"]': {
54
186
  zIndex: "1"
55
187
  }
56
188
  };
57
189
 
58
- const StyledIndicator = styled(Primitive.span, {});
59
- const checkboxItemStyles = {
190
+ const StyledIndicator = styled(Primitive.span, {
191
+ display: "flex",
192
+ alignItems: "center",
193
+ justifyContent: "center"
194
+ });
195
+ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
60
196
  ...itemDefaults,
61
197
  [`&[data-state="checked"] ${StyledIndicator}`]: {
62
198
  color: "$icon-primary"
63
199
  },
64
- [`&[data-state="checked"]:hover ${StyledIndicator}`]: {
200
+ [`&[data-state="checked"]:hover:not([aria-disabled="true"]) ${StyledIndicator}`]: {
65
201
  color: "$icon-primary-hover"
66
202
  },
67
- [`&[data-disabled] ${StyledIndicator}`]: {
203
+ [`
204
+ &[aria-disabled="true"] ${StyledIndicator},
205
+ &[data-disabled] ${StyledIndicator}
206
+ `]: {
68
207
  color: "$icon-neutrals-disabled"
69
208
  }
70
- };
71
- const StyledCheckboxItem = styled(
72
- RadixDropdownMenu.CheckboxItem,
73
- checkboxItemStyles
74
- );
75
-
76
- const LeftSlot = styled(Primitive.div, {
77
- display: "flex",
78
- placeContent: "center",
79
- marginRight: "$100",
80
- gridArea: "left-slot"
81
- });
82
- const IconSlot = styled(LeftSlot, {
83
- width: "$6"
84
- });
85
- const IllustrationSlot = styled(LeftSlot, {
86
- width: "$13"
87
- });
88
- const RightSlot = styled(Primitive.div, {
89
- display: "flex",
90
- alignItems: "center",
91
- marginLeft: "auto",
92
- paddingLeft: "$200",
93
- gridArea: "right-slot"
94
209
  });
95
210
 
96
- const CheckboxItemRoot = ({
97
- disabled = false,
98
- onChange,
211
+ const useAriaDisabled = ({
212
+ "aria-disabled": ariaDisabled,
213
+ onKeyDown,
99
214
  onSelect,
100
- ref,
101
- ...restProps
102
- }) => /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
103
- ...restProps,
104
- ref,
105
- disabled,
106
- onCheckedChange: onChange,
107
- onSelect: (event) => {
108
- event.preventDefault();
109
- 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: () => {
110
260
  }
111
261
  });
112
- const CheckboxItem = React.forwardRef(({ children, checked, disabled, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(CheckboxItemRoot, {
113
- ...restProps,
114
- checked,
115
- disabled,
116
- ref: forwardRef
117
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, disabled === true && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
118
- size: "small"
119
- }), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
120
- size: "small"
121
- })))));
122
-
123
- const GUTTER_TOKEN = 150;
124
- 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]);
125
303
  const CONTENT_OFFSET = parseInt(theme.space[50]);
126
- 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
+ };
127
310
  const contentDefaults = {
128
311
  maxWidth: "$125",
129
- backgroundColor: "$white",
312
+ backgroundColor: "$background-neutrals-container",
130
313
  borderRadius: "$50",
131
- padding: `$${GUTTER_TOKEN}`,
132
314
  boxShadow: "$50",
133
- [`&:has(${RightSlot}) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
134
- paddingRight: "44px"
135
- },
136
- [`&:has([role="switch"]) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
137
- 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"
138
318
  },
139
319
  "@media (prefers-reduced-motion: no-preference)": {
140
320
  animationDuration: "150ms",
@@ -167,7 +347,56 @@ const contentDefaults = {
167
347
  zIndex: "$dropdownMenu"
168
348
  };
169
349
 
170
- 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
+ };
171
400
 
172
401
  const Content = React.forwardRef(
173
402
  ({
@@ -180,8 +409,14 @@ const Content = React.forwardRef(
180
409
  avoidCollisions = true,
181
410
  sticky = "partial",
182
411
  hideWhenDetached = false,
412
+ containerSpacing = "medium",
413
+ overflow = "visible",
414
+ maxHeight,
415
+ children,
183
416
  ...restProps
184
- }, forwardRef) => /* @__PURE__ */ React.createElement(StyledContent, {
417
+ }, forwardRef) => /* @__PURE__ */ React.createElement(ContentProvider, {
418
+ containerSpacing
419
+ }, /* @__PURE__ */ React.createElement(StyledContent, {
185
420
  ...restProps,
186
421
  ref: forwardRef,
187
422
  loop,
@@ -192,29 +427,51 @@ const Content = React.forwardRef(
192
427
  avoidCollisions,
193
428
  collisionPadding,
194
429
  sticky,
195
- hideWhenDetached
196
- })
430
+ hideWhenDetached,
431
+ containerSpacing
432
+ }, /* @__PURE__ */ React.createElement(ScrollableContent, {
433
+ ...{ containerSpacing, maxHeight, overflow }
434
+ }, children)))
197
435
  );
198
436
 
199
- 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
+ });
200
447
 
201
448
  const Item = React.forwardRef(
202
- ({ disabled = false, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledItem, {
203
- ...restProps,
204
- ref: forwardRef,
205
- disabled
206
- })
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
+ }
207
458
  );
208
459
 
209
- const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(Item, {
210
- asChild: true,
211
- ref: forwardRef,
212
- ...restProps
213
- }, /* @__PURE__ */ React.createElement("a", {
214
- href
215
- }, 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
+ });
216
471
 
217
- const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup);
472
+ const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup, {
473
+ marginY: "$50"
474
+ });
218
475
 
219
476
  const RadioGroup = React.forwardRef((props, forwardRef) => {
220
477
  const { onChange, ...restProps } = props;
@@ -225,7 +482,7 @@ const RadioGroup = React.forwardRef((props, forwardRef) => {
225
482
  });
226
483
  });
227
484
 
228
- const StyledRadioContainer = styled(Primitive.span, {
485
+ const StyledRadioContainer = styled(Primitive.div, {
229
486
  display: "flex",
230
487
  alignItems: "center",
231
488
  justifyContent: "center",
@@ -235,7 +492,7 @@ const StyledRadioContainer = styled(Primitive.span, {
235
492
  border: "1px solid $border-neutrals",
236
493
  borderRadius: "$half"
237
494
  });
238
- const StyledPill = styled(Primitive.span, {
495
+ const StyledPill = styled(Primitive.div, {
239
496
  display: "none",
240
497
  width: "$2",
241
498
  height: "$2",
@@ -243,7 +500,7 @@ const StyledPill = styled(Primitive.span, {
243
500
  });
244
501
  const StyledProhibited = styled(IconProhibit, {
245
502
  display: "none",
246
- width: "$3"
503
+ width: "$3 !important"
247
504
  });
248
505
  const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
249
506
  ...itemDefaults,
@@ -255,37 +512,46 @@ const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
255
512
  backgroundColor: "$background-primary-prominent-selected"
256
513
  }
257
514
  },
258
- [`&:hover ${StyledRadioContainer}`]: {
515
+ [`&:hover:not([aria-disabled="true"]) ${StyledRadioContainer}`]: {
259
516
  borderColor: "$border-primary-hover",
260
517
  [`& ${StyledPill}`]: {
261
518
  backgroundColor: "$background-primary-prominent-hover"
262
519
  }
263
520
  },
264
- [`&[data-disabled] ${StyledRadioContainer}`]: {
521
+ [`
522
+ &[aria-disabled="true"] ${StyledRadioContainer},
523
+ &[data-disabled] ${StyledRadioContainer}
524
+ `]: {
265
525
  color: "$icon-neutrals-disabled",
266
526
  borderColor: "$border-neutrals-disabled",
267
527
  [`& ${StyledPill}`]: {
268
528
  backgroundColor: "$icon-neutrals-disabled"
269
529
  }
270
530
  },
271
- [`&[data-state="unchecked"][data-disabled] ${StyledProhibited}`]: {
272
- display: "block"
531
+ '&[data-state="unchecked"]': {
532
+ [`
533
+ &[aria-disabled="true"] ${StyledProhibited},
534
+ &[data-disabled] ${StyledProhibited}
535
+ `]: {
536
+ display: "flex"
537
+ }
273
538
  }
274
539
  });
275
540
 
276
- const RadioItem = React.forwardRef(({ disabled = false, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledRadioItem, {
277
- ...restProps,
278
- ref: forwardRef,
279
- disabled,
280
- onSelect: (event) => {
281
- event.preventDefault();
282
- onSelect == null ? void 0 : onSelect(event);
283
- }
284
- }, 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
+ });
285
552
 
286
553
  const StyledSeparator = styled(RadixDropdownMenu.Separator, {
287
- borderTop: "1px solid rgba(235, 235, 239, 1)",
288
- marginY: "$100"
554
+ borderTop: "1px solid $border-neutrals-subtle"
289
555
  });
290
556
 
291
557
  const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.createElement(StyledSeparator, {
@@ -293,33 +559,48 @@ const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.
293
559
  ref: forwardRef
294
560
  }));
295
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
+
296
578
  const SwitchItem = React.forwardRef(
297
- ({ disabled = false, checked, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(CheckboxItemRoot, {
298
- ...restProps,
299
- ref: forwardRef,
300
- disabled,
301
- checked
302
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(Switch, {
303
- checked,
304
- disabled,
305
- onChange: (x) => x,
306
- value: ""
307
- })))
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
+ }
308
590
  );
309
591
 
310
- const defaultStyles = {
311
- boxSizing: "border-box",
312
- cursor: "pointer",
313
- ...focus.defaults
314
- };
315
592
  const StyledTrigger = styled(RadixDropdownMenu.Trigger, {
316
593
  variants: {
317
594
  unstyled: {
318
595
  true: {
319
596
  all: "unset",
320
- ...defaultStyles
597
+ boxSizing: "border-box",
598
+ cursor: "pointer",
599
+ ...focus.defaults
321
600
  },
322
- false: defaultStyles
601
+ false: {
602
+ cursor: "pointer"
603
+ }
323
604
  }
324
605
  }
325
606
  });
@@ -332,26 +613,36 @@ const Trigger = React.forwardRef(({ asChild = false, onPress, onClick, ...restPr
332
613
  asChild
333
614
  }));
334
615
 
616
+ const StyledIconContainer = styled(Primitive.span, {
617
+ color: "$icon-neutrals-with-text",
618
+ display: "flex",
619
+ alignItems: "center"
620
+ });
335
621
  const StyledSubTrigger = styled(RadixDropdownMenu.SubTrigger, {
336
622
  ...itemDefaults,
337
- '&[data-state="open"]': itemDefaults["&:hover"]
338
- });
339
-
340
- const ArrowIcon = () => /* @__PURE__ */ React.createElement("svg", {
341
- width: "16",
342
- height: "16",
343
- viewBox: "0 0 16 16",
344
- fill: "currentColor",
345
- xmlns: "http://www.w3.org/2000/svg",
346
- "data-testid": "submenu-arrow-icon"
347
- }, /* @__PURE__ */ React.createElement("path", {
348
- 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"
349
- }));
350
- const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledSubTrigger, {
351
- ...restProps,
352
- ref: forwardRef,
353
- disabled
354
- }, 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
+ });
355
646
 
356
647
  const StyledSubContent = styled(
357
648
  RadixDropdownMenu.SubContent,
@@ -365,19 +656,29 @@ const SubContent = React.forwardRef(
365
656
  alignOffset = -CONTENT_GUTTER,
366
657
  collisionPadding = 0,
367
658
  loop = false,
368
- hideWhenDetached = false,
659
+ hideWhenDetached = true,
369
660
  sticky = "partial",
661
+ overflow = "visible",
662
+ maxHeight,
663
+ children,
370
664
  ...restProps
371
- }, forwardRef) => /* @__PURE__ */ React.createElement(StyledSubContent, {
372
- ...restProps,
373
- ref: forwardRef,
374
- sideOffset,
375
- alignOffset,
376
- collisionPadding,
377
- loop,
378
- hideWhenDetached,
379
- sticky
380
- })
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
+ }
381
682
  );
382
683
 
383
684
  const StyledSub = styled(RadixDropdownMenu.Sub, {});
@@ -403,6 +704,47 @@ const Portal = (props) => /* @__PURE__ */ React.createElement(Portal$1, {
403
704
  ...props
404
705
  });
405
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
+
406
748
  const DropdownMenu = ({
407
749
  defaultOpen = false,
408
750
  direction = "ltr",
@@ -428,6 +770,7 @@ const DropdownMenu = ({
428
770
  };
429
771
  DropdownMenu.CheckboxItem = CheckboxItem;
430
772
  DropdownMenu.Content = Content;
773
+ DropdownMenu.HotkeySlot = HotkeySlot;
431
774
  DropdownMenu.IconSlot = IconSlot;
432
775
  DropdownMenu.IllustrationSlot = IllustrationSlot;
433
776
  DropdownMenu.Item = Item;