@mirohq/design-system-dropdown-menu 4.4.8 → 4.4.10-dropdown-on-pointerup.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/main.js CHANGED
@@ -14,9 +14,11 @@ var designSystemStitches = require('@mirohq/design-system-stitches');
14
14
  var designSystemStyles = require('@mirohq/design-system-styles');
15
15
  var designSystemBaseHotkey = require('@mirohq/design-system-base-hotkey');
16
16
  var designSystemUseLayoutEffect = require('@mirohq/design-system-use-layout-effect');
17
+ var designSystemUseAriaDisabled = require('@mirohq/design-system-use-aria-disabled');
17
18
  var designSystemScrollArea = require('@mirohq/design-system-scroll-area');
18
19
  var designSystemBaseSwitch = require('@mirohq/design-system-base-switch');
19
20
  var utils = require('@react-aria/utils');
21
+ var designSystemUsePress = require('@mirohq/design-system-use-press');
20
22
  var designSystemBaseIcon = require('@mirohq/design-system-base-icon');
21
23
 
22
24
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -273,29 +275,24 @@ const RightSlot = (props) => {
273
275
  return /* @__PURE__ */ jsxRuntime.jsx(StyledRightSlot, { ref, ...props });
274
276
  };
275
277
 
276
- const useAriaDisabled = ({
277
- "aria-disabled": ariaDisabled,
278
- onKeyDown,
279
- onSelect,
280
- onPointerMove,
281
- onClick
282
- }, closeOnCheck = true) => React.useMemo(
283
- () => ({
284
- "aria-disabled": designSystemUtils.booleanify(ariaDisabled) ? ariaDisabled : void 0,
285
- onKeyDown: (e) => {
286
- if (designSystemUtils.booleanify(ariaDisabled) && e.code !== "ArrowUp" && e.code !== "ArrowDown" && e.code !== "Escape") {
287
- e.preventDefault();
288
- e.stopPropagation();
289
- return;
290
- }
291
- onKeyDown == null ? void 0 : onKeyDown(e);
292
- },
278
+ const useAriaDisabled = ({ onSelect, ...restProps }, { exceptions, closeOnSelect = true } = {}) => {
279
+ const elementProps = designSystemUseAriaDisabled.useAriaDisabled(restProps, {
280
+ ...exceptions,
281
+ allowArrows: true
282
+ });
283
+ const { "aria-disabled": ariaDisabled, onPointerMove, onClick } = elementProps;
284
+ return {
285
+ ...elementProps,
286
+ // these events need to be manually included
287
+ // bacause useAriaDisabled only removes the events from the props.
288
+ // Radix uses these events to handle the dropdown menu so we need to prevent
289
+ // it from being called when the item is aria-disabled.
293
290
  onSelect: (e) => {
294
291
  if (designSystemUtils.booleanify(ariaDisabled)) {
295
292
  e.preventDefault();
296
293
  return;
297
294
  }
298
- if (!closeOnCheck) {
295
+ if (!closeOnSelect) {
299
296
  e.preventDefault();
300
297
  }
301
298
  onSelect == null ? void 0 : onSelect(e);
@@ -314,9 +311,8 @@ const useAriaDisabled = ({
314
311
  }
315
312
  onClick == null ? void 0 : onClick(e);
316
313
  }
317
- }),
318
- [ariaDisabled, onKeyDown, onSelect, onPointerMove, onClick, closeOnCheck]
319
- );
314
+ };
315
+ };
320
316
 
321
317
  const Context = React.createContext({
322
318
  leftSlotMount: () => {
@@ -360,16 +356,15 @@ const CheckboxItem = React__default["default"].forwardRef(
360
356
  variant = "ghost",
361
357
  ...restProps
362
358
  }, forwardRef) => {
363
- const ariaDisabledProps = useAriaDisabled(restProps, closeOnSelect);
364
- const { "aria-disabled": ariaDisabled } = ariaDisabledProps;
359
+ const elementProps = useAriaDisabled(restProps, { closeOnSelect });
360
+ const { "aria-disabled": ariaDisabled } = restProps;
365
361
  const iconCss = { square: "100%", display: "block" };
366
362
  const isAriaDisabled = designSystemUtils.booleanify(ariaDisabled != null ? ariaDisabled : false);
367
363
  const disabledUnchecked = (disabled === true || isAriaDisabled) && checked === false;
368
364
  return /* @__PURE__ */ jsxRuntime.jsx(ItemProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
369
365
  StyledCheckboxItem,
370
366
  {
371
- ...restProps,
372
- ...ariaDisabledProps,
367
+ ...elementProps,
373
368
  ref: forwardRef,
374
369
  checked,
375
370
  disabled,
@@ -486,16 +481,25 @@ const ScrollableContent = ({
486
481
  const DropdownContext = React.createContext({});
487
482
  const DropdownProvider = ({
488
483
  children,
484
+ open: rootOpen,
489
485
  ...restProps
490
- }) => /* @__PURE__ */ jsxRuntime.jsx(
491
- DropdownContext.Provider,
492
- {
493
- value: {
494
- ...restProps
495
- },
496
- children
497
- }
498
- );
486
+ }) => {
487
+ const [open, setOpen] = React.useState(rootOpen);
488
+ const triggerRef = React.useRef(null);
489
+ return /* @__PURE__ */ jsxRuntime.jsx(
490
+ DropdownContext.Provider,
491
+ {
492
+ value: {
493
+ ...restProps,
494
+ rootOpen,
495
+ open,
496
+ setOpen,
497
+ triggerRef
498
+ },
499
+ children
500
+ }
501
+ );
502
+ };
499
503
  const useDropdownContext = () => React.useContext(DropdownContext);
500
504
 
501
505
  const Content = React__default["default"].forwardRef(
@@ -512,10 +516,11 @@ const Content = React__default["default"].forwardRef(
512
516
  containerSpacing = "medium",
513
517
  overflow = "visible",
514
518
  maxHeight,
519
+ onInteractOutside,
515
520
  children,
516
521
  ...restProps
517
522
  }, forwardRef) => {
518
- const { direction } = useDropdownContext();
523
+ const { direction, triggerRef } = useDropdownContext();
519
524
  return /* @__PURE__ */ jsxRuntime.jsx(ContentProvider, { containerSpacing, children: /* @__PURE__ */ jsxRuntime.jsx(
520
525
  StyledContent,
521
526
  {
@@ -530,6 +535,12 @@ const Content = React__default["default"].forwardRef(
530
535
  collisionPadding,
531
536
  sticky,
532
537
  hideWhenDetached,
538
+ onInteractOutside: (e) => {
539
+ if (e.target === triggerRef.current) {
540
+ e.preventDefault();
541
+ }
542
+ onInteractOutside == null ? void 0 : onInteractOutside(e);
543
+ },
533
544
  children: /* @__PURE__ */ jsxRuntime.jsx(
534
545
  ScrollableContent,
535
546
  {
@@ -575,12 +586,11 @@ const StyledItem = designSystemStitches.styled(RadixDropdownMenu__namespace.Item
575
586
 
576
587
  const Item = React__default["default"].forwardRef(
577
588
  ({ disabled = false, variant = "subtle", ...restProps }, forwardRef) => {
578
- const ariaDisabledProps = useAriaDisabled(restProps);
589
+ const elementProps = useAriaDisabled(restProps);
579
590
  return /* @__PURE__ */ jsxRuntime.jsx(ItemProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(
580
591
  StyledItem,
581
592
  {
582
- ...restProps,
583
- ...ariaDisabledProps,
593
+ ...elementProps,
584
594
  variant,
585
595
  disabled,
586
596
  ref: forwardRef
@@ -589,10 +599,7 @@ const Item = React__default["default"].forwardRef(
589
599
  }
590
600
  );
591
601
 
592
- const LinkItem = React__default["default"].forwardRef(({ children, href, ...restProps }, forwardRef) => {
593
- const ariaDisabledProps = useAriaDisabled(restProps);
594
- return /* @__PURE__ */ jsxRuntime.jsx(Item, { asChild: true, ref: forwardRef, ...restProps, ...ariaDisabledProps, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href, children }) });
595
- });
602
+ const LinkItem = React__default["default"].forwardRef(({ children, href, ...restProps }, forwardRef) => /* @__PURE__ */ jsxRuntime.jsx(Item, { asChild: true, ref: forwardRef, ...restProps, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href, children }) }));
596
603
 
597
604
  const StyledRadioGroup = designSystemStitches.styled(RadixDropdownMenu__namespace.RadioGroup, {
598
605
  display: "grid",
@@ -662,23 +669,16 @@ const StyledRadioItem = designSystemStitches.styled(RadixDropdownMenu__namespace
662
669
  });
663
670
 
664
671
  const RadioItem = React__default["default"].forwardRef(({ disabled, children, closeOnSelect = false, ...restProps }, forwardRef) => {
665
- const ariaDisabledProps = useAriaDisabled(restProps, closeOnSelect);
666
- return /* @__PURE__ */ jsxRuntime.jsx(ItemProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
667
- StyledRadioItem,
668
- {
669
- ...restProps,
670
- ...ariaDisabledProps,
671
- disabled,
672
- ref: forwardRef,
673
- children: [
674
- children,
675
- /* @__PURE__ */ jsxRuntime.jsx(RightSlot, { children: /* @__PURE__ */ jsxRuntime.jsxs(StyledRadioContainer, { children: [
676
- /* @__PURE__ */ jsxRuntime.jsx(StyledPill, {}),
677
- /* @__PURE__ */ jsxRuntime.jsx(StyledProhibited, { weight: "thin" })
678
- ] }) })
679
- ]
680
- }
681
- ) });
672
+ const elementProps = useAriaDisabled(restProps, {
673
+ closeOnSelect
674
+ });
675
+ return /* @__PURE__ */ jsxRuntime.jsx(ItemProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(StyledRadioItem, { ...elementProps, disabled, ref: forwardRef, children: [
676
+ children,
677
+ /* @__PURE__ */ jsxRuntime.jsx(RightSlot, { children: /* @__PURE__ */ jsxRuntime.jsxs(StyledRadioContainer, { children: [
678
+ /* @__PURE__ */ jsxRuntime.jsx(StyledPill, {}),
679
+ /* @__PURE__ */ jsxRuntime.jsx(StyledProhibited, { weight: "thin" })
680
+ ] }) })
681
+ ] }) });
682
682
  });
683
683
 
684
684
  const StyledSeparator = designSystemStitches.styled(RadixDropdownMenu__namespace.Separator, {
@@ -705,16 +705,15 @@ const SwitchItem = React__default["default"].forwardRef(
705
705
  disabled,
706
706
  checked,
707
707
  onChange,
708
- children,
709
708
  closeOnSelect = false,
709
+ children,
710
710
  ...restProps
711
711
  }, forwardRef) => {
712
- const ariaDisabledProps = useAriaDisabled(restProps, closeOnSelect);
712
+ const elementProps = useAriaDisabled(restProps, { closeOnSelect });
713
713
  return /* @__PURE__ */ jsxRuntime.jsx(ItemProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
714
714
  StyledSwitchItem,
715
715
  {
716
- ...restProps,
717
- ...ariaDisabledProps,
716
+ ...elementProps,
718
717
  disabled,
719
718
  checked,
720
719
  onCheckedChange: onChange,
@@ -747,8 +746,9 @@ const StyledTrigger = designSystemStitches.styled(RadixDropdownMenu__namespace.T
747
746
  }
748
747
  });
749
748
 
750
- const Trigger = React__default["default"].forwardRef(({ asChild = false, onClick, ...restProps }, forwardRef) => {
749
+ const Trigger = React__default["default"].forwardRef(({ asChild = false, ...restProps }, forwardRef) => {
751
750
  const ref = React.useRef(null);
751
+ const { setOpen, rootOpen, triggerRef } = useDropdownContext();
752
752
  const handleVirtualClick = (e) => {
753
753
  var _a;
754
754
  if ((e == null ? void 0 : e.nativeEvent) === void 0) {
@@ -769,15 +769,40 @@ const Trigger = React__default["default"].forwardRef(({ asChild = false, onClick
769
769
  (_a = ref.current) == null ? void 0 : _a.dispatchEvent(pointerDownEvent);
770
770
  }
771
771
  };
772
+ const { pressProps } = designSystemUsePress.usePress({
773
+ onPress: () => {
774
+ if (rootOpen === void 0) {
775
+ setOpen((open) => !designSystemUtils.booleanify(open));
776
+ }
777
+ }
778
+ });
779
+ const elementProps = utils.mergeProps(restProps, pressProps);
772
780
  return /* @__PURE__ */ jsxRuntime.jsx(
773
781
  StyledTrigger,
774
782
  {
775
- ...restProps,
783
+ ...elementProps,
776
784
  onClick: (e) => {
785
+ var _a, _b;
777
786
  handleVirtualClick(e);
778
- onClick == null ? void 0 : onClick(e);
787
+ if (e instanceof MouseEvent) {
788
+ e.preventDefault();
789
+ (_a = elementProps.onClick) == null ? void 0 : _a.call(elementProps, e);
790
+ } else {
791
+ (_b = restProps.onClick) == null ? void 0 : _b.call(restProps, e);
792
+ }
779
793
  },
780
- ref: designSystemUtils.mergeRefs([ref, forwardRef]),
794
+ onKeyDown: (e) => {
795
+ var _a, _b;
796
+ if ((e == null ? void 0 : e.nativeEvent) instanceof KeyboardEvent) {
797
+ if (!/^(Arrow|Tab|Escape)/.test(e.key)) {
798
+ e.preventDefault();
799
+ }
800
+ (_a = elementProps.onKeyDown) == null ? void 0 : _a.call(elementProps, e);
801
+ } else {
802
+ (_b = restProps.onKeyDown) == null ? void 0 : _b.call(restProps, e);
803
+ }
804
+ },
805
+ ref: designSystemUtils.mergeRefs([ref, triggerRef, forwardRef]),
781
806
  unstyled: !asChild,
782
807
  asChild
783
808
  }
@@ -798,29 +823,18 @@ const StyledSubTrigger = designSystemStitches.styled(RadixDropdownMenu__namespac
798
823
  });
799
824
 
800
825
  const SubTrigger = React__default["default"].forwardRef(({ children, disabled = false, ...restProps }, forwardRef) => {
801
- const { onSelect, ...ariaDisabledProps } = useAriaDisabled({
802
- onKeyDown: restProps.onKeyDown,
803
- "aria-disabled": restProps["aria-disabled"]
804
- });
805
- return /* @__PURE__ */ jsxRuntime.jsxs(
806
- StyledSubTrigger,
807
- {
808
- ...restProps,
809
- ...ariaDisabledProps,
810
- disabled,
811
- ref: forwardRef,
812
- children: [
813
- children,
814
- /* @__PURE__ */ jsxRuntime.jsx(RightSlot, { children: /* @__PURE__ */ jsxRuntime.jsx(
815
- StyledIconContainer,
816
- {
817
- "data-testid": process.env.NODE_ENV === "test" ? "submenu-arrow-icon" : void 0,
818
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconChevronRight, { size: "small", weight: "thin" })
819
- }
820
- ) })
821
- ]
822
- }
823
- );
826
+ let { onSelect, ...elementProps } = restProps;
827
+ elementProps = useAriaDisabled(elementProps);
828
+ return /* @__PURE__ */ jsxRuntime.jsxs(StyledSubTrigger, { ...elementProps, disabled, ref: forwardRef, children: [
829
+ children,
830
+ /* @__PURE__ */ jsxRuntime.jsx(RightSlot, { children: /* @__PURE__ */ jsxRuntime.jsx(
831
+ StyledIconContainer,
832
+ {
833
+ "data-testid": process.env.NODE_ENV === "test" ? "submenu-arrow-icon" : void 0,
834
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystemIcons.IconChevronRight, { size: "small", weight: "thin" })
835
+ }
836
+ ) })
837
+ ] });
824
838
  });
825
839
 
826
840
  const StyledSubContent = designSystemStitches.styled(
@@ -939,39 +953,52 @@ const Root = ({
939
953
  defaultOpen = false,
940
954
  direction,
941
955
  interactOutside = false,
942
- open,
943
956
  onOpen,
944
957
  onClose,
945
958
  ...restProps
946
959
  }) => {
947
960
  const { ignoreNextTooltip } = designSystemBaseTooltip.useBaseTooltipContext();
961
+ const { rootOpen, open, setOpen } = useDropdownContext();
948
962
  const prevOpen = designSystemUsePrevious.usePrevious(open);
949
963
  React.useEffect(() => {
950
- if (prevOpen === true && open === false) {
951
- ignoreNextTooltip();
964
+ if (prevOpen !== open) {
965
+ if (open === true) {
966
+ onOpen == null ? void 0 : onOpen();
967
+ } else {
968
+ if (prevOpen === true) {
969
+ ignoreNextTooltip();
970
+ }
971
+ onClose == null ? void 0 : onClose();
972
+ }
952
973
  }
953
- }, [ignoreNextTooltip, open, prevOpen]);
974
+ }, [open, prevOpen, onOpen, onClose, ignoreNextTooltip]);
954
975
  return /* @__PURE__ */ jsxRuntime.jsx(
955
976
  RadixDropdownMenu__namespace.Root,
956
977
  {
957
978
  ...restProps,
958
979
  dir: direction,
959
980
  modal: interactOutside,
960
- open,
981
+ open: (
982
+ // use the root open state if it is defined
983
+ rootOpen != null ? rootOpen : defaultOpen && (prevOpen === void 0 || prevOpen === open) ? (
984
+ // only use defaultOpen in the first render then use the context open state
985
+ // if the open state is the same as the previous one, it is most likely a re-render and we should still use the defaultOpen
986
+ void 0
987
+ ) : (
988
+ // otherwise, use the user open state
989
+ open
990
+ )
991
+ ),
961
992
  defaultOpen,
962
- onOpenChange: (newOpen) => {
963
- if (!newOpen && open === void 0) {
964
- ignoreNextTooltip();
965
- }
966
- newOpen ? onOpen == null ? void 0 : onOpen() : onClose == null ? void 0 : onClose();
967
- }
993
+ onOpenChange: setOpen
968
994
  }
969
995
  );
970
996
  };
971
997
  const DropdownMenu = ({
972
998
  direction = "ltr",
999
+ open,
973
1000
  ...restProps
974
- }) => /* @__PURE__ */ jsxRuntime.jsx(DropdownProvider, { direction, children: /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseTooltip.BaseTooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(Root, { direction, ...restProps }) }) });
1001
+ }) => /* @__PURE__ */ jsxRuntime.jsx(DropdownProvider, { direction, open, children: /* @__PURE__ */ jsxRuntime.jsx(designSystemBaseTooltip.BaseTooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(Root, { direction, ...restProps }) }) });
975
1002
  DropdownMenu.CheckboxItem = CheckboxItem;
976
1003
  DropdownMenu.Content = Content;
977
1004
  DropdownMenu.Hotkey = Hotkey;