@mirohq/design-system-dropdown-menu 3.3.0-dropdown.8 → 3.3.0

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
@@ -8,7 +8,7 @@ import { styled, theme } from '@mirohq/design-system-stitches';
8
8
  import { focus, animations } from '@mirohq/design-system-styles';
9
9
  import { ScrollArea } from '@mirohq/design-system-scroll-area';
10
10
  import { styles, Thumb } from '@mirohq/design-system-base-switch';
11
- import { isIconComponent } from '@mirohq/design-system-base-icon';
11
+ import { styles as styles$1, isIconComponent } from '@mirohq/design-system-base-icon';
12
12
 
13
13
  const ItemDescription = styled(Primitive.div, {
14
14
  display: "-webkit-box",
@@ -18,31 +18,116 @@ const ItemDescription = styled(Primitive.div, {
18
18
  overflow: "hidden",
19
19
  gridArea: "item-description",
20
20
  fontSize: "$150",
21
+ lineHeight: 1.5,
21
22
  color: "$text-neutrals-subtle"
22
23
  });
23
24
 
24
25
  const LeftSlot = styled(Primitive.div, {
25
26
  display: "flex",
26
- placeContent: "center",
27
+ alignItems: "center",
28
+ justifyContent: "center",
27
29
  marginRight: "$100",
28
30
  gridArea: "left-slot"
29
31
  });
32
+
30
33
  const StyledIllustrationSlot = styled(LeftSlot, {
31
34
  width: "$13"
32
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
+
33
93
  const StyledRightSlot = styled(Primitive.div, {
34
94
  display: "flex",
35
95
  alignItems: "center",
96
+ justifyContent: "center",
36
97
  marginLeft: "auto",
37
98
  paddingLeft: "$200",
38
99
  gridArea: "right-slot",
100
+ height: "$5",
101
+ width: "$7",
39
102
  minWidth: "max-content",
40
103
  textAlign: "right",
41
104
  "&:empty": {
42
- paddingLeft: "$none"
105
+ paddingLeft: "$0"
43
106
  }
44
107
  });
45
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, {
128
+ color: "$text-neutrals-subtle"
129
+ });
130
+
46
131
  const itemDefaults = {
47
132
  all: "unset",
48
133
  boxSizing: "border-box",
@@ -52,18 +137,16 @@ const itemDefaults = {
52
137
  borderRadius: "$50",
53
138
  display: "grid",
54
139
  gridTemplateColumns: "auto 1fr minmax(auto, var(--right-slot-max-width))",
55
- gridTemplateRows: "1fr auto",
140
+ gridTemplateRows: "auto 1fr",
56
141
  gridTemplateAreas: `'left-slot item-text right-slot'
57
142
  'left-slot item-description right-slot'`,
58
143
  alignItems: "start",
59
- minHeight: "$10",
60
- padding: "$100 $100",
144
+ padding: "10px $100",
61
145
  position: "relative",
62
146
  userSelect: "none",
63
147
  cursor: "pointer",
64
148
  "&[data-no-left-slot]": {
65
149
  gridTemplateColumns: "1fr minmax(auto, var(--right-slot-max-width))",
66
- gridTemplateRows: "auto",
67
150
  gridTemplateAreas: `'item-text right-slot'
68
151
  'item-description right-slot'`
69
152
  },
@@ -73,24 +156,30 @@ const itemDefaults = {
73
156
  "&:not(:first-child)": {
74
157
  marginTop: "$50"
75
158
  },
76
- ...focus.defaults,
159
+ ...focus.css({
160
+ boxShadow: "$focus-small",
161
+ outline: "1px solid transparent"
162
+ }),
77
163
  '&:disabled, &[aria-disabled="true"], &[data-disabled]': {
78
- pointerEvents: "none",
79
- [`&, & ${ItemDescription}`]: {
164
+ cursor: "default",
165
+ [`&, & ${ItemDescription}, & ${HotkeySlot}`]: {
80
166
  color: "$text-neutrals-disabled"
81
167
  },
82
168
  [`& ${StyledIllustrationSlot}`]: {
83
169
  filter: "grayscale(1)"
84
170
  }
85
171
  },
86
- "&:hover": {
172
+ "&:disabled, &[data-disabled]": {
173
+ pointerEvents: "none"
174
+ },
175
+ '&:hover:not([aria-disabled="true"])': {
87
176
  background: "$background-primary-subtle-hover",
88
177
  color: "$text-primary-hover",
89
178
  '&:not([aria-disabled="true"])': {
90
179
  boxShadow: "none"
91
180
  }
92
181
  },
93
- "&:active": {
182
+ '&:active:not([aria-disabled="true"])': {
94
183
  background: "$background-primary-subtle-active",
95
184
  boxShadow: "none",
96
185
  color: "$text-primary-active"
@@ -101,14 +190,16 @@ const itemDefaults = {
101
190
  };
102
191
 
103
192
  const StyledIndicator = styled(Primitive.span, {
104
- padding: "4px 6px"
193
+ display: "flex",
194
+ alignItems: "center",
195
+ justifyContent: "center"
105
196
  });
106
197
  const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
107
198
  ...itemDefaults,
108
199
  [`&[data-state="checked"] ${StyledIndicator}`]: {
109
200
  color: "$icon-primary"
110
201
  },
111
- [`&[data-state="checked"]:hover ${StyledIndicator}`]: {
202
+ [`&[data-state="checked"]:hover:not([aria-disabled="true"]) ${StyledIndicator}`]: {
112
203
  color: "$icon-primary-hover"
113
204
  },
114
205
  [`
@@ -119,61 +210,50 @@ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
119
210
  }
120
211
  });
121
212
 
122
- const Context$1 = createContext({
123
- rightSlotMount: () => 0,
124
- rightSlotDestroy: () => {
125
- },
126
- containerSpacing: "medium"
127
- });
128
- const ContentProvider = ({
129
- children,
130
- containerSpacing = "medium"
131
- }) => {
132
- const [maxWidth, setMaxWidth] = useState(0);
133
- const maxRef = useRef(0);
134
- const indexRef = useRef(0);
135
- const widthMapRef = useRef(/* @__PURE__ */ new Map());
136
- const updateMaxWith = useCallback((value) => {
137
- maxRef.current = value;
138
- setMaxWidth(value);
139
- }, []);
140
- const rightSlotMount = useCallback(
141
- (width) => {
142
- indexRef.current++;
143
- widthMapRef.current.set(indexRef.current, width);
144
- if (width > maxRef.current) {
145
- updateMaxWith(width);
213
+ const useAriaDisabled = ({
214
+ "aria-disabled": ariaDisabled,
215
+ onKeyDown,
216
+ onSelect,
217
+ onPointerMove,
218
+ onClick
219
+ }, preventDefault = false) => useMemo(
220
+ () => ({
221
+ "aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
222
+ onKeyDown: (e) => {
223
+ if (booleanify(ariaDisabled) && e.code !== "ArrowUp" && e.code !== "ArrowDown") {
224
+ e.preventDefault();
225
+ e.stopPropagation();
226
+ return;
146
227
  }
147
- return indexRef.current;
228
+ onKeyDown == null ? void 0 : onKeyDown(e);
148
229
  },
149
- [updateMaxWith]
150
- );
151
- const rightSlotDestroy = useCallback(
152
- (index) => {
153
- widthMapRef.current.delete(index);
154
- if (widthMapRef.current.size === 0) {
155
- updateMaxWith(0);
156
- } else {
157
- const maximum = Math.max(...Array.from(widthMapRef.current.values()));
158
- updateMaxWith(maximum);
230
+ onSelect: (e) => {
231
+ if (preventDefault) {
232
+ e.preventDefault();
233
+ }
234
+ if (booleanify(ariaDisabled)) {
235
+ e.preventDefault();
236
+ return;
159
237
  }
238
+ onSelect == null ? void 0 : onSelect(e);
160
239
  },
161
- [updateMaxWith]
162
- );
163
- const formattedChildren = addPropsToChildren(children, () => true, {
164
- UNSAFE_style: {
165
- "--right-slot-max-width": `${Math.ceil(maxWidth)}px`
166
- }
167
- });
168
- return /* @__PURE__ */ React.createElement(Context$1.Provider, {
169
- value: {
170
- rightSlotMount,
171
- rightSlotDestroy,
172
- containerSpacing
240
+ onPointerMove: (e) => {
241
+ if (booleanify(ariaDisabled)) {
242
+ e.preventDefault();
243
+ return;
244
+ }
245
+ onPointerMove == null ? void 0 : onPointerMove(e);
246
+ },
247
+ onClick: (e) => {
248
+ if (booleanify(ariaDisabled)) {
249
+ e.preventDefault();
250
+ return;
251
+ }
252
+ onClick == null ? void 0 : onClick(e);
173
253
  }
174
- }, formattedChildren);
175
- };
176
- const useContent = () => useContext(Context$1);
254
+ }),
255
+ [ariaDisabled, onKeyDown, onSelect, onPointerMove, onClick, preventDefault]
256
+ );
177
257
 
178
258
  const Context = createContext({
179
259
  leftSlotMount: () => {
@@ -203,62 +283,6 @@ const ItemProvider = ({
203
283
  };
204
284
  const useItem = () => useContext(Context);
205
285
 
206
- const RightSlot = (props) => {
207
- const { rightSlotMount, rightSlotDestroy } = useContent();
208
- const ref = useRef(null);
209
- useEffect(() => {
210
- if (ref.current !== null) {
211
- const width = ref.current.getBoundingClientRect().width;
212
- const index = rightSlotMount(width);
213
- return () => rightSlotDestroy(index);
214
- }
215
- return () => {
216
- };
217
- }, [rightSlotMount, rightSlotDestroy, ref]);
218
- return /* @__PURE__ */ React.createElement(StyledRightSlot, {
219
- ref,
220
- ...props
221
- });
222
- };
223
- const HotkeySlot = styled(RightSlot, {
224
- color: "$text-neutrals-subtle"
225
- });
226
- const IllustrationSlot = React.forwardRef((props, forwardRef) => {
227
- const { leftSlotMount, leftSlotDestroy } = useItem();
228
- useEffect(() => {
229
- leftSlotMount();
230
- return () => leftSlotDestroy();
231
- }, [leftSlotMount, leftSlotDestroy]);
232
- return /* @__PURE__ */ React.createElement(StyledIllustrationSlot, {
233
- ref: forwardRef,
234
- ...props
235
- });
236
- });
237
-
238
- const useAriaDisabled = ({ "aria-disabled": ariaDisabled, onKeyDown, onSelect }, preventDefault = false) => useMemo(
239
- () => ({
240
- "aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
241
- onKeyDown: (e) => {
242
- if (booleanify(ariaDisabled) && e.code !== "ArrowUp" && e.code !== "ArrowDown") {
243
- e.preventDefault();
244
- e.stopPropagation();
245
- return;
246
- }
247
- onKeyDown == null ? void 0 : onKeyDown(e);
248
- },
249
- onSelect: (e) => {
250
- if (preventDefault) {
251
- e.preventDefault();
252
- }
253
- if (booleanify(ariaDisabled)) {
254
- return;
255
- }
256
- onSelect == null ? void 0 : onSelect(e);
257
- }
258
- }),
259
- [ariaDisabled, onKeyDown, onSelect, preventDefault]
260
- );
261
-
262
286
  const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled, ...restProps }, forwardRef) => {
263
287
  const ariaDisabledProps = useAriaDisabled(restProps, true);
264
288
  const { "aria-disabled": ariaDisabled } = ariaDisabledProps;
@@ -270,6 +294,7 @@ const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled,
270
294
  disabled,
271
295
  onCheckedChange: onChange
272
296
  }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, (disabled === true || booleanify(ariaDisabled)) && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
297
+ weight: "thin",
273
298
  css: { square: "$3", display: "block" }
274
299
  }), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
275
300
  css: { square: "$3", display: "block" }
@@ -459,7 +484,7 @@ const RadioGroup = React.forwardRef((props, forwardRef) => {
459
484
  });
460
485
  });
461
486
 
462
- const StyledRadioContainer = styled(Primitive.span, {
487
+ const StyledRadioContainer = styled(Primitive.div, {
463
488
  display: "flex",
464
489
  alignItems: "center",
465
490
  justifyContent: "center",
@@ -467,10 +492,9 @@ const StyledRadioContainer = styled(Primitive.span, {
467
492
  height: "$4",
468
493
  boxSizing: "border-box",
469
494
  border: "1px solid $border-neutrals",
470
- borderRadius: "$half",
471
- margin: "2px 4px"
495
+ borderRadius: "$half"
472
496
  });
473
- const StyledPill = styled(Primitive.span, {
497
+ const StyledPill = styled(Primitive.div, {
474
498
  display: "none",
475
499
  width: "$2",
476
500
  height: "$2",
@@ -490,7 +514,7 @@ const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
490
514
  backgroundColor: "$background-primary-prominent-selected"
491
515
  }
492
516
  },
493
- [`&:hover ${StyledRadioContainer}`]: {
517
+ [`&:hover:not([aria-disabled="true"]) ${StyledRadioContainer}`]: {
494
518
  borderColor: "$border-primary-hover",
495
519
  [`& ${StyledPill}`]: {
496
520
  backgroundColor: "$background-primary-prominent-hover"
@@ -523,7 +547,9 @@ const RadioItem = React.forwardRef(({ disabled = false, children, ...restProps }
523
547
  ...ariaDisabledProps,
524
548
  disabled,
525
549
  ref: forwardRef
526
- }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null)))));
550
+ }, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, {
551
+ weight: "thin"
552
+ })))));
527
553
  });
528
554
 
529
555
  const StyledSeparator = styled(RadixDropdownMenu.Separator, {
@@ -538,14 +564,13 @@ const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.
538
564
  const StyledSwitch = styled(Primitive.span, {
539
565
  ...styles.default,
540
566
  width: "$7",
541
- height: "$4",
542
- marginTop: "2px"
567
+ height: "$4"
543
568
  });
544
569
  const StyledSwitchItem = styled(RadixDropdownMenu.CheckboxItem, {
545
570
  ...itemDefaults,
546
571
  [`&[data-state="checked"] ${StyledSwitch}`]: styles.checked,
547
- [`&[data-state="checked"]:hover ${StyledSwitch}`]: styles.checkedHovered,
548
- [`&:hover ${StyledSwitch}`]: styles.hovered,
572
+ [`&[data-state="checked"]:hover:not([aria-disabled="true"]) ${StyledSwitch}`]: styles.checkedHovered,
573
+ [`&:hover:not([aria-disabled="true"]) ${StyledSwitch}`]: styles.hovered,
549
574
  [`
550
575
  &[aria-disabled="true"] ${StyledSwitch},
551
576
  &[data-disabled] ${StyledSwitch}
@@ -573,7 +598,10 @@ const StyledTrigger = styled(RadixDropdownMenu.Trigger, {
573
598
  all: "unset",
574
599
  boxSizing: "border-box",
575
600
  cursor: "pointer",
576
- ...focus.defaults
601
+ ...focus.css({
602
+ boxShadow: "$focus-small",
603
+ outline: "1px solid transparent"
604
+ })
577
605
  },
578
606
  false: {
579
607
  cursor: "pointer"
@@ -592,12 +620,13 @@ const Trigger = React.forwardRef(({ asChild = false, onPress, onClick, ...restPr
592
620
 
593
621
  const StyledIconContainer = styled(Primitive.span, {
594
622
  color: "$icon-neutrals-with-text",
595
- marginRight: "-4px"
623
+ display: "flex",
624
+ alignItems: "center"
596
625
  });
597
626
  const StyledSubTrigger = styled(RadixDropdownMenu.SubTrigger, {
598
627
  ...itemDefaults,
599
- '&[data-state="open"]': itemDefaults["&:hover"],
600
- [`&[data-state="open"] ${StyledIconContainer}, &:hover ${StyledIconContainer}`]: {
628
+ '&[data-state="open"]': itemDefaults['&:hover:not([aria-disabled="true"])'],
629
+ [`&[data-state="open"] ${StyledIconContainer}, &:hover:not([aria-disabled="true"]) ${StyledIconContainer}`]: {
601
630
  color: "$icon-primary-hover"
602
631
  }
603
632
  });
@@ -681,34 +710,47 @@ const Portal = (props) => /* @__PURE__ */ React.createElement(Portal$1, {
681
710
  });
682
711
 
683
712
  const StyledIconSlot = styled(LeftSlot, {
684
- paddingTop: "2px",
685
- variants: {
686
- customIcon: {
687
- true: {
688
- square: "$icon-200"
689
- }
690
- }
713
+ square: "$5",
714
+ "& svg:not([data-icon-component]), & img:not([data-icon-component])": {
715
+ ...styles$1.size.small,
716
+ ...styles$1.weight.thin
691
717
  }
692
718
  });
693
719
 
694
720
  const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
695
721
  const { leftSlotMount, leftSlotDestroy } = useItem();
696
- const child = React.Children.only(children);
697
- const isIcon = isIconComponent(child);
698
- const formattedChild = isIcon ? React.cloneElement(child, {
699
- ...child.props,
700
- size: "small",
701
- weight: "thin"
702
- }) : child;
722
+ const formattedChildren = addPropsToChildren(
723
+ children,
724
+ isIconComponent,
725
+ {
726
+ "data-icon-component": "",
727
+ size: "small",
728
+ weight: "thin"
729
+ }
730
+ );
703
731
  useEffect(() => {
704
732
  leftSlotMount();
705
733
  return () => leftSlotDestroy();
706
734
  }, [leftSlotMount, leftSlotDestroy]);
707
735
  return /* @__PURE__ */ React.createElement(StyledIconSlot, {
708
736
  ref: forwardRef,
709
- ...restProps,
710
- customIcon: !isIcon
711
- }, formattedChild);
737
+ ...restProps
738
+ }, /* @__PURE__ */ React.createElement(Primitive.svg, {
739
+ asChild: true,
740
+ "aria-hidden": true
741
+ }, formattedChildren));
742
+ });
743
+
744
+ const IllustrationSlot = React.forwardRef((props, forwardRef) => {
745
+ const { leftSlotMount, leftSlotDestroy } = useItem();
746
+ useEffect(() => {
747
+ leftSlotMount();
748
+ return () => leftSlotDestroy();
749
+ }, [leftSlotMount, leftSlotDestroy]);
750
+ return /* @__PURE__ */ React.createElement(StyledIllustrationSlot, {
751
+ ref: forwardRef,
752
+ ...props
753
+ });
712
754
  });
713
755
 
714
756
  const DropdownMenu = ({