@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.
- package/dist/index.js +195 -163
- package/dist/index.js.map +1 -1
- package/dist/src/react-menu3/components/FocusableItem.d.ts +9 -1
- package/dist/src/react-menu3/components/Menu.d.ts +16 -2
- package/dist/src/react-menu3/components/MenuButton.d.ts +8 -1
- package/dist/src/react-menu3/components/MenuDivider.d.ts +3 -2
- package/dist/src/react-menu3/components/MenuGroup.d.ts +12 -2
- package/dist/src/react-menu3/components/MenuHeader.d.ts +4 -2
- package/dist/src/react-menu3/components/MenuItem.d.ts +59 -1
- package/dist/src/react-menu3/components/MenuList.d.ts +57 -30
- package/dist/src/react-menu3/components/MenuRadioGroup.d.ts +44 -2
- package/dist/src/react-menu3/components/SubMenu.d.ts +110 -1
- package/dist/src/react-menu3/hooks/useBEM.d.ts +4 -3
- package/dist/src/react-menu3/hooks/useCombinedRef.d.ts +2 -2
- package/dist/src/react-menu3/hooks/useItemEffect.d.ts +1 -1
- package/dist/src/react-menu3/hooks/useItemState.d.ts +4 -3
- package/dist/src/react-menu3/hooks/useItems.d.ts +6 -4
- package/dist/src/react-menu3/hooks/useMenuChange.d.ts +2 -1
- package/dist/src/react-menu3/hooks/useMenuState.d.ts +13 -10
- package/dist/src/react-menu3/hooks/useMenuStateAndFocus.d.ts +2 -10
- package/dist/src/react-menu3/index.d.ts +391 -0
- package/dist/src/react-menu3/positionUtils/getPositionHelpers.d.ts +10 -9
- package/dist/src/react-menu3/positionUtils/placeArrowHorizontal.d.ts +7 -6
- package/dist/src/react-menu3/positionUtils/placeArrowVertical.d.ts +7 -6
- package/dist/src/react-menu3/positionUtils/placeLeftorRight.d.ts +17 -19
- package/dist/src/react-menu3/positionUtils/placeToporBottom.d.ts +18 -20
- package/dist/src/react-menu3/positionUtils/positionContextMenu.d.ts +11 -6
- package/dist/src/react-menu3/positionUtils/positionMenu.d.ts +23 -18
- package/dist/src/react-menu3/utils/constants.d.ts +51 -9
- package/dist/src/react-menu3/utils/propTypes.d.ts +1 -0
- package/dist/src/react-menu3/utils/utils.d.ts +19 -10
- package/dist/src/react-menu3/utils/withHovering.d.ts +7 -1
- package/dist/src/stories/components/ReactMenu.stories.d.ts +8 -0
- package/dist/step-ag-grid.esm.js +197 -165
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +11 -11
- package/src/components/gridForm/GridFormDropDown.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +10 -4
- package/src/react-menu3/components/ControlledMenu.tsx +2 -1
- package/src/react-menu3/components/FocusableItem.tsx +58 -53
- package/src/react-menu3/components/Menu.tsx +40 -28
- package/src/react-menu3/components/MenuButton.tsx +30 -29
- package/src/react-menu3/components/MenuDivider.tsx +14 -18
- package/src/react-menu3/components/MenuGroup.tsx +25 -16
- package/src/react-menu3/components/MenuHeader.tsx +14 -18
- package/src/react-menu3/components/MenuItem.tsx +159 -106
- package/src/react-menu3/components/MenuList.tsx +104 -36
- package/src/react-menu3/components/MenuRadioGroup.tsx +54 -15
- package/src/react-menu3/components/SubMenu.tsx +307 -201
- package/src/react-menu3/hooks/useBEM.ts +4 -3
- package/src/react-menu3/hooks/useCombinedRef.ts +6 -12
- package/src/react-menu3/hooks/useItemEffect.ts +6 -5
- package/src/react-menu3/hooks/useItemState.ts +16 -12
- package/src/react-menu3/hooks/useItems.ts +11 -10
- package/src/react-menu3/hooks/useMenuChange.ts +3 -3
- package/src/react-menu3/hooks/useMenuState.ts +25 -7
- package/src/react-menu3/hooks/useMenuStateAndFocus.ts +6 -4
- package/src/react-menu3/index.d.ts +1 -0
- package/src/react-menu3/index.ts +431 -0
- package/src/react-menu3/positionUtils/getPositionHelpers.ts +18 -11
- package/src/react-menu3/positionUtils/placeArrowHorizontal.ts +12 -5
- package/src/react-menu3/positionUtils/placeArrowVertical.ts +12 -5
- package/src/react-menu3/positionUtils/placeLeftorRight.ts +33 -17
- package/src/react-menu3/positionUtils/placeToporBottom.ts +34 -18
- package/src/react-menu3/positionUtils/positionContextMenu.ts +15 -3
- package/src/react-menu3/positionUtils/positionMenu.ts +21 -14
- package/src/react-menu3/style-utils/index.ts +10 -7
- package/src/react-menu3/utils/constants.ts +63 -10
- package/src/react-menu3/utils/propTypes.ts +3 -1
- package/src/react-menu3/utils/utils.ts +40 -23
- package/src/react-menu3/utils/withHovering.tsx +11 -6
- 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 = (
|
|
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) =>
|
|
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
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
5
|
-
anchorRect
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
5
|
-
anchorRect
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
2
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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 =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
2
|
-
import {
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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,
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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) =>
|
|
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 (
|
|
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
|
|
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
|
|
54
|
-
|
|
55
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
13
|
+
const menuItemRef = useRef<any>(null);
|
|
9
14
|
return (
|
|
10
15
|
<Component
|
|
11
16
|
{...props}
|
|
12
|
-
|
|
17
|
+
menuItemRef={menuItemRef}
|
|
13
18
|
externalRef={ref}
|
|
14
|
-
isHovering={useContext(HoverItemContext) ===
|
|
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({});
|