@mirohq/design-system-dropdown-menu 3.3.0-dropdown.2 → 3.3.0-dropdown.4

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,7 +1,8 @@
1
- import React, { useState } from 'react';
1
+ import React, { useMemo, useState } 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, isIconComponent } from '@mirohq/design-system-icons';
5
+ import { 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';
@@ -18,6 +19,24 @@ const ItemDescription = styled(Primitive.div, {
18
19
  color: "$text-neutrals-subtle"
19
20
  });
20
21
 
22
+ const LeftSlot = styled(Primitive.div, {
23
+ display: "flex",
24
+ placeContent: "center",
25
+ marginRight: "$100",
26
+ gridArea: "left-slot"
27
+ });
28
+ const IllustrationSlot = styled(LeftSlot, {
29
+ width: "$13"
30
+ });
31
+ const RightSlot = styled(Primitive.div, {
32
+ display: "flex",
33
+ alignItems: "center",
34
+ marginLeft: "auto",
35
+ paddingLeft: "$200",
36
+ gridArea: "right-slot"
37
+ });
38
+ const HotkeySlot = RightSlot;
39
+
21
40
  const itemDefaults = {
22
41
  all: "unset",
23
42
  boxSizing: "border-box",
@@ -38,18 +57,28 @@ const itemDefaults = {
38
57
  position: "relative",
39
58
  userSelect: "none",
40
59
  cursor: "pointer",
41
- "&[data-disabled]": {
42
- color: "rgba(9, 9, 9, 0.4)",
43
- pointerEvents: "none"
44
- },
45
60
  ...focus.defaults,
46
- "&:hover": {
47
- background: "rgba(232, 236, 255, 1)",
48
- boxShadow: "none",
61
+ '&:disabled, &[aria-disabled="true"], &[data-disabled]': {
62
+ pointerEvents: "none",
49
63
  [`&, & ${ItemDescription}`]: {
50
- color: "$text-primary-hover"
64
+ color: "$text-neutrals-disabled"
65
+ },
66
+ [`& ${IllustrationSlot}`]: {
67
+ filter: "grayscale(1)"
68
+ }
69
+ },
70
+ "&:hover": {
71
+ background: "$background-primary-subtle-hover",
72
+ color: "$text-primary-hover",
73
+ '&:not([aria-disabled="true"])': {
74
+ boxShadow: "none"
51
75
  }
52
76
  },
77
+ "&:active": {
78
+ background: "$background-primary-subtle-active",
79
+ boxShadow: "none",
80
+ color: "$text-primary-active"
81
+ },
53
82
  '&[tabindex="0"]': {
54
83
  zIndex: "1"
55
84
  }
@@ -64,48 +93,54 @@ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
64
93
  [`&[data-state="checked"]:hover ${StyledIndicator}`]: {
65
94
  color: "$icon-primary-hover"
66
95
  },
67
- [`&[data-disabled] ${StyledIndicator}`]: {
96
+ [`
97
+ &[aria-disabled="true"] ${StyledIndicator},
98
+ &[data-disabled] ${StyledIndicator}
99
+ `]: {
68
100
  color: "$icon-neutrals-disabled"
69
101
  }
70
102
  });
71
103
 
72
- const LeftSlot = styled(Primitive.div, {
73
- display: "flex",
74
- placeContent: "center",
75
- marginRight: "$100",
76
- gridArea: "left-slot"
77
- });
78
- const IconSlot = styled(LeftSlot, {
79
- width: "$6"
80
- });
81
- const IllustrationSlot = styled(LeftSlot, {
82
- width: "$13"
83
- });
84
- const RightSlot = styled(Primitive.div, {
85
- display: "flex",
86
- alignItems: "center",
87
- marginLeft: "auto",
88
- paddingLeft: "$200",
89
- gridArea: "right-slot"
90
- });
104
+ const useAriaDisabled = ({ "aria-disabled": ariaDisabled, onKeyDown, onSelect }, preventDefault = false) => useMemo(
105
+ () => ({
106
+ "aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
107
+ onKeyDown: (e) => {
108
+ if (booleanify(ariaDisabled) && e.code !== "ArrowUp" && e.code !== "ArrowDown") {
109
+ e.preventDefault();
110
+ e.stopPropagation();
111
+ return;
112
+ }
113
+ onKeyDown == null ? void 0 : onKeyDown(e);
114
+ },
115
+ onSelect: (e) => {
116
+ if (preventDefault) {
117
+ e.preventDefault();
118
+ }
119
+ if (booleanify(ariaDisabled)) {
120
+ return;
121
+ }
122
+ onSelect == null ? void 0 : onSelect(e);
123
+ }
124
+ }),
125
+ [ariaDisabled, onKeyDown, onSelect, preventDefault]
126
+ );
91
127
 
92
- const CheckboxItem = React.forwardRef(
93
- ({ children, checked, onChange, onSelect, disabled, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
128
+ const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled, ...restProps }, forwardRef) => {
129
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
130
+ const { "aria-disabled": ariaDisabled } = ariaDisabledProps;
131
+ return /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
94
132
  ...restProps,
133
+ ...ariaDisabledProps,
95
134
  ref: forwardRef,
96
135
  checked,
97
136
  disabled,
98
- onCheckedChange: onChange,
99
- onSelect: (event) => {
100
- event.preventDefault();
101
- onSelect == null ? void 0 : onSelect(event);
102
- }
103
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, disabled === true && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
137
+ onCheckedChange: onChange
138
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, (disabled === true || booleanify(ariaDisabled)) && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
104
139
  size: "small"
105
140
  }), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
106
141
  size: "small"
107
- }))))
108
- );
142
+ }))));
143
+ });
109
144
 
