@mirohq/design-system-dropdown-menu 3.3.0-dropdown.3 → 3.3.0-dropdown.5
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/main.js +174 -56
- package/dist/main.js.map +1 -1
- package/dist/module.js +176 -58
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +600 -123
- package/package.json +8 -8
package/dist/module.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { createContext, useState, 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
5
|
import { booleanify } from '@mirohq/design-system-utils';
|
|
6
6
|
import { Primitive } from '@mirohq/design-system-primitive';
|
|
7
7
|
import { styled, theme } from '@mirohq/design-system-stitches';
|
|
8
8
|
import { focus, animations } from '@mirohq/design-system-styles';
|
|
9
9
|
import { styles, Thumb } from '@mirohq/design-system-base-switch';
|
|
10
|
+
import { isIconComponent } from '@mirohq/design-system-base-icon';
|
|
10
11
|
|
|
11
12
|
const ItemDescription = styled(Primitive.div, {
|
|
12
13
|
display: "-webkit-box",
|
|
@@ -25,18 +26,20 @@ const LeftSlot = styled(Primitive.div, {
|
|
|
25
26
|
marginRight: "$100",
|
|
26
27
|
gridArea: "left-slot"
|
|
27
28
|
});
|
|
28
|
-
const IconSlot = styled(LeftSlot, {
|
|
29
|
-
width: "$6"
|
|
30
|
-
});
|
|
31
29
|
const IllustrationSlot = styled(LeftSlot, {
|
|
32
30
|
width: "$13"
|
|
33
31
|
});
|
|
34
|
-
const
|
|
32
|
+
const StyledRightSlot = styled(Primitive.div, {
|
|
35
33
|
display: "flex",
|
|
36
34
|
alignItems: "center",
|
|
37
35
|
marginLeft: "auto",
|
|
38
36
|
paddingLeft: "$200",
|
|
39
|
-
gridArea: "right-slot"
|
|
37
|
+
gridArea: "right-slot",
|
|
38
|
+
minWidth: "max-content",
|
|
39
|
+
textAlign: "right",
|
|
40
|
+
"&:empty": {
|
|
41
|
+
paddingLeft: "$none"
|
|
42
|
+
}
|
|
40
43
|
});
|
|
41
44
|
|
|
42
45
|
const itemDefaults = {
|
|
@@ -49,16 +52,26 @@ const itemDefaults = {
|
|
|
49
52
|
display: "grid",
|
|
50
53
|
gridTemplateColumns: "auto 1fr auto",
|
|
51
54
|
gridTemplateRows: "1fr auto",
|
|
52
|
-
gridTemplateAreas: `
|
|
53
|
-
'left-slot item-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
minHeight: "$11",
|
|
58
|
-
padding: "$100 $150",
|
|
55
|
+
gridTemplateAreas: `'left-slot item-text right-slot'
|
|
56
|
+
'left-slot item-description right-slot'`,
|
|
57
|
+
alignItems: "start",
|
|
58
|
+
minHeight: "$10",
|
|
59
|
+
padding: "$100 $100",
|
|
59
60
|
position: "relative",
|
|
60
61
|
userSelect: "none",
|
|
61
62
|
cursor: "pointer",
|
|
63
|
+
"&[data-no-left-slot]": {
|
|
64
|
+
gridTemplateColumns: "1fr auto",
|
|
65
|
+
gridTemplateRows: "auto",
|
|
66
|
+
gridTemplateAreas: `'item-text right-slot'
|
|
67
|
+
'item-description right-slot'`
|
|
68
|
+
},
|
|
69
|
+
"&:not(:last-child)": {
|
|
70
|
+
marginBottom: "$50"
|
|
71
|
+
},
|
|
72
|
+
"&:not(:first-child)": {
|
|
73
|
+
marginTop: "$50"
|
|
74
|
+
},
|
|
62
75
|
...focus.defaults,
|
|
63
76
|
'&:disabled, &[aria-disabled="true"], &[data-disabled]': {
|
|
64
77
|
pointerEvents: "none",
|
|
@@ -86,7 +99,9 @@ const itemDefaults = {
|
|
|
86
99
|
}
|
|
87
100
|
};
|
|
88
101
|
|
|
89
|
-
const StyledIndicator = styled(Primitive.span, {
|
|
102
|
+
const StyledIndicator = styled(Primitive.span, {
|
|
103
|
+
padding: "4px 6px"
|
|
104
|
+
});
|
|
90
105
|
const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
|
|
91
106
|
...itemDefaults,
|
|
92
107
|
[`&[data-state="checked"] ${StyledIndicator}`]: {
|
|
@@ -103,6 +118,53 @@ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
|
|
|
103
118
|
}
|
|
104
119
|
});
|
|
105
120
|
|
|
121
|
+
const Context = createContext({
|
|
122
|
+
counter: {
|
|
123
|
+
right: 0,
|
|
124
|
+
left: 0
|
|
125
|
+
},
|
|
126
|
+
increaseCounter: () => {
|
|
127
|
+
},
|
|
128
|
+
decreaseCounter: () => {
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
const SlotsProvider = ({
|
|
132
|
+
children
|
|
133
|
+
}) => {
|
|
134
|
+
const [counter, setCounter] = useState({
|
|
135
|
+
right: 0,
|
|
136
|
+
left: 0
|
|
137
|
+
});
|
|
138
|
+
return /* @__PURE__ */ React.createElement(Context.Provider, {
|
|
139
|
+
value: {
|
|
140
|
+
counter,
|
|
141
|
+
increaseCounter: (side) => {
|
|
142
|
+
setCounter((counter2) => ({
|
|
143
|
+
...counter2,
|
|
144
|
+
[side]: counter2[side] + 1
|
|
145
|
+
}));
|
|
146
|
+
},
|
|
147
|
+
decreaseCounter: (side) => setCounter((counter2) => ({
|
|
148
|
+
...counter2,
|
|
149
|
+
[side]: counter2[side] - 1
|
|
150
|
+
}))
|
|
151
|
+
}
|
|
152
|
+
}, children);
|
|
153
|
+
};
|
|
154
|
+
const useSlots = () => useContext(Context);
|
|
155
|
+
|
|
156
|
+
const RightSlot = (props) => {
|
|
157
|
+
const { increaseCounter, decreaseCounter } = useSlots();
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
increaseCounter("right");
|
|
160
|
+
return () => decreaseCounter("right");
|
|
161
|
+
}, []);
|
|
162
|
+
return /* @__PURE__ */ React.createElement(StyledRightSlot, {
|
|
163
|
+
...props
|
|
164
|
+
});
|
|
165
|
+
};
|
|
166
|
+
const HotkeySlot = RightSlot;
|
|
167
|
+
|
|
106
168
|
const useAriaDisabled = ({ "aria-disabled": ariaDisabled, onKeyDown, onSelect }, preventDefault = false) => useMemo(
|
|
107
169
|
() => ({
|
|
108
170
|
"aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
|
|
@@ -140,26 +202,17 @@ const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled,
|
|
|
140
202
|
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIndicator, null, (disabled === true || booleanify(ariaDisabled)) && !checked && /* @__PURE__ */ React.createElement(IconProhibit, {
|
|
141
203
|
size: "small"
|
|
142
204
|
}), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
|
|
143
|
-
|
|
205
|
+
css: { width: "12px", display: "block" }
|
|
144
206
|
}))));
|
|
145
207
|
});
|
|
146
208
|
|
|
147
|
-
const
|
|
148
|
-
const CONTENT_GUTTER = parseInt(theme.space[GUTTER_TOKEN]);
|
|
209
|
+
const CONTENT_GUTTER = parseInt(theme.space[150]);
|
|
149
210
|
const CONTENT_OFFSET = parseInt(theme.space[50]);
|
|
150
|
-
const ITEM_WITHOUT_RIGHT_SLOT = `[role="menuitem"]:not(:has(${RightSlot}))`;
|
|
151
211
|
const contentDefaults = {
|
|
152
212
|
maxWidth: "$125",
|
|
153
213
|
backgroundColor: "$white",
|
|
154
214
|
borderRadius: "$50",
|
|
155
|
-
padding: `$${GUTTER_TOKEN}`,
|
|
156
215
|
boxShadow: "$50",
|
|
157
|
-
[`&:has(${RightSlot}) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
|
|
158
|
-
paddingRight: "44px"
|
|
159
|
-
},
|
|
160
|
-
[`&:has([role="switch"]) > ${ITEM_WITHOUT_RIGHT_SLOT}`]: {
|
|
161
|
-
paddingRight: "56px"
|
|
162
|
-
},
|
|
163
216
|
"@media (prefers-reduced-motion: no-preference)": {
|
|
164
217
|
animationDuration: "150ms",
|
|
165
218
|
animationTimingFunction: "cubic-bezier(0.25, 0.5, 0.5, 0.9)",
|
|
@@ -191,7 +244,28 @@ const contentDefaults = {
|
|
|
191
244
|
zIndex: "$dropdownMenu"
|
|
192
245
|
};
|
|
193
246
|
|
|
194
|
-
const StyledContent = styled(RadixDropdownMenu.Content,
|
|
247
|
+
const StyledContent = styled(RadixDropdownMenu.Content, {
|
|
248
|
+
...contentDefaults,
|
|
249
|
+
variants: {
|
|
250
|
+
containerSpacing: {
|
|
251
|
+
small: {
|
|
252
|
+
'&, [role="menu"]': {
|
|
253
|
+
padding: "$50 $150"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
medium: {
|
|
257
|
+
'&, [role="menu"]': {
|
|
258
|
+
padding: "$150"
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
large: {
|
|
262
|
+
'&, [role="menu"]': {
|
|
263
|
+
padding: "$150 $300"
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
});
|
|
195
269
|
|
|
196
270
|
const Content = React.forwardRef(
|
|
197
271
|
({
|
|
@@ -204,8 +278,9 @@ const Content = React.forwardRef(
|
|
|
204
278
|
avoidCollisions = true,
|
|
205
279
|
sticky = "partial",
|
|
206
280
|
hideWhenDetached = false,
|
|
281
|
+
containerSpacing = "medium",
|
|
207
282
|
...restProps
|
|
208
|
-
}, forwardRef) => /* @__PURE__ */ React.createElement(StyledContent, {
|
|
283
|
+
}, forwardRef) => /* @__PURE__ */ React.createElement(SlotsProvider, null, /* @__PURE__ */ React.createElement(StyledContent, {
|
|
209
284
|
...restProps,
|
|
210
285
|
ref: forwardRef,
|
|
211
286
|
loop,
|
|
@@ -216,20 +291,32 @@ const Content = React.forwardRef(
|
|
|
216
291
|
avoidCollisions,
|
|
217
292
|
collisionPadding,
|
|
218
293
|
sticky,
|
|
219
|
-
hideWhenDetached
|
|
220
|
-
|
|
294
|
+
hideWhenDetached,
|
|
295
|
+
containerSpacing
|
|
296
|
+
}))
|
|
221
297
|
);
|
|
222
298
|
|
|
223
|
-
const StyledItem = styled(RadixDropdownMenu.Item,
|
|
299
|
+
const StyledItem = styled(RadixDropdownMenu.Item, {
|
|
300
|
+
...itemDefaults,
|
|
301
|
+
variants: {
|
|
302
|
+
hasRightSlot: {
|
|
303
|
+
true: {
|
|
304
|
+
paddingRight: "$600"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
224
309
|
|
|
225
310
|
const Item = React.forwardRef(
|
|
226
311
|
({ disabled = false, ...restProps }, forwardRef) => {
|
|
312
|
+
const { counter } = useSlots();
|
|
227
313
|
const ariaDisabledProps = useAriaDisabled(restProps);
|
|
228
314
|
return /* @__PURE__ */ React.createElement(StyledItem, {
|
|
229
315
|
...restProps,
|
|
230
316
|
...ariaDisabledProps,
|
|
231
317
|
disabled,
|
|
232
|
-
ref: forwardRef
|
|
318
|
+
ref: forwardRef,
|
|
319
|
+
hasRightSlot: counter.right > 0
|
|
233
320
|
});
|
|
234
321
|
}
|
|
235
322
|
);
|
|
@@ -246,7 +333,9 @@ const LinkItem = React.forwardRef(({ children, href, ...restProps }, forwardRef)
|
|
|
246
333
|
}, children));
|
|
247
334
|
});
|
|
248
335
|
|
|
249
|
-
const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup
|
|
336
|
+
const StyledRadioGroup = styled(RadixDropdownMenu.RadioGroup, {
|
|
337
|
+
marginY: "$50"
|
|
338
|
+
});
|
|
250
339
|
|
|
251
340
|
const RadioGroup = React.forwardRef((props, forwardRef) => {
|
|
252
341
|
const { onChange, ...restProps } = props;
|
|
@@ -265,7 +354,8 @@ const StyledRadioContainer = styled(Primitive.span, {
|
|
|
265
354
|
height: "$4",
|
|
266
355
|
boxSizing: "border-box",
|
|
267
356
|
border: "1px solid $border-neutrals",
|
|
268
|
-
borderRadius: "$half"
|
|
357
|
+
borderRadius: "$half",
|
|
358
|
+
marginTop: "2px"
|
|
269
359
|
});
|
|
270
360
|
const StyledPill = styled(Primitive.span, {
|
|
271
361
|
display: "none",
|
|
@@ -324,8 +414,7 @@ const RadioItem = React.forwardRef(({ disabled = false, children, ...restProps }
|
|
|
324
414
|
});
|
|
325
415
|
|
|
326
416
|
const StyledSeparator = styled(RadixDropdownMenu.Separator, {
|
|
327
|
-
borderTop: "1px solid $border-neutrals-subtle"
|
|
328
|
-
marginY: "$100"
|
|
417
|
+
borderTop: "1px solid $border-neutrals-subtle"
|
|
329
418
|
});
|
|
330
419
|
|
|
331
420
|
const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.createElement(StyledSeparator, {
|
|
@@ -336,7 +425,8 @@ const Separator = React.forwardRef((props, forwardRef) => /* @__PURE__ */ React.
|
|
|
336
425
|
const StyledSwitch = styled(Primitive.span, {
|
|
337
426
|
...styles.default,
|
|
338
427
|
width: "$7",
|
|
339
|
-
height: "$4"
|
|
428
|
+
height: "$4",
|
|
429
|
+
marginTop: "2px"
|
|
340
430
|
});
|
|
341
431
|
const StyledSwitchItem = styled(RadixDropdownMenu.CheckboxItem, {
|
|
342
432
|
...itemDefaults,
|
|
@@ -363,19 +453,18 @@ const SwitchItem = React.forwardRef(
|
|
|
363
453
|
}
|
|
364
454
|
);
|
|
365
455
|
|
|
366
|
-
const defaultStyles = {
|
|
367
|
-
boxSizing: "border-box",
|
|
368
|
-
cursor: "pointer",
|
|
369
|
-
...focus.defaults
|
|
370
|
-
};
|
|
371
456
|
const StyledTrigger = styled(RadixDropdownMenu.Trigger, {
|
|
372
457
|
variants: {
|
|
373
458
|
unstyled: {
|
|
374
459
|
true: {
|
|
375
460
|
all: "unset",
|
|
376
|
-
|
|
461
|
+
boxSizing: "border-box",
|
|
462
|
+
cursor: "pointer",
|
|
463
|
+
...focus.defaults
|
|
377
464
|
},
|
|
378
|
-
false:
|
|
465
|
+
false: {
|
|
466
|
+
cursor: "pointer"
|
|
467
|
+
}
|
|
379
468
|
}
|
|
380
469
|
}
|
|
381
470
|
});
|
|
@@ -388,21 +477,18 @@ const Trigger = React.forwardRef(({ asChild = false, onPress, onClick, ...restPr
|
|
|
388
477
|
asChild
|
|
389
478
|
}));
|
|
390
479
|
|
|
480
|
+
const StyledIconContainer = styled(Primitive.span, {
|
|
481
|
+
color: "$icon-neutrals-with-text",
|
|
482
|
+
marginRight: "-4px"
|
|
483
|
+
});
|
|
391
484
|
const StyledSubTrigger = styled(RadixDropdownMenu.SubTrigger, {
|
|
392
485
|
...itemDefaults,
|
|
393
|
-
'&[data-state="open"]': itemDefaults["&:hover"]
|
|
486
|
+
'&[data-state="open"]': itemDefaults["&:hover"],
|
|
487
|
+
[`&[data-state="open"] ${StyledIconContainer}, &:hover ${StyledIconContainer}`]: {
|
|
488
|
+
color: "$icon-primary-hover"
|
|
489
|
+
}
|
|
394
490
|
});
|
|
395
491
|
|
|
396
|
-
const ArrowIcon = () => /* @__PURE__ */ React.createElement("svg", {
|
|
397
|
-
width: "16",
|
|
398
|
-
height: "16",
|
|
399
|
-
viewBox: "0 0 16 16",
|
|
400
|
-
fill: "currentColor",
|
|
401
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
402
|
-
"data-testid": "submenu-arrow-icon"
|
|
403
|
-
}, /* @__PURE__ */ React.createElement("path", {
|
|
404
|
-
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"
|
|
405
|
-
}));
|
|
406
492
|
const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => {
|
|
407
493
|
const { onSelect, ...ariaDisabledProps } = useAriaDisabled({
|
|
408
494
|
onKeyDown: restProps.onKeyDown,
|
|
@@ -413,7 +499,12 @@ const SubTrigger = React.forwardRef(({ children, disabled = false, ...restProps
|
|
|
413
499
|
...ariaDisabledProps,
|
|
414
500
|
disabled,
|
|
415
501
|
ref: forwardRef
|
|
416
|
-
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(
|
|
502
|
+
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledIconContainer, {
|
|
503
|
+
"data-testid": process.env.NODE_ENV === "test" ? "submenu-arrow-icon" : void 0
|
|
504
|
+
}, /* @__PURE__ */ React.createElement(IconChevronRight, {
|
|
505
|
+
size: "small",
|
|
506
|
+
weight: "thin"
|
|
507
|
+
}))));
|
|
417
508
|
});
|
|
418
509
|
|
|
419
510
|
const StyledSubContent = styled(
|
|
@@ -431,7 +522,7 @@ const SubContent = React.forwardRef(
|
|
|
431
522
|
hideWhenDetached = false,
|
|
432
523
|
sticky = "partial",
|
|
433
524
|
...restProps
|
|
434
|
-
}, forwardRef) => /* @__PURE__ */ React.createElement(StyledSubContent, {
|
|
525
|
+
}, forwardRef) => /* @__PURE__ */ React.createElement(SlotsProvider, null, /* @__PURE__ */ React.createElement(StyledSubContent, {
|
|
435
526
|
...restProps,
|
|
436
527
|
ref: forwardRef,
|
|
437
528
|
sideOffset,
|
|
@@ -440,7 +531,7 @@ const SubContent = React.forwardRef(
|
|
|
440
531
|
loop,
|
|
441
532
|
hideWhenDetached,
|
|
442
533
|
sticky
|
|
443
|
-
})
|
|
534
|
+
}))
|
|
444
535
|
);
|
|
445
536
|
|
|
446
537
|
const StyledSub = styled(RadixDropdownMenu.Sub, {});
|
|
@@ -466,6 +557,32 @@ const Portal = (props) => /* @__PURE__ */ React.createElement(Portal$1, {
|
|
|
466
557
|
...props
|
|
467
558
|
});
|
|
468
559
|
|
|
560
|
+
const StyledIconSlot = styled(LeftSlot, {
|
|
561
|
+
paddingTop: "2px",
|
|
562
|
+
variants: {
|
|
563
|
+
customIcon: {
|
|
564
|
+
true: {
|
|
565
|
+
square: "$icon-200"
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
});
|
|
570
|
+
|
|
571
|
+
const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
|
|
572
|
+
const child = React.Children.only(children);
|
|
573
|
+
const isIcon = isIconComponent(child);
|
|
574
|
+
const formattedChild = isIcon ? React.cloneElement(child, {
|
|
575
|
+
...child.props,
|
|
576
|
+
size: "small",
|
|
577
|
+
weight: "thin"
|
|
578
|
+
}) : child;
|
|
579
|
+
return /* @__PURE__ */ React.createElement(StyledIconSlot, {
|
|
580
|
+
ref: forwardRef,
|
|
581
|
+
...restProps,
|
|
582
|
+
customIcon: !isIcon
|
|
583
|
+
}, formattedChild);
|
|
584
|
+
});
|
|
585
|
+
|
|
469
586
|
const DropdownMenu = ({
|
|
470
587
|
defaultOpen = false,
|
|
471
588
|
direction = "ltr",
|
|
@@ -491,6 +608,7 @@ const DropdownMenu = ({
|
|
|
491
608
|
};
|
|
492
609
|
DropdownMenu.CheckboxItem = CheckboxItem;
|
|
493
610
|
DropdownMenu.Content = Content;
|
|
611
|
+
DropdownMenu.HotkeySlot = HotkeySlot;
|
|
494
612
|
DropdownMenu.IconSlot = IconSlot;
|
|
495
613
|
DropdownMenu.IllustrationSlot = IllustrationSlot;
|
|
496
614
|
DropdownMenu.Item = Item;
|