@mirohq/design-system-dropdown-menu 3.3.0-dropdown.5 → 3.3.0-dropdown.6
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 +132 -63
- package/dist/main.js.map +1 -1
- package/dist/module.js +134 -65
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +225 -562
- package/package.json +2 -2
package/dist/module.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React, { createContext, useState, useContext, useEffect, useMemo } 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
4
|
import { IconProhibit, IconCheckMark, IconChevronRight } from '@mirohq/design-system-icons';
|
|
5
|
-
import { booleanify } from '@mirohq/design-system-utils';
|
|
5
|
+
import { addPropsToChildren, 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';
|
|
@@ -20,13 +20,66 @@ const ItemDescription = styled(Primitive.div, {
|
|
|
20
20
|
color: "$text-neutrals-subtle"
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
+
const Context$1 = createContext({
|
|
24
|
+
rightSlotMount: () => 0,
|
|
25
|
+
rightSlotDestroy: () => {
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const ContentProvider = ({
|
|
29
|
+
children
|
|
30
|
+
}) => {
|
|
31
|
+
const [maxWidth, setMaxWidth] = useState(0);
|
|
32
|
+
const maxRef = useRef(0);
|
|
33
|
+
const indexRef = useRef(0);
|
|
34
|
+
const widthMapRef = useRef(/* @__PURE__ */ new Map());
|
|
35
|
+
const updateMaxWith = useCallback((value) => {
|
|
36
|
+
maxRef.current = value;
|
|
37
|
+
setMaxWidth(value);
|
|
38
|
+
}, []);
|
|
39
|
+
const rightSlotMount = useCallback(
|
|
40
|
+
(width) => {
|
|
41
|
+
indexRef.current++;
|
|
42
|
+
widthMapRef.current.set(indexRef.current, width);
|
|
43
|
+
if (width > maxRef.current) {
|
|
44
|
+
updateMaxWith(width);
|
|
45
|
+
}
|
|
46
|
+
return indexRef.current;
|
|
47
|
+
},
|
|
48
|
+
[updateMaxWith]
|
|
49
|
+
);
|
|
50
|
+
const rightSlotDestroy = useCallback(
|
|
51
|
+
(index) => {
|
|
52
|
+
widthMapRef.current.delete(index);
|
|
53
|
+
if (widthMapRef.current.size === 0) {
|
|
54
|
+
updateMaxWith(0);
|
|
55
|
+
} else {
|
|
56
|
+
const maximum = Math.max(...Array.from(widthMapRef.current.values()));
|
|
57
|
+
updateMaxWith(maximum);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
[updateMaxWith]
|
|
61
|
+
);
|
|
62
|
+
const formattedChildren = addPropsToChildren(children, () => true, {
|
|
63
|
+
UNSAFE_style: {
|
|
64
|
+
"--right-slot-max-width": `${Math.ceil(maxWidth)}px`
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return /* @__PURE__ */ React.createElement(Context$1.Provider, {
|
|
68
|
+
value: {
|
|
69
|
+
rightSlotMount,
|
|
70
|
+
rightSlotDestroy
|
|
71
|
+
}
|
|
72
|
+
}, formattedChildren);
|
|
73
|
+
};
|
|
74
|
+
const useContent = () => useContext(Context$1);
|
|
75
|
+
|
|
23
76
|
const LeftSlot = styled(Primitive.div, {
|
|
24
77
|
display: "flex",
|
|
25
78
|
placeContent: "center",
|
|
26
79
|
marginRight: "$100",
|
|
27
80
|
gridArea: "left-slot"
|
|
28
81
|
});
|
|
29
|
-
const
|
|
82
|
+
const StyledIllustrationSlot = styled(LeftSlot, {
|
|
30
83
|
width: "$13"
|
|
31
84
|
});
|
|
32
85
|
const StyledRightSlot = styled(Primitive.div, {
|
|
@@ -42,6 +95,66 @@ const StyledRightSlot = styled(Primitive.div, {
|
|
|
42
95
|
}
|
|
43
96
|
});
|
|
44
97
|
|
|
98
|
+
const Context = createContext({
|
|
99
|
+
leftSlotMount: () => {
|
|
100
|
+
},
|
|
101
|
+
leftSlotDestroy: () => {
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const ItemProvider = ({
|
|
105
|
+
children
|
|
106
|
+
}) => {
|
|
107
|
+
const [hasSlot, setHasSlot] = useState(false);
|
|
108
|
+
const leftSlotMount = useCallback(() => {
|
|
109
|
+
setHasSlot(true);
|
|
110
|
+
}, []);
|
|
111
|
+
const leftSlotDestroy = useCallback(() => {
|
|
112
|
+
setHasSlot(false);
|
|
113
|
+
}, []);
|
|
114
|
+
const formattedChildren = hasSlot ? children : addPropsToChildren(children, () => true, {
|
|
115
|
+
"data-no-left-slot": ""
|
|
116
|
+
});
|
|
117
|
+
return /* @__PURE__ */ React.createElement(Context.Provider, {
|
|
118
|
+
value: {
|
|
119
|
+
leftSlotMount,
|
|
120
|
+
leftSlotDestroy
|
|
121
|
+
}
|
|
122
|
+
}, formattedChildren);
|
|
123
|
+
};
|
|
124
|
+
const useItem = () => useContext(Context);
|
|
125
|
+
|
|
126
|
+
const RightSlot = (props) => {
|
|
127
|
+
const { rightSlotMount, rightSlotDestroy } = useContent();
|
|
128
|
+
const ref = useRef(null);
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (ref.current !== null) {
|
|
131
|
+
const width = ref.current.getBoundingClientRect().width;
|
|
132
|
+
const index = rightSlotMount(width);
|
|
133
|
+
return () => rightSlotDestroy(index);
|
|
134
|
+
}
|
|
135
|
+
return () => {
|
|
136
|
+
};
|
|
137
|
+
}, [rightSlotMount, rightSlotDestroy, ref]);
|
|
138
|
+
return /* @__PURE__ */ React.createElement(StyledRightSlot, {
|
|
139
|
+
ref,
|
|
140
|
+
...props
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
const HotkeySlot = styled(RightSlot, {
|
|
144
|
+
color: "$text-neutrals-subtle"
|
|
145
|
+
});
|
|
146
|
+
const IllustrationSlot = React.forwardRef((props, forwardRef) => {
|
|
147
|
+
const { leftSlotMount, leftSlotDestroy } = useItem();
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
leftSlotMount();
|
|
150
|
+
return () => leftSlotDestroy();
|
|
151
|
+
}, [leftSlotMount, leftSlotDestroy]);
|
|
152
|
+
return /* @__PURE__ */ React.createElement(StyledIllustrationSlot, {
|
|
153
|
+
ref: forwardRef,
|
|
154
|
+
...props
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
45
158
|
const itemDefaults = {
|
|
46
159
|
all: "unset",
|
|
47
160
|
boxSizing: "border-box",
|
|
@@ -50,7 +163,7 @@ const itemDefaults = {
|
|
|
50
163
|
color: "$text-neutrals",
|
|
51
164
|
borderRadius: "$50",
|
|
52
165
|
display: "grid",
|
|
53
|
-
gridTemplateColumns: "auto 1fr auto",
|
|
166
|
+
gridTemplateColumns: "auto 1fr minmax(auto, var(--right-slot-max-width))",
|
|
54
167
|
gridTemplateRows: "1fr auto",
|
|
55
168
|
gridTemplateAreas: `'left-slot item-text right-slot'
|
|
56
169
|
'left-slot item-description right-slot'`,
|
|
@@ -61,7 +174,7 @@ const itemDefaults = {
|
|
|
61
174
|
userSelect: "none",
|
|
62
175
|
cursor: "pointer",
|
|
63
176
|
"&[data-no-left-slot]": {
|
|
64
|
-
gridTemplateColumns: "1fr auto",
|
|
177
|
+
gridTemplateColumns: "1fr minmax(auto, var(--right-slot-max-width))",
|
|
65
178
|
gridTemplateRows: "auto",
|
|
66
179
|
gridTemplateAreas: `'item-text right-slot'
|
|
67
180
|
'item-description right-slot'`
|
|
@@ -118,53 +231,6 @@ const StyledCheckboxItem = styled(RadixDropdownMenu.CheckboxItem, {
|
|
|
118
231
|
}
|
|
119
232
|
});
|
|
120
233
|
|
|
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
|
-
|
|
168
234
|
const useAriaDisabled = ({ "aria-disabled": ariaDisabled, onKeyDown, onSelect }, preventDefault = false) => useMemo(
|
|
169
235
|
() => ({
|
|
170
236
|
"aria-disabled": booleanify(ariaDisabled) ? ariaDisabled : void 0,
|
|
@@ -192,7 +258,7 @@ const useAriaDisabled = ({ "aria-disabled": ariaDisabled, onKeyDown, onSelect },
|
|
|
192
258
|
const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled, ...restProps }, forwardRef) => {
|
|
193
259
|
const ariaDisabledProps = useAriaDisabled(restProps, true);
|
|
194
260
|
const { "aria-disabled": ariaDisabled } = ariaDisabledProps;
|
|
195
|
-
return /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
|
|
261
|
+
return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledCheckboxItem, {
|
|
196
262
|
...restProps,
|
|
197
263
|
...ariaDisabledProps,
|
|
198
264
|
ref: forwardRef,
|
|
@@ -203,7 +269,7 @@ const CheckboxItem = React.forwardRef(({ children, checked, onChange, disabled,
|
|
|
203
269
|
size: "small"
|
|
204
270
|
}), checked && /* @__PURE__ */ React.createElement(IconCheckMark, {
|
|
205
271
|
css: { width: "12px", display: "block" }
|
|
206
|
-
}))));
|
|
272
|
+
})))));
|
|
207
273
|
});
|
|
208
274
|
|
|
209
275
|
const CONTENT_GUTTER = parseInt(theme.space[150]);
|
|
@@ -280,7 +346,7 @@ const Content = React.forwardRef(
|
|
|
280
346
|
hideWhenDetached = false,
|
|
281
347
|
containerSpacing = "medium",
|
|
282
348
|
...restProps
|
|
283
|
-
}, forwardRef) => /* @__PURE__ */ React.createElement(
|
|
349
|
+
}, forwardRef) => /* @__PURE__ */ React.createElement(ContentProvider, null, /* @__PURE__ */ React.createElement(StyledContent, {
|
|
284
350
|
...restProps,
|
|
285
351
|
ref: forwardRef,
|
|
286
352
|
loop,
|
|
@@ -309,15 +375,13 @@ const StyledItem = styled(RadixDropdownMenu.Item, {
|
|
|
309
375
|
|
|
310
376
|
const Item = React.forwardRef(
|
|
311
377
|
({ disabled = false, ...restProps }, forwardRef) => {
|
|
312
|
-
const { counter } = useSlots();
|
|
313
378
|
const ariaDisabledProps = useAriaDisabled(restProps);
|
|
314
|
-
return /* @__PURE__ */ React.createElement(StyledItem, {
|
|
379
|
+
return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledItem, {
|
|
315
380
|
...restProps,
|
|
316
381
|
...ariaDisabledProps,
|
|
317
382
|
disabled,
|
|
318
|
-
ref: forwardRef
|
|
319
|
-
|
|
320
|
-
});
|
|
383
|
+
ref: forwardRef
|
|
384
|
+
}));
|
|
321
385
|
}
|
|
322
386
|
);
|
|
323
387
|
|
|
@@ -405,12 +469,12 @@ const StyledRadioItem = styled(RadixDropdownMenu.RadioItem, {
|
|
|
405
469
|
|
|
406
470
|
const RadioItem = React.forwardRef(({ disabled = false, children, ...restProps }, forwardRef) => {
|
|
407
471
|
const ariaDisabledProps = useAriaDisabled(restProps, true);
|
|
408
|
-
return /* @__PURE__ */ React.createElement(StyledRadioItem, {
|
|
472
|
+
return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledRadioItem, {
|
|
409
473
|
...restProps,
|
|
410
474
|
...ariaDisabledProps,
|
|
411
475
|
disabled,
|
|
412
476
|
ref: forwardRef
|
|
413
|
-
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null))));
|
|
477
|
+
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledRadioContainer, null, /* @__PURE__ */ React.createElement(StyledPill, null), /* @__PURE__ */ React.createElement(StyledProhibited, null)))));
|
|
414
478
|
});
|
|
415
479
|
|
|
416
480
|
const StyledSeparator = styled(RadixDropdownMenu.Separator, {
|
|
@@ -442,14 +506,14 @@ const StyledSwitchItem = styled(RadixDropdownMenu.CheckboxItem, {
|
|
|
442
506
|
const SwitchItem = React.forwardRef(
|
|
443
507
|
({ disabled = false, checked, onChange, children, ...restProps }, forwardRef) => {
|
|
444
508
|
const ariaDisabledProps = useAriaDisabled(restProps, true);
|
|
445
|
-
return /* @__PURE__ */ React.createElement(StyledSwitchItem, {
|
|
509
|
+
return /* @__PURE__ */ React.createElement(ItemProvider, null, /* @__PURE__ */ React.createElement(StyledSwitchItem, {
|
|
446
510
|
...restProps,
|
|
447
511
|
...ariaDisabledProps,
|
|
448
512
|
disabled,
|
|
449
513
|
checked,
|
|
450
514
|
onCheckedChange: onChange,
|
|
451
515
|
ref: forwardRef
|
|
452
|
-
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledSwitch, null, /* @__PURE__ */ React.createElement(Thumb, null))));
|
|
516
|
+
}, children, /* @__PURE__ */ React.createElement(RightSlot, null, /* @__PURE__ */ React.createElement(StyledSwitch, null, /* @__PURE__ */ React.createElement(Thumb, null)))));
|
|
453
517
|
}
|
|
454
518
|
);
|
|
455
519
|
|
|
@@ -522,7 +586,7 @@ const SubContent = React.forwardRef(
|
|
|
522
586
|
hideWhenDetached = false,
|
|
523
587
|
sticky = "partial",
|
|
524
588
|
...restProps
|
|
525
|
-
}, forwardRef) => /* @__PURE__ */ React.createElement(
|
|
589
|
+
}, forwardRef) => /* @__PURE__ */ React.createElement(ContentProvider, null, /* @__PURE__ */ React.createElement(StyledSubContent, {
|
|
526
590
|
...restProps,
|
|
527
591
|
ref: forwardRef,
|
|
528
592
|
sideOffset,
|
|
@@ -569,6 +633,7 @@ const StyledIconSlot = styled(LeftSlot, {
|
|
|
569
633
|
});
|
|
570
634
|
|
|
571
635
|
const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
|
|
636
|
+
const { leftSlotMount, leftSlotDestroy } = useItem();
|
|
572
637
|
const child = React.Children.only(children);
|
|
573
638
|
const isIcon = isIconComponent(child);
|
|
574
639
|
const formattedChild = isIcon ? React.cloneElement(child, {
|
|
@@ -576,6 +641,10 @@ const IconSlot = React.forwardRef(({ children, ...restProps }, forwardRef) => {
|
|
|
576
641
|
size: "small",
|
|
577
642
|
weight: "thin"
|
|
578
643
|
}) : child;
|
|
644
|
+
useEffect(() => {
|
|
645
|
+
leftSlotMount();
|
|
646
|
+
return () => leftSlotDestroy();
|
|
647
|
+
}, [leftSlotMount, leftSlotDestroy]);
|
|
579
648
|
return /* @__PURE__ */ React.createElement(StyledIconSlot, {
|
|
580
649
|
ref: forwardRef,
|
|
581
650
|
...restProps,
|