@linzjs/step-ag-grid 1.4.5 → 1.4.7
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.d.ts +1 -0
- package/dist/index.js +284 -232
- package/dist/index.js.map +1 -1
- package/dist/src/components/GridCell.d.ts +4 -3
- package/dist/src/components/gridRender/GridRenderGenericCell.d.ts +8 -5
- package/dist/src/react-menu3/components/ControlledMenu.d.ts +8 -2
- package/dist/src/react-menu3/components/FocusableItem.d.ts +8 -0
- 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 +2 -1
- 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 +56 -0
- package/dist/src/react-menu3/components/MenuList.d.ts +2 -29
- package/dist/src/react-menu3/components/MenuRadioGroup.d.ts +44 -2
- package/dist/src/react-menu3/components/SubMenu.d.ts +109 -0
- 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 +1 -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/types.d.ts +389 -0
- package/dist/src/react-menu3/utils/constants.d.ts +58 -9
- package/dist/src/react-menu3/utils/index.d.ts +0 -1
- package/dist/src/react-menu3/utils/{propTypes.d.ts → propTypes2.d.ts} +1 -0
- package/dist/src/react-menu3/utils/utils.d.ts +20 -11
- 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 +276 -235
- package/dist/step-ag-grid.esm.js.map +1 -1
- package/package.json +11 -11
- package/src/components/GridCell.tsx +6 -3
- package/src/components/GridPopoverHook.tsx +1 -1
- package/src/components/gridForm/GridFormDropDown.tsx +1 -1
- package/src/components/gridForm/GridFormMultiSelect.tsx +36 -17
- package/src/components/gridRender/GridRenderGenericCell.tsx +11 -7
- package/src/components/gridRender/GridRenderPopoutMenuCell.tsx +14 -2
- package/src/contexts/GridContextProvider.tsx +3 -2
- package/src/react-menu3/components/ControlledMenu.tsx +40 -45
- 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 +158 -106
- package/src/react-menu3/components/MenuList.tsx +61 -36
- package/src/react-menu3/components/MenuRadioGroup.tsx +54 -15
- package/src/react-menu3/components/SubMenu.tsx +317 -202
- 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.ts +1 -0
- package/src/react-menu3/positionUtils/getPositionHelpers.ts +19 -12
- 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/{index.d.ts → types.ts} +106 -358
- package/src/react-menu3/utils/constants.ts +82 -10
- package/src/react-menu3/utils/index.ts +1 -1
- package/src/react-menu3/utils/{propTypes.ts → propTypes2.ts} +3 -1
- package/src/react-menu3/utils/utils.ts +41 -24
- package/src/react-menu3/utils/withHovering.tsx +11 -6
- package/src/stories/components/GridReadOnly.stories.tsx +3 -4
- package/src/stories/components/ReactMenu.stories.tsx +37 -0
|
@@ -1,23 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
import { useRef, useContext, useEffect } from "react";
|
|
1
|
+
import { useRef, useContext, useEffect, FocusEvent, MutableRefObject } from "react";
|
|
3
2
|
import { ItemSettingsContext, MenuListItemContext, HoverActionTypes } from "../utils";
|
|
4
3
|
import { useItemEffect } from "./useItemEffect";
|
|
5
4
|
|
|
6
5
|
// This hook includes some common stateful logic in MenuItem and FocusableItem
|
|
7
|
-
export const useItemState = (
|
|
6
|
+
export const useItemState = (
|
|
7
|
+
menuItemRef: MutableRefObject<any> | undefined,
|
|
8
|
+
focusRef: MutableRefObject<any> | undefined,
|
|
9
|
+
isHovering?: boolean,
|
|
10
|
+
isDisabled?: boolean,
|
|
11
|
+
) => {
|
|
8
12
|
const { submenuCloseDelay } = useContext(ItemSettingsContext);
|
|
9
13
|
const { isParentOpen, isSubmenuOpen, dispatch, updateItems } = useContext(MenuListItemContext);
|
|
10
|
-
const timeoutId = useRef(
|
|
14
|
+
const timeoutId = useRef<ReturnType<typeof setTimeout>>();
|
|
11
15
|
|
|
12
16
|
const setHover = () => {
|
|
13
|
-
!isHovering && !isDisabled && dispatch(HoverActionTypes.SET,
|
|
17
|
+
!isHovering && !isDisabled && dispatch(HoverActionTypes.SET, menuItemRef?.current, 0);
|
|
14
18
|
};
|
|
15
19
|
|
|
16
20
|
const unsetHover = () => {
|
|
17
|
-
!isDisabled && dispatch(HoverActionTypes.UNSET,
|
|
21
|
+
!isDisabled && dispatch(HoverActionTypes.UNSET, menuItemRef?.current, 0);
|
|
18
22
|
};
|
|
19
23
|
|
|
20
|
-
const onBlur = (e) => {
|
|
24
|
+
const onBlur = (e: FocusEvent) => {
|
|
21
25
|
// Focus has moved out of the entire item
|
|
22
26
|
// It handles situation such as clicking on a sibling disabled menu item
|
|
23
27
|
if (isHovering && !e.currentTarget.contains(e.relatedTarget)) unsetHover();
|
|
@@ -27,7 +31,7 @@ export const useItemState = (itemRef, focusRef, isHovering, isDisabled) => {
|
|
|
27
31
|
if (isSubmenuOpen) {
|
|
28
32
|
if (!timeoutId.current)
|
|
29
33
|
timeoutId.current = setTimeout(() => {
|
|
30
|
-
timeoutId.current =
|
|
34
|
+
timeoutId.current = undefined;
|
|
31
35
|
setHover();
|
|
32
36
|
}, submenuCloseDelay);
|
|
33
37
|
} else {
|
|
@@ -35,22 +39,22 @@ export const useItemState = (itemRef, focusRef, isHovering, isDisabled) => {
|
|
|
35
39
|
}
|
|
36
40
|
};
|
|
37
41
|
|
|
38
|
-
const onPointerLeave = (_, keepHover) => {
|
|
42
|
+
const onPointerLeave = (_: PointerEvent, keepHover: boolean) => {
|
|
39
43
|
if (timeoutId.current) {
|
|
40
44
|
clearTimeout(timeoutId.current);
|
|
41
|
-
timeoutId.current =
|
|
45
|
+
timeoutId.current = undefined;
|
|
42
46
|
}
|
|
43
47
|
|
|
44
48
|
!keepHover && unsetHover();
|
|
45
49
|
};
|
|
46
50
|
|
|
47
|
-
useItemEffect(isDisabled,
|
|
51
|
+
useItemEffect(isDisabled, menuItemRef, updateItems);
|
|
48
52
|
useEffect(() => () => clearTimeout(timeoutId.current), []);
|
|
49
53
|
useEffect(() => {
|
|
50
54
|
// Don't set focus when parent menu is closed, otherwise focus will be lost
|
|
51
55
|
// and onBlur event will be fired with relatedTarget setting as null.
|
|
52
56
|
if (isHovering && isParentOpen) {
|
|
53
|
-
focusRef
|
|
57
|
+
focusRef?.current && focusRef.current.focus();
|
|
54
58
|
}
|
|
55
59
|
}, [focusRef, isHovering, isParentOpen]);
|
|
56
60
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import { useState, useCallback, useRef } from "react";
|
|
1
|
+
import { useState, useCallback, useRef, MutableRefObject } from "react";
|
|
3
2
|
import { HoverActionTypes, indexOfNode } from "../utils";
|
|
3
|
+
import { FocusPosition } from "../types";
|
|
4
4
|
|
|
5
|
-
export const useItems = (menuRef
|
|
6
|
-
const [hoverItem, setHoverItem] = useState();
|
|
5
|
+
export const useItems = (menuRef: MutableRefObject<any>, focusRef: MutableRefObject<any> | undefined) => {
|
|
6
|
+
const [hoverItem, setHoverItem] = useState<any>();
|
|
7
7
|
const stateRef = useRef({
|
|
8
|
-
items: [],
|
|
8
|
+
items: [] as any[],
|
|
9
9
|
hoverIndex: -1,
|
|
10
10
|
sorted: false,
|
|
11
11
|
});
|
|
12
12
|
const mutableState = stateRef.current;
|
|
13
13
|
|
|
14
14
|
const updateItems = useCallback(
|
|
15
|
-
(item, isMounted) => {
|
|
15
|
+
(item?: any, isMounted?: boolean) => {
|
|
16
16
|
const { items } = mutableState;
|
|
17
17
|
if (!item) {
|
|
18
18
|
mutableState.items = [];
|
|
@@ -23,8 +23,8 @@ export const useItems = (menuRef, focusRef) => {
|
|
|
23
23
|
if (index > -1) {
|
|
24
24
|
items.splice(index, 1);
|
|
25
25
|
if (item.contains(document.activeElement)) {
|
|
26
|
-
focusRef
|
|
27
|
-
setHoverItem();
|
|
26
|
+
focusRef?.current?.focus();
|
|
27
|
+
setHoverItem(undefined);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -35,7 +35,7 @@ export const useItems = (menuRef, focusRef) => {
|
|
|
35
35
|
);
|
|
36
36
|
|
|
37
37
|
const dispatch = useCallback(
|
|
38
|
-
(actionType, item, nextIndex) => {
|
|
38
|
+
(actionType: number, item: any, nextIndex: FocusPosition) => {
|
|
39
39
|
const { items, hoverIndex } = mutableState;
|
|
40
40
|
const sortItems = () => {
|
|
41
41
|
if (mutableState.sorted) return;
|
|
@@ -55,7 +55,7 @@ export const useItems = (menuRef, focusRef) => {
|
|
|
55
55
|
break;
|
|
56
56
|
|
|
57
57
|
case HoverActionTypes.UNSET:
|
|
58
|
-
newItem = (prevItem) => (prevItem === item ? undefined : prevItem);
|
|
58
|
+
newItem = (prevItem: any) => (prevItem === item ? undefined : prevItem);
|
|
59
59
|
break;
|
|
60
60
|
|
|
61
61
|
case HoverActionTypes.FIRST:
|
|
@@ -71,6 +71,7 @@ export const useItems = (menuRef, focusRef) => {
|
|
|
71
71
|
break;
|
|
72
72
|
|
|
73
73
|
case HoverActionTypes.SET_INDEX:
|
|
74
|
+
if (typeof nextIndex !== "number") break;
|
|
74
75
|
sortItems();
|
|
75
76
|
index = nextIndex;
|
|
76
77
|
newItem = items[index];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import { useRef, useEffect } from "react";
|
|
3
2
|
import { safeCall } from "../utils";
|
|
3
|
+
import { EventHandler, MenuChangeEvent } from "../types";
|
|
4
4
|
|
|
5
|
-
export const useMenuChange = (onMenuChange
|
|
5
|
+
export const useMenuChange = (onMenuChange?: EventHandler<MenuChangeEvent>, isOpen?: boolean) => {
|
|
6
6
|
const prevOpen = useRef(isOpen);
|
|
7
7
|
|
|
8
8
|
useEffect(() => {
|
|
9
|
-
if (prevOpen.current !== isOpen) safeCall(onMenuChange, { open: isOpen });
|
|
9
|
+
if (onMenuChange && prevOpen.current !== isOpen) safeCall(onMenuChange, { open: !!isOpen });
|
|
10
10
|
prevOpen.current = isOpen;
|
|
11
11
|
}, [onMenuChange, isOpen]);
|
|
12
12
|
};
|
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
import { useTransition } from "react-transition-state";
|
|
2
2
|
import { MenuStateMap, getTransition } from "../utils";
|
|
3
|
+
import { MenuState, MenuStateOptions } from "../types";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
/**
|
|
6
|
+
* A custom Hook which helps manage the states of `ControlledMenu`.
|
|
7
|
+
*/
|
|
8
|
+
export const useMenuState = (
|
|
9
|
+
props?: MenuStateOptions,
|
|
10
|
+
): [
|
|
11
|
+
{
|
|
12
|
+
/**
|
|
13
|
+
* Menu state which should be forwarded to `ControlledMenu`.
|
|
14
|
+
*/
|
|
15
|
+
state?: MenuState;
|
|
16
|
+
/**
|
|
17
|
+
* Stop transition animation. This function value should be forwarded to `ControlledMenu`.
|
|
18
|
+
*/
|
|
19
|
+
endTransition: () => void;
|
|
20
|
+
},
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Open or close menu.
|
|
24
|
+
*
|
|
25
|
+
* - If no parameter is supplied, this function will toggle state between open and close phases.
|
|
26
|
+
* - You can set a boolean parameter to explicitly switch into one of the two phases.
|
|
27
|
+
*/
|
|
28
|
+
(open?: boolean) => void,
|
|
29
|
+
] => {
|
|
12
30
|
const { initialMounted, unmountOnClose, transition, transitionTimeout } = props ?? {
|
|
13
31
|
transition: false,
|
|
14
32
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
1
|
import { useState } from "react";
|
|
3
2
|
import { useMenuState } from "./useMenuState";
|
|
3
|
+
import { ControlledMenuProps, FocusPosition, MenuStateOptions } from "../types";
|
|
4
4
|
|
|
5
|
-
export const useMenuStateAndFocus = (
|
|
5
|
+
export const useMenuStateAndFocus = (
|
|
6
|
+
options: MenuStateOptions,
|
|
7
|
+
): [any, (open?: boolean) => void, (position?: FocusPosition, alwaysUpdate?: boolean) => void] => {
|
|
6
8
|
const [menuProps, toggleMenu] = useMenuState(options);
|
|
7
|
-
const [menuItemFocus, setMenuItemFocus] = useState();
|
|
9
|
+
const [menuItemFocus, setMenuItemFocus] = useState<ControlledMenuProps["menuItemFocus"]>();
|
|
8
10
|
|
|
9
|
-
const openMenu = (position, alwaysUpdate) => {
|
|
11
|
+
const openMenu = (position?: FocusPosition, alwaysUpdate?: boolean) => {
|
|
10
12
|
setMenuItemFocus({ position, alwaysUpdate });
|
|
11
13
|
toggleMenu(true);
|
|
12
14
|
};
|
package/src/react-menu3/index.ts
CHANGED
|
@@ -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 | undefined>,
|
|
6
|
+
menuRef: MutableRefObject<HTMLElement>,
|
|
7
|
+
menuScroll: Window | Element,
|
|
8
|
+
boundingBoxPadding: string | undefined,
|
|
9
|
+
) => {
|
|
5
10
|
const menuRect = menuRef.current.getBoundingClientRect();
|
|
6
|
-
const
|
|
7
|
-
const
|
|
11
|
+
const thisWindow = containerRef.current?.ownerDocument.defaultView ?? window;
|
|
12
|
+
const containerRect = (containerRef.current ?? thisWindow.document.body).getBoundingClientRect();
|
|
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 "../types";
|
|
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 "../types";
|
|
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 "../types";
|
|
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 "../types";
|
|
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(),
|