@mirohq/design-system-dropdown-menu 3.3.0-dropdown.1 → 3.3.0-dropdown.11

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