@linzjs/step-ag-grid 1.4.5 → 1.4.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.
Files changed (72) hide show
  1. package/dist/index.js +195 -163
  2. package/dist/index.js.map +1 -1
  3. package/dist/src/react-menu3/components/FocusableItem.d.ts +9 -1
  4. package/dist/src/react-menu3/components/Menu.d.ts +16 -2
  5. package/dist/src/react-menu3/components/MenuButton.d.ts +8 -1
  6. package/dist/src/react-menu3/components/MenuDivider.d.ts +3 -2
  7. package/dist/src/react-menu3/components/MenuGroup.d.ts +12 -2
  8. package/dist/src/react-menu3/components/MenuHeader.d.ts +4 -2
  9. package/dist/src/react-menu3/components/MenuItem.d.ts +59 -1
  10. package/dist/src/react-menu3/components/MenuList.d.ts +57 -30
  11. package/dist/src/react-menu3/components/MenuRadioGroup.d.ts +44 -2
  12. package/dist/src/react-menu3/components/SubMenu.d.ts +110 -1
  13. package/dist/src/react-menu3/hooks/useBEM.d.ts +4 -3
  14. package/dist/src/react-menu3/hooks/useCombinedRef.d.ts +2 -2
  15. package/dist/src/react-menu3/hooks/useItemEffect.d.ts +1 -1
  16. package/dist/src/react-menu3/hooks/useItemState.d.ts +4 -3
  17. package/dist/src/react-menu3/hooks/useItems.d.ts +6 -4
  18. package/dist/src/react-menu3/hooks/useMenuChange.d.ts +2 -1
  19. package/dist/src/react-menu3/hooks/useMenuState.d.ts +13 -10
  20. package/dist/src/react-menu3/hooks/useMenuStateAndFocus.d.ts +2 -10
  21. package/dist/src/react-menu3/index.d.ts +391 -0
  22. package/dist/src/react-menu3/positionUtils/getPositionHelpers.d.ts +10 -9
  23. package/dist/src/react-menu3/positionUtils/placeArrowHorizontal.d.ts +7 -6
  24. package/dist/src/react-menu3/positionUtils/placeArrowVertical.d.ts +7 -6
  25. package/dist/src/react-menu3/positionUtils/placeLeftorRight.d.ts +17 -19
  26. package/dist/src/react-menu3/positionUtils/placeToporBottom.d.ts +18 -20
  27. package/dist/src/react-menu3/positionUtils/positionContextMenu.d.ts +11 -6
  28. package/dist/src/react-menu3/positionUtils/positionMenu.d.ts +23 -18
  29. package/dist/src/react-menu3/utils/constants.d.ts +51 -9
  30. package/dist/src/react-menu3/utils/propTypes.d.ts +1 -0
  31. package/dist/src/react-menu3/utils/utils.d.ts +19 -10
  32. package/dist/src/react-menu3/utils/withHovering.d.ts +7 -1
  33. package/dist/src/stories/components/ReactMenu.stories.d.ts +8 -0
  34. package/dist/step-ag-grid.esm.js +197 -165
  35. package/dist/step-ag-grid.esm.js.map +1 -1
  36. package/package.json +11 -11
  37. package/src/components/gridForm/GridFormDropDown.tsx +1 -1
  38. package/src/components/gridForm/GridFormMultiSelect.tsx +10 -4
  39. package/src/react-menu3/components/ControlledMenu.tsx +2 -1
  40. package/src/react-menu3/components/FocusableItem.tsx +58 -53
  41. package/src/react-menu3/components/Menu.tsx +40 -28
  42. package/src/react-menu3/components/MenuButton.tsx +30 -29
  43. package/src/react-menu3/components/MenuDivider.tsx +14 -18
  44. package/src/react-menu3/components/MenuGroup.tsx +25 -16
  45. package/src/react-menu3/components/MenuHeader.tsx +14 -18
  46. package/src/react-menu3/components/MenuItem.tsx +159 -106
  47. package/src/react-menu3/components/MenuList.tsx +104 -36
  48. package/src/react-menu3/components/MenuRadioGroup.tsx +54 -15
  49. package/src/react-menu3/components/SubMenu.tsx +307 -201
  50. package/src/react-menu3/hooks/useBEM.ts +4 -3
  51. package/src/react-menu3/hooks/useCombinedRef.ts +6 -12
  52. package/src/react-menu3/hooks/useItemEffect.ts +6 -5
  53. package/src/react-menu3/hooks/useItemState.ts +16 -12
  54. package/src/react-menu3/hooks/useItems.ts +11 -10
  55. package/src/react-menu3/hooks/useMenuChange.ts +3 -3
  56. package/src/react-menu3/hooks/useMenuState.ts +25 -7
  57. package/src/react-menu3/hooks/useMenuStateAndFocus.ts +6 -4
  58. package/src/react-menu3/index.d.ts +1 -0
  59. package/src/react-menu3/index.ts +431 -0
  60. package/src/react-menu3/positionUtils/getPositionHelpers.ts +18 -11
  61. package/src/react-menu3/positionUtils/placeArrowHorizontal.ts +12 -5
  62. package/src/react-menu3/positionUtils/placeArrowVertical.ts +12 -5
  63. package/src/react-menu3/positionUtils/placeLeftorRight.ts +33 -17
  64. package/src/react-menu3/positionUtils/placeToporBottom.ts +34 -18
  65. package/src/react-menu3/positionUtils/positionContextMenu.ts +15 -3
  66. package/src/react-menu3/positionUtils/positionMenu.ts +21 -14
  67. package/src/react-menu3/style-utils/index.ts +10 -7
  68. package/src/react-menu3/utils/constants.ts +63 -10
  69. package/src/react-menu3/utils/propTypes.ts +3 -1
  70. package/src/react-menu3/utils/utils.ts +40 -23
  71. package/src/react-menu3/utils/withHovering.tsx +11 -6
  72. package/src/stories/components/ReactMenu.stories.tsx +37 -0
