@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/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 IllustrationSlot = styled(LeftSlot, {
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(SlotsProvider, null, /* @__PURE__ */ React.createElement(StyledContent, {
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
- hasRightSlot: counter.right > 0
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(SlotsProvider, null, /* @__PURE__ */ React.createElement(StyledSubContent, {
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,