110
145
  const GUTTER_TOKEN = 150;
111
146
  const CONTENT_GUTTER = parseInt(theme.space[GUTTER_TOKEN]);
@@ -186,20 +221,28 @@ const Content = React.forwardRef(
186
221
  const StyledItem = styled(RadixDropdownMenu.Item, itemDefaults);
187
222
 
188
223
  const Item = React.forwardRef(
189
- ({ disabled = false, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledItem, {
190
- ...restProps,
191
- ref: forwardRef,
192
- disabled
193
- })
224
+ ({ disabled = false, ...restProps }, forwardRef) => {
225
+ const ariaDisabledProps = useAriaDisabled(restProps);
226
+ return /* @__PURE__ */ React.createElement(StyledItem, {
227
+ ...restProps,
228
+ ...ariaDisabledProps,
229
+ disabled,
230
+ ref: forwardRef
231
+ });
232
+ }
194
233
  );
195
234
 
196
- const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(Item, {
197
- asChild: true,
198
- ref: forwardRef,
199
- ...restProps
200
- }, /* @__PURE__ */ React.createElement("a", {
201
- href
202
- }, children)));
235
+ const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef) => {
236
+ const ariaDisabledProps = useAriaDisabled(restProps);
237
+ return /* @__PURE__ */ React.createElement(Item, {
238
+ asChild: true,
239
+ ref: forwardRef,
240
+ ...restProps,
241
+ ...ariaDisabledProps
242
+ }, /* @__PURE__ */ React.createElement("a", {
243
+ href
244
+ }, children));
245
+ });
203
246
 
204
247
  const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup);
205
248
 
@@ -248,30 +291,38 @@ const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
248
291
  backgroundColor: "$background-primary-prominent-hover"
249
292
  }
250
293
  },
251
- [`&[data-disabled] ${StyledRadioContainer}`]: {
294
+ [`
295
+ &[aria-disabled="true"] ${StyledRadioContainer},
296
+ &[data-disabled] ${StyledRadioContainer}
297
+ `]: {
252
298
  color: "$icon-neutrals-disabled",
253
299
  borderColor: "$border-neutrals-disabled",
254
300
  [`& ${StyledPill}`]: {
255
301
  backgroundColor: "$icon-neutrals-disabled"
256
302
  }
257
303
  },
258
- [`&[data-state="unchecked"][data-disabled] ${StyledProhibited}`]: {
259
- display: "block"
304
+ '&[data-state="unchecked"]': {
305
+ [`
306
+ &[aria-disabled="true"] ${StyledProhibited},
307
+ &[data-disabled] ${StyledProhibited}
308
+ `]: {
309
+ display: "flex"
310
+ }
260
311
  }
261
312
  });
262
313
 
263
- const RadioItem = React.forwardRef(({ disabled = false, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledRadioItem, {
264
- ...restProps,
265
- ref: forwardRef,
266
- disabled,
267
- onSelect: (event) => {
268
- event.preventDefault();
269
- onSelect == null ? void 0 : onSelect(event);
270
- }
271
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null)))));
314
+ const RadioItem = React.forwardRef(({ disabled = false, children, ...restProps }, forwardRef) => {
315
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
316
+ return /* @__PURE__ */ React.createElement(StyledRadioItem, {
317
+ ...restProps,
318
+ ...ariaDisabledProps,
319
+ disabled,
320
+ ref: forwardRef
321
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null))));
322
+ });
272
323
 
273
324
  const StyledSeparator = styled(RadixDropdownMenu.Separator, {
274
- borderTop: "1px solid rgba(235, 235, 239, 1)",
325
+ borderTop: "1px solid $border-neutrals-subtle",
275
326
  marginY: "$100"
276
327
  });
277
328
 