@@ -1,10 +1,16 @@
1
- // @ts-nocheck
2
1
  import { parsePadding } from "../utils";
2
+ import { MutableRefObject } from "react";
3
3
 
4
- export const getPositionHelpers = (containerRef, menuRef, menuScroll, boundingBoxPadding) => {
4
+ export const getPositionHelpers = (
5
+ containerRef: MutableRefObject<HTMLElement>,
6
+ menuRef: MutableRefObject<HTMLElement>,
7
+ menuScroll: Window | Element,
8
+ boundingBoxPadding: string | undefined,
9
+ ) => {
5
10
  const menuRect = menuRef.current.getBoundingClientRect();
6
11
  const containerRect = containerRef.current.getBoundingClientRect();
7
- const thisWindow = containerRef.current.ownerDocument.defaultView;
12
+ const thisWindow = containerRef.current.ownerDocument.defaultView ?? window;
13
+
8
14
  const boundingRect =
9
15
  menuScroll === window || menuScroll === thisWindow
10
16
  ? {
@@ -13,17 +19,18 @@ export const getPositionHelpers = (containerRef, menuRef, menuScroll, boundingBo
13
19
  right: thisWindow.document.documentElement.clientWidth,
14
20
  bottom: thisWindow.innerHeight,
15
21
  }
16
- : menuScroll.getBoundingClientRect();
22
+ : (menuScroll as Element).getBoundingClientRect();
17
23
  const padding = parsePadding(boundingBoxPadding);
18
24
 
19
25
  // For left and top, overflows are negative value.
20
26
  // For right and bottom, overflows are positive value.
21
- const getLeftOverflow = (x) => x + containerRect.left - boundingRect.left - padding.left;
22
- const getRightOverflow = (x) => x + containerRect.left + menuRect.width - boundingRect.right + padding.right;
23
- const getTopOverflow = (y) => y + containerRect.top - boundingRect.top - padding.top;
24
- const getBottomOverflow = (y) => y + containerRect.top + menuRect.height - boundingRect.bottom + padding.bottom;
27
+ const getLeftOverflow = (x: number) => x + containerRect.left - boundingRect.left - padding.left;
28
+ const getRightOverflow = (x: number) => x + containerRect.left + menuRect.width - boundingRect.right + padding.right;
29
+ const getTopOverflow = (y: number) => y + containerRect.top - boundingRect.top - padding.top;
30
+ const getBottomOverflow = (y: number) =>
31
+ y + containerRect.top + menuRect.height - boundingRect.bottom + padding.bottom;
25
32
 
26
- const confineHorizontally = (x) => {
33
+ const confineHorizontally = (x: number) => {
27
34
  // If menu overflows to the left side, adjust x to have the menu contained within the viewport
28
35
  // and there is no need to check the right side;
29
36
  // if it doesn't overflow to the left, then check the right side
@@ -35,7 +42,7 @@ export const getPositionHelpers = (containerRef, menuRef, menuScroll, boundingBo
35
42
  if (rightOverflow > 0) {
36
43
  x -= rightOverflow;
37
44
  // Check again to make sure menu doesn't overflow to the left
38
- // because it may go off screen and cannot be scroll into view.
45
+ // because it may go off-screen and cannot be scrolled into view.
39
46
  leftOverflow = getLeftOverflow(x);
40
47
  if (leftOverflow < 0) x -= leftOverflow;
41
48
  }
@@ -44,7 +51,7 @@ export const getPositionHelpers = (containerRef, menuRef, menuScroll, boundingBo
44
51
  return x;
45
52
  };
46
53
 
47
- const confineVertically = (y) => {
54
+ const confineVertically = (y: number) => {
48
55
  // Similar logic to confineHorizontally above
49
56
  let topOverflow = getTopOverflow(y);
50
57
  if (topOverflow < 0) {
@@ -1,8 +1,15 @@
1
- // @ts-nocheck
2
- export const placeArrowHorizontal = ({ arrowRef, menuX, anchorRect, containerRect, menuRect }) => {
3
- let x = anchorRect.left - containerRect.left - menuX + anchorRect.width / 2;
4
- const offset = arrowRef.current.offsetWidth * 1.25;
1
+ import { MutableRefObject } from "react";
2
+
3
+ export const placeArrowHorizontal = (p: {
4
+ arrowRef: MutableRefObject<HTMLElement | null>;
5
+ menuX: number;
6
+ anchorRect: DOMRect;
7
+ containerRect: DOMRect;
8
+ menuRect: DOMRect;
9
+ }) => {
10
+ let x = p.anchorRect.left - p.containerRect.left - p.menuX + p.anchorRect.width / 2;
11
+ const offset = p.arrowRef.current ? p.arrowRef.current.offsetWidth * 1.25 : 0;
5
12
  x = Math.max(offset, x);
6
- x = Math.min(x, menuRect.width - offset);
13
+ x = Math.min(x, p.menuRect.width - offset);
7
14
  return x;
8
15
  };
@@ -1,8 +1,15 @@
1
- // @ts-nocheck
2
- export const placeArrowVertical = ({ arrowRef, menuY, anchorRect, containerRect, menuRect }) => {
3
- let y = anchorRect.top - containerRect.top - menuY + anchorRect.height / 2;
4
- const offset = arrowRef.current.offsetHeight * 1.25;
1
+ import { MutableRefObject } from "react";
2
+
3
+ export const placeArrowVertical = (p: {
4
+ arrowRef: MutableRefObject<HTMLElement | null>;
5
+ menuY: number;
6
+ anchorRect: DOMRect;
7
+ containerRect: DOMRect;
8
+ menuRect: DOMRect;
9
+ }) => {
10
+ let y = p.anchorRect.top - p.containerRect.top - p.menuY + p.anchorRect.height / 2;
11
+ const offset = p.arrowRef.current ? p.arrowRef.current.offsetHeight * 1.25 : 0;
5
12
  y = Math.max(offset, y);
6
- y = Math.min(y, menuRect.height - offset);
13
+ y = Math.min(y, p.menuRect.height - offset);
7
14
  return y;
8
15
  };
@@ -1,22 +1,38 @@
1
- // @ts-nocheck
2
1
  import { placeArrowVertical } from "./placeArrowVertical";
2
+ import { getPositionHelpers } from "./getPositionHelpers";
3
+ import { MutableRefObject } from "react";
4
+ import { MenuDirection } from "../index";
3
5
 
4
- export const placeLeftorRight = ({
5
- anchorRect,
6
- containerRect,
7
- menuRect,
8
- placeLeftorRightY,
9
- placeLeftX,
10
- placeRightX,
11
- getLeftOverflow,
12
- getRightOverflow,
13
- confineHorizontally,
14
- confineVertically,
15
- arrowRef,
16
- arrow,
17
- direction,
18
- position,
19
- }) => {
6
+ export interface placeLeftorRightParams {
7
+ anchorRect: DOMRect;
8
+ placeLeftorRightY: number;
9
+ placeLeftX: number;
10
+ placeRightX: number;
11
+ arrowRef: MutableRefObject<HTMLElement | null>;
12
+ arrow?: boolean;
13
+ direction: MenuDirection;
14
+ position: "auto" | "anchor" | "initial";
15
+ }
16
+
17
+ export const placeLeftorRight = (
18
+ props: ReturnType<typeof getPositionHelpers> & placeLeftorRightParams,
19
+ ): { arrowY: number | undefined; x: number; y: number; computedDirection: MenuDirection } => {
20
+ const {
21
+ anchorRect,
22
+ containerRect,
23
+ menuRect,
24
+ placeLeftorRightY,
25
+ placeLeftX,
26
+ placeRightX,
27
+ getLeftOverflow,
28
+ getRightOverflow,
29
+ confineHorizontally,
30
+ confineVertically,
31
+ arrowRef,
32
+ arrow,
33
+ direction,
34
+ position,
35
+ } = props;
20
36
  let computedDirection = direction;
21
37
  let y = placeLeftorRightY;
22
38
  if (position !== "initial") {
@@ -1,24 +1,40 @@
1
- // @ts-nocheck
2
1
  import { placeArrowHorizontal } from "./placeArrowHorizontal";
2
+ import { getPositionHelpers } from "./getPositionHelpers";
3
+ import { MutableRefObject } from "react";
4
+ import { MenuDirection } from "../index";
3
5
 
4
- export const placeToporBottom = ({
5
- anchorRect,
6
- containerRect,
7
- menuRect,
8
- placeToporBottomX,
9
- placeTopY,
10
- placeBottomY,
11
- getTopOverflow,
12
- getBottomOverflow,
13
- confineHorizontally,
14
- confineVertically,
15
- arrowRef,
16
- arrow,
17
- direction,
18
- position,
19
- }) => {
6
+ export interface placeToporBottomParams {
7
+ anchorRect: DOMRect;
8
+ placeToporBottomX: number;
9
+ placeTopY: number;
10
+ placeBottomY: number;
11
+ arrowRef: MutableRefObject<HTMLElement | null>;
12
+ arrow?: boolean;
13
+ direction: "left" | "right" | "top" | "bottom";
14
+ position: "auto" | "anchor" | "initial";
15
+ }
16
+
17
+ export const placeToporBottom = (
18
+ props: ReturnType<typeof getPositionHelpers> & placeToporBottomParams,
19
+ ): { arrowX?: number | undefined; x: number; y: number; computedDirection: MenuDirection } => {
20
+ const {
21
+ anchorRect,
22
+ containerRect,
23
+ menuRect,
24
+ placeToporBottomX,
25
+ placeTopY,
26
+ placeBottomY,
27
+ getTopOverflow,
28
+ getBottomOverflow,
29
+ confineHorizontally,
30
+ confineVertically,
31
+ arrowRef,
32
+ arrow,
33
+ direction,
34
+ position,
35
+ } = props;
20
36
  // make sure invalid direction is treated as 'bottom'
21
- let computedDirection = direction === "top" ? "top" : "bottom";
37
+ let computedDirection: MenuDirection = direction === "top" ? "top" : "bottom";
22
38
  let x = placeToporBottomX;
23
39
  if (position !== "initial") {
24
40
  x = confineHorizontally(x);
@@ -1,5 +1,17 @@
1
- // @ts-nocheck
2
- export const positionContextMenu = ({ positionHelpers, anchorPoint }) => {
1
+ import { getPositionHelpers } from "./getPositionHelpers";
2
+ import { MenuDirection } from "../index";
3
+
4
+ export const positionContextMenu = ({
5
+ positionHelpers,
6
+ anchorPoint,
7
+ }: {
8
+ positionHelpers: ReturnType<typeof getPositionHelpers>;
9
+ anchorPoint: { x: number; y: number };
10
+ }): {
11
+ x: number;
12
+ y: number;
13
+ computedDirection: MenuDirection;
14
+ } => {
3
15
  const {
4
16
  menuRect,
5
17
  containerRect,
@@ -33,7 +45,7 @@ export const positionContextMenu = ({ positionHelpers, anchorPoint }) => {
33
45
  }
34
46
 
35
47
  // Similar logic to the left and right side above.
36
- let computedDirection = "bottom";
48
+ let computedDirection: MenuDirection = "bottom";
37
49
  const bottomOverflow = getBottomOverflow(y);
38
50
  if (bottomOverflow > 0) {
39
51
  const adjustedY = y - menuRect.height;
@@ -1,23 +1,28 @@
1
- // @ts-nocheck
2
1
  import { placeLeftorRight } from "./placeLeftorRight";
3
2
  import { placeToporBottom } from "./placeToporBottom";
3
+ import { MutableRefObject } from "react";
4
+ import { getPositionHelpers } from "./getPositionHelpers";
5
+ import { MenuDirection } from "../index";
4
6
 
5
- export const positionMenu = ({
6
- arrow,
7
- align,
8
- direction,
9
- offsetX,
10
- offsetY,
11
- position,
12
- anchorRef,
13
- arrowRef,
14
- positionHelpers,
15
- }) => {
7
+ interface positionMenuProps {
8
+ offsetX: number;
9
+ offsetY: number;
10
+ arrowRef: MutableRefObject<HTMLDivElement | null>;
11
+ anchorRef: MutableRefObject<HTMLElement | null>;
12
+ arrow?: boolean;
13
+ direction: MenuDirection;
14
+ position: "auto" | "anchor" | "initial";
15
+ align: "start" | "center" | "end";
16
+ positionHelpers: ReturnType<typeof getPositionHelpers>;
17
+ }
18
+
19
+ export const positionMenu = (props: positionMenuProps) => {
20
+ const { arrow, align, direction, offsetX, offsetY, position, anchorRef, arrowRef, positionHelpers } = props;
16
21
  const { menuRect, containerRect } = positionHelpers;
17
22
 
18
23
  let horizontalOffset = offsetX;
19
24
  let verticalOffset = offsetY;
20
- if (arrow) {
25
+ if (arrow && arrowRef.current) {
21
26
  if (direction === "left" || direction === "right") {
22
27
  horizontalOffset += arrowRef.current.offsetWidth;
23
28
  } else {
@@ -25,7 +30,9 @@ export const positionMenu = ({
25
30
  }
26
31
  }
27
32
 
28
- const anchorRect = anchorRef.current.getBoundingClientRect();
33
+ const anchorRect = anchorRef.current
34
+ ? anchorRef.current.getBoundingClientRect()
35
+ : ({ left: 0, right: 0, top: 200, bottom: 200, width: 200, height: 200 } as DOMRect);
29
36
  const placeLeftX = anchorRect.left - containerRect.left - menuRect.width - horizontalOffset;
30
37
  const placeRightX = anchorRect.right - containerRect.left + horizontalOffset;
31
38
  const placeTopY = anchorRect.top - containerRect.top - menuRect.height - verticalOffset;
@@ -11,14 +11,17 @@ import {
11
11
  subMenuClass,
12
12
  } from "../utils";
13
13
 
14
- const bem = (block) => (element) => (modifier) => {
15
- let selector = `.${block}`;
16
- if (element) selector += `__${element}`;
17
- if (modifier) selector += `--${modifier}`;
18
- return selector;
19
- };
14
+ const bem =
15
+ (block: string) =>
16
+ (element?: string) =>
17
+ (modifier?: string): string => {
18
+ let selector = `.${block}`;
19
+ if (element) selector += `__${element}`;
20
+ if (modifier) selector += `--${modifier}`;
21
+ return selector;
22
+ };
20
23
 
21
- const createSelector = (blockElement, modifiers = []) => {
24
+ const createSelector = (blockElement: (modifier?: string) => string, modifiers: string[] = []) => {
22
25
  const selectorObj = {};
23
26
  Object.defineProperty(selectorObj, "name", {
24
27
  value: blockElement(),
@@ -1,5 +1,7 @@
1
- // @ts-nocheck
2
- import { createContext } from "react";
1
+ import { createContext, MutableRefObject } from "react";
2
+ import { EventHandler, FocusPosition, MenuDirection, MenuOverflow, MenuState } from "../index";
3
+ import { RadioChangeEvent } from "../components/MenuRadioGroup";
4
+ import { ControlledMenuProps } from "../components/MenuList";
3
5
 
4
6
  export const menuContainerClass = "szh-menu-container";
5
7
  export const menuClass = "szh-menu";
@@ -12,13 +14,64 @@ export const menuGroupClass = "group";
12
14
  export const subMenuClass = "submenu";
13
15
  export const radioGroupClass = "radio-group";
14
16
 
15
- export const HoverItemContext = createContext();
16
- export const MenuListItemContext = createContext({});
17
- export const MenuListContext = createContext({});
18
- export const EventHandlersContext = createContext({});
19
- export const RadioGroupContext = createContext({});
20
- export const SettingsContext = createContext({});
21
- export const ItemSettingsContext = createContext({});
17
+ export const HoverItemContext = createContext(undefined);
18
+
19
+ interface MenuListItemContextType {
20
+ isParentOpen?: boolean;
21
+ isSubmenuOpen?: boolean;
22
+ dispatch: (actionType: number, item: any, nextIndex: FocusPosition) => void;
23
+ updateItems: (item: any, isMounted?: boolean) => void;
24
+ setOpenSubmenuCount: (fn: (count: number) => number) => void;
25
+ }
26
+
27
+ export const MenuListItemContext = createContext<MenuListItemContextType>({
28
+ dispatch: () => {},
29
+ updateItems: () => {},
30
+ setOpenSubmenuCount: () => 0,
31
+ });
32
+
33
+ export const MenuListContext = createContext<{
34
+ overflow?: MenuOverflow;
35
+ overflowAmt?: number;
36
+ parentMenuRef?: MutableRefObject<any>;
37
+ parentDir?: MenuDirection;
38
+ reposSubmenu?: boolean;
39
+ }>({});
40
+
41
+ export interface RMEvent {
42
+ value: any;
43
+ syntheticEvent: any;
44
+ checked?: boolean;
45
+ name?: string;
46
+ key?: string;
47
+ }
48
+
49
+ export const EventHandlersContext = createContext<{
50
+ handleClose?: () => void;
51
+ handleClick: (event: RMEvent, checked: boolean) => void;
52
+ }>({
53
+ handleClick: () => {},
54
+ });
55
+
56
+ export const RadioGroupContext = createContext<{
57
+ value?: any;
58
+ name?: string;
59
+ onRadioChange?: EventHandler<RadioChangeEvent>;
60
+ }>({});
61
+
62
+ interface SettingsContextType extends ControlledMenuProps, MenuListItemContextType {
63
+ rootMenuRef?: MutableRefObject<any>;
64
+ rootAnchorRef?: MutableRefObject<any>;
65
+ scrollNodesRef: MutableRefObject<{ anchors?: Element[]; menu: any }>;
66
+ }
67
+
68
+ // FIXME hacking a default context in here is probably bad
69
+ export const SettingsContext = createContext<SettingsContextType>({} as SettingsContextType);
70
+
71
+ export const ItemSettingsContext = createContext<{ submenuCloseDelay: number; submenuOpenDelay: number }>({
72
+ submenuOpenDelay: 0,
73
+ submenuCloseDelay: 0,
74
+ });
22
75
 
23
76
  export const Keys = Object.freeze({
24
77
  ENTER: "Enter",
@@ -55,7 +108,7 @@ export const FocusPositions = Object.freeze({
55
108
  LAST: "last",
56
109
  });
57
110
 
58
- export const MenuStateMap: Record<string, string | undefined> = Object.freeze({
111
+ export const MenuStateMap: Record<string, MenuState> = Object.freeze({
59
112
  entering: "opening",
60
113
  entered: "open",
61
114
  exiting: "closing",
@@ -4,6 +4,8 @@ export const stylePropTypes = (name?: string) => ({
4
4
  [name ? `${name}ClassName` : "className"]: oneOfType([string, func]),
5
5
  });
6
6
 
7
+ export const Direction = oneOf(["left", "right", "top", "bottom"]);
8
+
7
9
  // Menu, SubMenu and ControlledMenu
8
10
  export const menuPropTypes = {
9
11
  className: string,
@@ -16,7 +18,7 @@ export const menuPropTypes = {
16
18
  offsetX: number,
17
19
  offsetY: number,
18
20
  align: oneOf(["start", "center", "end"]),
19
- direction: oneOf(["left", "right", "top", "bottom"]),
21
+ direction: Direction,
20
22
  position: oneOf(["auto", "anchor", "initial"]),
21
23
  overflow: oneOf(["auto", "visible", "hidden"]),
22
24
  };
@@ -1,17 +1,36 @@
1
- // @ts-nocheck
2
1
  import { unstable_batchedUpdates } from "react-dom";
2
+ import { MenuState, MenuStateOptions } from "../index";
3
+ import { MenuButtonProps } from "../components/MenuButton";
4
+ import { findIndex } from "lodash-es";
3
5
 
4
- export const isMenuOpen = (state) => !!state && state[0] === "o";
5
- export const batchedUpdates = unstable_batchedUpdates || ((callback) => callback());
6
- export const values = Object.values || ((obj) => Object.keys(obj).map((key) => obj[key]));
6
+ export const isMenuOpen = (state?: MenuState) => !!state && state[0] === "o";
7
+ export const batchedUpdates = unstable_batchedUpdates || ((callback: () => any) => callback());
8
+ export const values = Object.values || ((obj: { [x: string]: any }) => Object.keys(obj).map((key) => obj[key]));
7
9
  export const floatEqual = (a: number, b: number, diff = 0.0001) => Math.abs(a - b) < diff;
8
- export const getTransition = (transition: boolean | Record<string, string>, name: string) =>
10
+
11
+ export type TransitionMap = {
12
+ open?: boolean;
13
+ close?: boolean;
14
+ item?: boolean;
15
+ };
16
+ export const getTransition = (transition: MenuStateOptions["transition"], name: keyof TransitionMap) =>
9
17
  transition === true || !!(transition && transition[name]);
10
- export const safeCall = (fn, arg) => (typeof fn === "function" ? fn(arg) : fn);
18
+
19
+ export function safeCall<T, R>(fn: (arg?: T) => R, arg?: T): R;
20
+ export function safeCall<T, R>(fn: T, arg: R): T;
21
+ export function safeCall<T, R>(fn: (arg?: T) => R, arg?: T): T | R {
22
+ return typeof fn === "function" ? fn(arg) : fn;
23
+ }
11
24
 
12
25
  const internalKey = "_szhsinMenu";
13
- export const getName = (component) => component[internalKey];
14
- export const defineName = (name, component) => Object.defineProperty(component, internalKey, { value: name });
26
+ export const getName = (component: Record<string, any | undefined>) => component[internalKey];
27
+ //export const defineName = <T extends any[]>(name: string, component: (...args: T) => JSX.Element) =>
28
+ // Object.defineProperty(component, internalKey, { value: name });
29
+
30
+ export const defineName = (
31
+ name: string,
32
+ component: React.ForwardRefExoticComponent<React.PropsWithoutRef<MenuButtonProps> & React.RefAttributes<unknown>>,
33
+ ) => Object.defineProperty(component, internalKey, { value: name });
15
34
 
16
35
  export const mergeProps = (target: Record<string, any>, source: Record<string, any>) => {
17
36
  source &&
@@ -19,7 +38,7 @@ export const mergeProps = (target: Record<string, any>, source: Record<string, a
19
38
  const targetProp = target[key];
20
39
  const sourceProp = source[key];
21
40
  if (typeof sourceProp === "function" && targetProp) {
22
- target[key] = (...arg) => {
41
+ target[key] = (...arg: any[]) => {
23
42
  sourceProp(...arg);
24
43
  targetProp(...arg);
25
44
  };
@@ -31,8 +50,8 @@ export const mergeProps = (target: Record<string, any>, source: Record<string, a
31
50
  return target;
32
51
  };
33
52
 
34
- export const parsePadding = (paddingStr) => {
35
- if (typeof paddingStr !== "string") return { top: 0, right: 0, bottom: 0, left: 0 };
53
+ export const parsePadding = (paddingStr: string | undefined) => {
54
+ if (paddingStr == null) return { top: 0, right: 0, bottom: 0, left: 0 };
36
55
 
37
56
  const padding = paddingStr.trim().split(/\s+/, 4).map(parseFloat);
38
57
  const top = !isNaN(padding[0]) ? padding[0] : 0;
@@ -46,26 +65,24 @@ export const parsePadding = (paddingStr) => {
46
65
  };
47
66
 
48
67
  // Adapted from https://github.com/popperjs/popper-core/tree/v2.9.1/src/dom-utils
49
- export const getScrollAncestor = (node) => {
50
- const thisWindow = node.ownerDocument.defaultView;
68
+ export const getScrollAncestor = (node: Node | null): Element | null => {
69
+ const thisWindow = (node?.ownerDocument ?? document).defaultView ?? window;
51
70
  while (node) {
52
71
  node = node.parentNode;
53
- if (!node || node === thisWindow.document.body) return;
54
- const { overflow, overflowX, overflowY } = thisWindow.getComputedStyle(node);
55
- if (/auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX)) return node;
72
+ if (!node || node === thisWindow?.document?.body) return null;
73
+ if (node instanceof Element) {
74
+ const { overflow, overflowX, overflowY } = thisWindow.getComputedStyle(node);
75
+ if (/auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX)) return node;
76
+ }
56
77
  }
78
+ return null;
57
79
  };
58
80
 
59
- export function commonProps(isDisabled, isHovering) {
81
+ export function commonProps(isDisabled?: boolean, isHovering?: boolean) {
60
82
  return {
61
83
  "aria-disabled": isDisabled || undefined,
62
84
  tabIndex: isHovering ? 0 : -1,
63
85
  };
64
86
  }
65
87
 
66
- export function indexOfNode(nodeList, node) {
67
- for (let i = 0; i < nodeList.length; i++) {
68
- if (nodeList[i] === node) return i;
69
- }
70
- return -1;
71
- }
88
+ export const indexOfNode = (nodeList: NodeListOf<Node>, node: Node) => findIndex(nodeList, node);
@@ -1,17 +1,22 @@
1
- // @ts-nocheck
2
- import { memo, forwardRef, useContext, useRef } from "react";
1
+ import { memo, forwardRef, useContext, useRef, MutableRefObject } from "react";
3
2
  import { HoverItemContext } from "./constants";
4
3
 
5
- export const withHovering = (name: string, WrappedComponent: any): any => {
4
+ export interface withHoveringResultProps {
5
+ isHovering?: boolean;
6
+ externalRef?: MutableRefObject<any>;
7
+ menuItemRef?: MutableRefObject<any>;
8
+ }
9
+
10
+ export const withHovering = (name: string, WrappedComponent: (...args: any) => JSX.Element): any => {
6
11
  const Component = memo(WrappedComponent);
7
12
  const WithHovering = forwardRef<any>((props: any, ref) => {
8
- const itemRef = useRef(null);
13
+ const menuItemRef = useRef<any>(null);
9
14
  return (
10
15
  <Component
11
16
  {...props}
12
- itemRef={itemRef}
17
+ menuItemRef={menuItemRef}
13
18
  externalRef={ref}
14
- isHovering={useContext(HoverItemContext) === itemRef.current}
19
+ isHovering={useContext(HoverItemContext) === menuItemRef.current}
15
20
  />
16
21
  );
17
22
  });
@@ -0,0 +1,37 @@
1
+ import "@linzjs/lui/dist/scss/base.scss";
2
+ import "@linzjs/lui/dist/fonts";
3
+ import "../../lui-overrides.scss";
4
+
5
+ import { ComponentMeta, ComponentStory } from "@storybook/react/dist/ts3.9/client/preview/types-6-3";
6
+ import { Grid } from "@components/Grid";
7
+ import { Menu, MenuItem, MenuButton, MenuDivider, SubMenu } from "@react-menu3";
8
+
9
+ export default {
10
+ title: "Components / React-menu",
11
+ component: Grid,
12
+ args: {
13
+ externalSelectedItems: [],
14
+ setExternalSelectedItems: () => {},
15
+ },
16
+ } as ComponentMeta<typeof Grid>;
17
+
18
+ const ReactMenuTemplate: ComponentStory<typeof Grid> = () => {
19
+ return (
20
+ <>
21
+ <Menu menuButton={<MenuButton>Open menu</MenuButton>}>
22
+ <MenuItem>New File</MenuItem>
23
+ <MenuItem>Save</MenuItem>
24
+ <SubMenu label="Edit">
25
+ <MenuItem>Cut</MenuItem>
26
+ <MenuItem>Copy</MenuItem>
27
+ <MenuItem>Paste</MenuItem>
28
+ </SubMenu>
29
+ <MenuItem>Print...</MenuItem>
30
+ <MenuDivider />
31
+ <MenuItem>Exit</MenuItem>
32
+ </Menu>
33
+ </>
34
+ );
35
+ };
36
+
37
+ export const ReactMenuControlled = ReactMenuTemplate.bind({});