@@ -290,21 +341,24 @@ const StyledSwitchItem = styled(RadixDropdownMenu.CheckboxItem, {
290
341
  [`&[data-state="checked"] ${StyledSwitch}`]: styles.checked,
291
342
  [`&[data-state="checked"]:hover ${StyledSwitch}`]: styles.checkedHovered,
292
343
  [`&:hover ${StyledSwitch}`]: styles.hovered,
293
- [`&[data-disabled] ${StyledSwitch}`]: styles.disabled
344
+ [`
345
+ &[aria-disabled="true"] ${StyledSwitch},
346
+ &[data-disabled] ${StyledSwitch}
347
+ `]: styles.disabled
294
348
  });
295
349
 
296
350
  const SwitchItem = React.forwardRef(
297
- ({ disabled = false, checked, onChange, onSelect, children, ...restProps }, forwardRef) => /* @__PURE__ */ React.createElement(StyledSwitchItem, {
298
- ...restProps,
299
- ref: forwardRef,
300
- disabled,
301
- checked,
302
- onCheckedChange: onChange,
303
- onSelect: (event) => {
304
- event.preventDefault();
305
- onSelect == null ? void 0 : onSelect(event);
306
- }
307
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledSwitch, null, /* @__PURE__ */ React.createElement(Thumb, null))))
351
+ ({ disabled = false, checked, onChange, children, ...restProps }, forwardRef) => {
352
+ const ariaDisabledProps = useAriaDisabled(restProps, true);
353
+ return /* @__PURE__ */ React.createElement(StyledSwitchItem, {
354
+ ...restProps,
355
+ ...ariaDisabledProps,
356
+ disabled,
357
+ checked,
358
+ onCheckedChange: onChange,
359
+ ref: forwardRef
360
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledSwitch, null, /* @__PURE__ */ React.createElement(Thumb, null))));
361
+ }
308
362
  );
309
363
 
310
364
  const defaultStyles = {
@@ -332,26 +386,34 @@ const Trigger = React.forwardRef(({ asChild = false, onPress, onClick, ...restPr
332
386
  asChild
333
387
  }));
334
388
 
389
+ const StyledIconContainer = styled(Primitive.span, {
390
+ color: "$icon-neutrals-with-text"
391
+ });
335
392
  const StyledSubTrigger = styled(RadixDropdownMenu.SubTrigger, {
336
393
  ...itemDefaults,
337
- '&[data-state="open"]': itemDefaults["&:hover"]
394
+ '&[data-state="open"]': itemDefaults["&:hover"],
395
+ [`&[data-state="open"] ${StyledIconContainer}, &:hover ${StyledIconContainer}`]: {
396
+ color: "$icon-primary-hover"
397
+ }
338
398
  });
339
399
 
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))));
400
+ const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => {
401
+ const { onSelect, ...ariaDisabledProps } = useAriaDisabled({
402
+ onKeyDown: restProps.onKeyDown,
403
+ "aria-disabled": restProps["aria-disabled"]
404
+ });
405
+ return /* @__PURE__ */ React.createElement(StyledSubTrigger, {
406
+ ...restProps,
407
+ ...ariaDisabledProps,
408
+ disabled,
409
+ ref: forwardRef
410
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIconContainer, {
411
+ "data-testid": process.env.NODE_ENV === "test" ? "submenu-arrow-icon" : void 0
412
+ }, /* @__PURE__ */ React.createElement(IconChevronRight, {
413
+ size: "small",
414
+ weight: "thin"
415
+ }))));
416
+ });
355
417
 
356
418
  const StyledSubContent = styled(
357
419
  RadixDropdownMenu.SubContent,
@@ -403,6 +465,32 @@ const Portal = (props) => /* @__PURE__ */ React.createElement(Portal$1, {
403
465
  ...props
404
466
  });
405
467
 
468
+ const StyledIconSlot = styled(LeftSlot, {
469
+ square: "$5",
470
+ variants: {
471
+ customIcon: {
472
+ true: {
473
+ square: "$icon-200"
474
+ }
475
+ }
476
+ }
477
+ });
478
+
479
+ const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
480
+ const child = React.Children.only(children);
481
+ const isIcon = isIconComponent(child);
482
+ const formattedChild = isIcon ? React.cloneElement(child, {
483
+ ...child.props,
484
+ size: "small",
485
+ weight: "thin"
486
+ }) : child;
487
+ return /* @__PURE__ */ React.createElement(StyledIconSlot, {
488
+ ref: forwardRef,
489
+ ...restProps,
490
+ customIcon: !isIcon
491
+ }, formattedChild);
492
+ });
493
+
406
494
  const DropdownMenu = ({
407
495
  defaultOpen = false,
408
496
  direction = "ltr",
@@ -428,6 +516,7 @@ const DropdownMenu = ({
428
516
  };
429
517
  DropdownMenu.CheckboxItem = CheckboxItem;
430
518
  DropdownMenu.Content = Content;
519
+ DropdownMenu.HotkeySlot = HotkeySlot;
431
520
  DropdownMenu.IconSlot = IconSlot;
432
521
  DropdownMenu.IllustrationSlot = IllustrationSlot;
433
522
  DropdownMenu.Item = Item;