@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
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@linzjs/step-ag-grid",
|
|
3
3
|
"repository": "github:linz/step-ag-grid.git",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"version": "1.4.
|
|
5
|
+
"version": "1.4.6",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"typings": "dist/index.d.ts",
|
|
8
8
|
"module": "dist/step-ag-grid.esm.js",
|
|
@@ -17,23 +17,23 @@
|
|
|
17
17
|
"node": ">=14"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
|
-
"
|
|
21
|
-
"react-dom": ">=17",
|
|
20
|
+
"@linzjs/lui": ">=17",
|
|
22
21
|
"ag-grid-community": ">=27",
|
|
23
22
|
"ag-grid-react": ">=27",
|
|
24
|
-
"
|
|
23
|
+
"react": ">=17",
|
|
24
|
+
"react-dom": ">=17"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@linzjs/lui": "
|
|
28
|
-
"ag-grid-community": "
|
|
29
|
-
"ag-grid-react": "
|
|
27
|
+
"@linzjs/lui": ">=17",
|
|
28
|
+
"ag-grid-community": ">=27",
|
|
29
|
+
"ag-grid-react": ">=27",
|
|
30
30
|
"debounce-promise": "^3.1.2",
|
|
31
31
|
"lodash-es": "^4.17.21",
|
|
32
|
-
"react": "^17.0.2",
|
|
33
|
-
"react-dom": "^17.0.2",
|
|
34
|
-
"uuid": "^9.0.0",
|
|
35
32
|
"prop-types": "^15.8.1",
|
|
36
|
-
"react
|
|
33
|
+
"react": ">=17",
|
|
34
|
+
"react-dom": ">=17",
|
|
35
|
+
"react-transition-state": "^1.1.5",
|
|
36
|
+
"uuid": "^9.0.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "rollup -c && npm run",
|
|
@@ -153,7 +153,7 @@ export const GridFormDropDown = <RowType extends GridBaseRow, ValueType>(props:
|
|
|
153
153
|
<>
|
|
154
154
|
{formProps.filtered && (
|
|
155
155
|
<>
|
|
156
|
-
<FocusableItem className={"filter-item"}
|
|
156
|
+
<FocusableItem className={"filter-item"}>
|
|
157
157
|
{({ ref }: any) => (
|
|
158
158
|
<div style={{ display: "flex", width: "100%" }}>
|
|
159
159
|
<input
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../../react-menu3/styles/index.scss";
|
|
2
2
|
|
|
3
|
-
import { MenuItem, MenuDivider, FocusableItem } from "@react-menu3";
|
|
3
|
+
import { MenuItem, MenuDivider, FocusableItem, RadioChangeEvent } from "@react-menu3";
|
|
4
4
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
5
|
import { GridBaseRow } from "../Grid";
|
|
6
6
|
import { ComponentLoadingWrapper } from "../ComponentLoadingWrapper";
|
|
@@ -58,7 +58,7 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
|
|
|
58
58
|
},
|
|
59
59
|
[formProps, selectedValues],
|
|
60
60
|
);
|
|
61
|
-
const { popoverWrapper } = useGridPopoverHook(props, save);
|
|
61
|
+
const { popoverWrapper, triggerSave } = useGridPopoverHook(props, save);
|
|
62
62
|
|
|
63
63
|
// Load up options list if it's async function
|
|
64
64
|
useEffect(() => {
|
|
@@ -137,11 +137,17 @@ export const GridFormMultiSelect = <RowType extends GridBaseRow, ValueType>(prop
|
|
|
137
137
|
<>
|
|
138
138
|
<MenuItem
|
|
139
139
|
key={`${item.value}`}
|
|
140
|
-
onClick={(e:
|
|
140
|
+
onClick={(e: RadioChangeEvent) => {
|
|
141
|
+
// FIXME Matt Event type guessed here
|
|
141
142
|
e.keepOpen = true;
|
|
142
|
-
|
|
143
|
+
if (selectedValues.includes(e.value)) {
|
|
144
|
+
setSelectedValues(selectedValues.filter((value) => value != item.value));
|
|
145
|
+
} else {
|
|
146
|
+
setSelectedValues([...selectedValues, item.value as string]);
|
|
147
|
+
}
|
|
143
148
|
return false;
|
|
144
149
|
}}
|
|
150
|
+
onKeyDown={async (e) => e.key === "Enter" && triggerSave().then()}
|
|
145
151
|
>
|
|
146
152
|
<LuiCheckboxInput
|
|
147
153
|
isChecked={selectedValues.includes(item.value)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
+
/* eslint-disable */
|
|
2
3
|
import { forwardRef, useRef, useMemo, useCallback, useEffect } from "react";
|
|
3
4
|
import { createPortal } from "react-dom";
|
|
4
5
|
import { string, number, bool, func, object, oneOf, oneOfType, exact } from "prop-types";
|
|
@@ -47,7 +48,7 @@ export const ControlledMenu = forwardRef(function ControlledMenu(
|
|
|
47
48
|
externalRef,
|
|
48
49
|
) {
|
|
49
50
|
const containerRef = useRef(null);
|
|
50
|
-
const scrollNodesRef = useRef({});
|
|
51
|
+
const scrollNodesRef = useRef<{anchors?:HTMLDivElement[]}>({});
|
|
51
52
|
const { anchorRef, state } = restProps;
|
|
52
53
|
|
|
53
54
|
const settings = useMemo(
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { useContext, useMemo, useRef } from "react";
|
|
3
|
-
import { bool, func } from "prop-types";
|
|
1
|
+
import { LegacyRef, useContext, useMemo, useRef } from "react";
|
|
4
2
|
import { useBEM, useCombinedRef, useItemState } from "../hooks";
|
|
5
3
|
import {
|
|
6
4
|
mergeProps,
|
|
@@ -8,63 +6,70 @@ import {
|
|
|
8
6
|
safeCall,
|
|
9
7
|
menuClass,
|
|
10
8
|
menuItemClass,
|
|
11
|
-
stylePropTypes,
|
|
12
9
|
withHovering,
|
|
13
10
|
EventHandlersContext,
|
|
14
11
|
} from "../utils";
|
|
12
|
+
import { BaseProps } from "../index";
|
|
13
|
+
import { withHoveringResultProps } from "../utils/withHovering";
|
|
15
14
|
|
|
16
|
-
export
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const ref = useRef(null);
|
|
21
|
-
const { setHover, onPointerLeave, ...restStateProps } = useItemState(itemRef, ref, isHovering, isDisabled);
|
|
22
|
-
const { handleClose } = useContext(EventHandlersContext);
|
|
15
|
+
export interface FocusableItemProps extends BaseProps, withHoveringResultProps {
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
children: (ref: LegacyRef<any>) => JSX.Element;
|
|
18
|
+
}
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
export const FocusableItemFr = ({
|
|
21
|
+
className,
|
|
22
|
+
disabled,
|
|
23
|
+
children,
|
|
24
|
+
isHovering,
|
|
25
|
+
menuItemRef,
|
|
26
|
+
externalRef,
|
|
27
|
+
...restProps
|
|
28
|
+
}: FocusableItemProps) => {
|
|
29
|
+
const isDisabled = !!disabled;
|
|
30
|
+
const ref = useRef(null);
|
|
31
|
+
const { setHover, onPointerLeave, ...restStateProps } = useItemState(menuItemRef, ref, isHovering, isDisabled);
|
|
32
|
+
const { handleClose } = useContext(EventHandlersContext);
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
34
|
+
const modifiers = useMemo(
|
|
35
|
+
() => ({
|
|
36
|
+
disabled: isDisabled,
|
|
37
|
+
hover: isHovering,
|
|
38
|
+
focusable: true,
|
|
39
|
+
}),
|
|
40
|
+
[isDisabled, isHovering],
|
|
41
|
+
);
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
const renderChildren = useMemo(
|
|
44
|
+
() =>
|
|
45
|
+
safeCall(children, {
|
|
46
|
+
...modifiers,
|
|
47
|
+
ref,
|
|
48
|
+
closeMenu: handleClose,
|
|
49
|
+
}),
|
|
50
|
+
[children, modifiers, handleClose],
|
|
51
|
+
);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{renderChildren}
|
|
61
|
-
</li>
|
|
62
|
-
);
|
|
63
|
-
},
|
|
64
|
-
);
|
|
53
|
+
const mergedProps = mergeProps(
|
|
54
|
+
{
|
|
55
|
+
...restStateProps,
|
|
56
|
+
onPointerLeave: (e: PointerEvent) => onPointerLeave(e, true),
|
|
57
|
+
onFocus: setHover,
|
|
58
|
+
},
|
|
59
|
+
restProps,
|
|
60
|
+
);
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
62
|
+
return (
|
|
63
|
+
<li
|
|
64
|
+
role="menuitem"
|
|
65
|
+
{...mergedProps}
|
|
66
|
+
{...commonProps(isDisabled)}
|
|
67
|
+
ref={useCombinedRef(externalRef, menuItemRef)}
|
|
68
|
+
className={useBEM({ block: menuClass, element: menuItemClass, modifiers, className })}
|
|
69
|
+
>
|
|
70
|
+
{renderChildren}
|
|
71
|
+
</li>
|
|
72
|
+
);
|
|
70
73
|
};
|
|
74
|
+
|
|
75
|
+
export const FocusableItem = withHovering("FocusableItem", FocusableItemFr) as any as typeof FocusableItemFr;
|
|
@@ -1,43 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
cloneElement,
|
|
3
|
+
Fragment,
|
|
4
|
+
forwardRef,
|
|
5
|
+
useRef,
|
|
6
|
+
useCallback,
|
|
7
|
+
useImperativeHandle,
|
|
8
|
+
ReactElement,
|
|
9
|
+
ForwardedRef,
|
|
10
|
+
} from "react";
|
|
4
11
|
import { ControlledMenu } from "./ControlledMenu";
|
|
5
12
|
import { useMenuChange, useMenuStateAndFocus, useCombinedRef } from "../hooks";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
mergeProps,
|
|
9
|
-
safeCall,
|
|
10
|
-
isMenuOpen,
|
|
11
|
-
uncontrolledMenuPropTypes,
|
|
12
|
-
rootMenuPropTypes,
|
|
13
|
-
Keys,
|
|
14
|
-
FocusPositions,
|
|
15
|
-
} from "../utils";
|
|
13
|
+
import { getName, mergeProps, safeCall, isMenuOpen, Keys, FocusPositions } from "../utils";
|
|
14
|
+
import { MenuButtonModifiers, RenderProp, RootMenuProps, UncontrolledMenuProps } from "../index";
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
//
|
|
17
|
+
// Menu
|
|
18
|
+
// ----------------------------------------------------------------------
|
|
19
|
+
export interface MenuProps extends RootMenuProps, UncontrolledMenuProps {
|
|
20
|
+
/**
|
|
21
|
+
* Can be a `MenuButton`, a `button` element, or a React component.
|
|
22
|
+
* It also can be a render function that returns one.
|
|
23
|
+
*
|
|
24
|
+
* If a React component is provided, it needs to implement the following contracts:
|
|
25
|
+
* - Accepts a `ref` prop that is forwarded to an element to which menu will be positioned.
|
|
26
|
+
* The element should be able to receive focus.
|
|
27
|
+
* - Accepts `onClick` and `onKeyDown` event props.
|
|
28
|
+
*/
|
|
29
|
+
menuButton: RenderProp<MenuButtonModifiers, ReactElement>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function MenuFr(
|
|
33
|
+
{ "aria-label": ariaLabel, menuButton, instanceRef, onMenuChange, ...restProps }: MenuProps,
|
|
34
|
+
externalRef: ForwardedRef<any>, // FIXME Matt correct type?
|
|
20
35
|
) {
|
|
21
36
|
const [stateProps, toggleMenu, openMenu] = useMenuStateAndFocus(restProps);
|
|
22
37
|
const isOpen = isMenuOpen(stateProps.state);
|
|
23
38
|
const skipOpen = useRef(false);
|
|
24
|
-
const buttonRef = useRef(null);
|
|
39
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
25
40
|
|
|
26
41
|
const handleClose = useCallback(
|
|
27
42
|
(e) => {
|
|
28
43
|
toggleMenu(false);
|
|
29
|
-
if (e.key) buttonRef.current.focus();
|
|
44
|
+
if (e.key) buttonRef.current && buttonRef.current.focus();
|
|
30
45
|
},
|
|
31
46
|
[toggleMenu],
|
|
32
47
|
);
|
|
33
48
|
|
|
34
|
-
const onClick = (e) => {
|
|
49
|
+
const onClick = (e: MouseEvent) => {
|
|
35
50
|
if (skipOpen.current) return;
|
|
36
51
|
// Focus (hover) the first menu item when onClick event is trigger by keyboard
|
|
37
52
|
openMenu(e.detail === 0 ? FocusPositions.FIRST : undefined);
|
|
38
53
|
};
|
|
39
54
|
|
|
40
|
-
const onKeyDown = (e) => {
|
|
55
|
+
const onKeyDown = (e: KeyboardEvent) => {
|
|
41
56
|
switch (e.key) {
|
|
42
57
|
case Keys.UP:
|
|
43
58
|
openMenu(FocusPositions.LAST);
|
|
@@ -54,12 +69,14 @@ export const Menu = forwardRef(function Menu(
|
|
|
54
69
|
e.preventDefault();
|
|
55
70
|
};
|
|
56
71
|
|
|
57
|
-
|
|
72
|
+
// FIXME erk! button seems to be many types
|
|
73
|
+
const button: any = safeCall(menuButton, { open: isOpen });
|
|
58
74
|
if (!button || !button.type) throw new Error("Menu requires a menuButton prop.");
|
|
59
75
|
|
|
60
76
|
const buttonProps = {
|
|
61
77
|
ref: useCombinedRef(button.ref, buttonRef),
|
|
62
78
|
...mergeProps({ onClick, onKeyDown }, button.props),
|
|
79
|
+
isOpen: false,
|
|
63
80
|
};
|
|
64
81
|
if (getName(button.type) === "MenuButton") {
|
|
65
82
|
buttonProps.isOpen = isOpen;
|
|
@@ -87,10 +104,5 @@ export const Menu = forwardRef(function Menu(
|
|
|
87
104
|
/>
|
|
88
105
|
</Fragment>
|
|
89
106
|
);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
Menu.propTypes = {
|
|
93
|
-
...rootMenuPropTypes,
|
|
94
|
-
...uncontrolledMenuPropTypes,
|
|
95
|
-
menuButton: oneOfType([element, func]).isRequired,
|
|
96
|
-
};
|
|
107
|
+
}
|
|
108
|
+
export const Menu = forwardRef(MenuFr);
|
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
|
|
2
|
-
import { forwardRef, useMemo } from "react";
|
|
3
|
-
import { bool } from "prop-types";
|
|
1
|
+
import { forwardRef, LegacyRef, ReactNode, useMemo } from "react";
|
|
4
2
|
import { useBEM } from "../hooks";
|
|
5
|
-
import {
|
|
3
|
+
import { menuButtonClass } from "../utils";
|
|
4
|
+
import { BaseProps, MenuButtonModifiers } from "../index";
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const modifiers = useMemo(() => ({ open: isOpen }), [isOpen]);
|
|
6
|
+
export interface MenuButtonProps extends BaseProps<MenuButtonModifiers> {
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
children?: ReactNode;
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
aria-expanded={isOpen}
|
|
16
|
-
aria-disabled={disabled || undefined}
|
|
17
|
-
type="button"
|
|
18
|
-
disabled={disabled}
|
|
19
|
-
{...restProps}
|
|
20
|
-
ref={ref}
|
|
21
|
-
className={useBEM({ block: menuButtonClass, modifiers, className })}
|
|
22
|
-
>
|
|
23
|
-
{children}
|
|
24
|
-
</button>
|
|
25
|
-
);
|
|
26
|
-
}),
|
|
27
|
-
);
|
|
10
|
+
// FIXME Matt added, seems to be an internal thing
|
|
11
|
+
isOpen?: boolean;
|
|
12
|
+
}
|
|
28
13
|
|
|
29
|
-
MenuButton
|
|
30
|
-
...
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
14
|
+
export const MenuButton = forwardRef(function MenuButton(
|
|
15
|
+
{ className, isOpen, disabled, children, ...restProps }: MenuButtonProps,
|
|
16
|
+
ref: LegacyRef<HTMLButtonElement>,
|
|
17
|
+
) {
|
|
18
|
+
const modifiers = useMemo(() => ({ open: isOpen }), [isOpen]);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<button
|
|
22
|
+
aria-haspopup
|
|
23
|
+
aria-expanded={isOpen}
|
|
24
|
+
aria-disabled={disabled || undefined}
|
|
25
|
+
type="button"
|
|
26
|
+
disabled={disabled}
|
|
27
|
+
{...restProps}
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={useBEM({ block: menuButtonClass, modifiers, className })}
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</button>
|
|
33
|
+
);
|
|
34
|
+
});
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import { memo, forwardRef } from "react";
|
|
1
|
+
import { memo, forwardRef, LegacyRef } from "react";
|
|
3
2
|
import { useBEM } from "../hooks";
|
|
4
|
-
import { menuClass, menuDividerClass
|
|
3
|
+
import { menuClass, menuDividerClass } from "../utils";
|
|
4
|
+
import { BaseProps } from "../index";
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
}),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
MenuDivider.propTypes = {
|
|
20
|
-
...stylePropTypes(),
|
|
6
|
+
const MenuDividerFr = ({ className, ...restProps }: BaseProps, externalRef: LegacyRef<HTMLLIElement>) => {
|
|
7
|
+
return (
|
|
8
|
+
<li
|
|
9
|
+
role="separator"
|
|
10
|
+
{...restProps}
|
|
11
|
+
ref={externalRef}
|
|
12
|
+
className={useBEM({ block: menuClass, element: menuDividerClass, className })}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
21
15
|
};
|
|
16
|
+
|
|
17
|
+
export const MenuDivider = memo(forwardRef(MenuDividerFr)) as any as typeof MenuDividerFr;
|
|
@@ -1,38 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
import { forwardRef, useContext, useRef, useState } from "react";
|
|
3
|
-
import { bool } from "prop-types";
|
|
1
|
+
import { ForwardedRef, forwardRef, ReactNode, useContext, useRef, useState } from "react";
|
|
4
2
|
import { useBEM, useLayoutEffect, useCombinedRef } from "../hooks";
|
|
5
|
-
import { menuClass, menuGroupClass,
|
|
3
|
+
import { menuClass, menuGroupClass, MenuListContext } from "../utils";
|
|
4
|
+
import { BaseProps, MenuOverflow } from "../index";
|
|
6
5
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
export interface MenuGroupProps extends BaseProps {
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Set `true` to apply overflow of the parent menu to the group.
|
|
10
|
+
* Only one `MenuGroup` in a menu should set this prop as `true`.
|
|
11
|
+
*/
|
|
12
|
+
takeOverflow?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const MenuGroupFr = (
|
|
16
|
+
{ className, style, takeOverflow, ...restProps }: MenuGroupProps,
|
|
17
|
+
externalRef: ForwardedRef<HTMLDivElement>,
|
|
18
|
+
) => {
|
|
19
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
20
|
+
const [overflowStyle, setOverflowStyle] = useState<{ maxHeight?: number; overflow?: MenuOverflow }>();
|
|
10
21
|
const { overflow, overflowAmt } = useContext(MenuListContext);
|
|
11
22
|
|
|
12
23
|
useLayoutEffect(() => {
|
|
13
24
|
let maxHeight;
|
|
14
|
-
if (takeOverflow && overflowAmt >= 0) {
|
|
25
|
+
if (takeOverflow && overflowAmt != null && overflowAmt >= 0 && ref.current) {
|
|
26
|
+
// FIXME Matt added && ref.current
|
|
15
27
|
maxHeight = ref.current.getBoundingClientRect().height - overflowAmt;
|
|
16
28
|
if (maxHeight < 0) maxHeight = 0;
|
|
17
29
|
}
|
|
18
|
-
setOverflowStyle(maxHeight >= 0 ? { maxHeight, overflow } : undefined);
|
|
30
|
+
setOverflowStyle(maxHeight != null && maxHeight >= 0 ? { maxHeight, overflow } : undefined);
|
|
19
31
|
}, [takeOverflow, overflow, overflowAmt]);
|
|
20
32
|
|
|
21
33
|
useLayoutEffect(() => {
|
|
22
|
-
if (overflowStyle) ref.current.scrollTop = 0;
|
|
34
|
+
if (overflowStyle && ref.current) ref.current.scrollTop = 0;
|
|
23
35
|
}, [overflowStyle]);
|
|
24
36
|
|
|
25
37
|
return (
|
|
26
38
|
<div
|
|
27
39
|
{...restProps}
|
|
28
|
-
ref={useCombinedRef(externalRef, ref)}
|
|
40
|
+
ref={useCombinedRef(externalRef, ref)} // TODO wierd refs
|
|
29
41
|
className={useBEM({ block: menuClass, element: menuGroupClass, className })}
|
|
30
42
|
style={{ ...style, ...overflowStyle }}
|
|
31
43
|
/>
|
|
32
44
|
);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
MenuGroup.propTypes = {
|
|
36
|
-
...stylePropTypes(),
|
|
37
|
-
takeOverflow: bool,
|
|
38
45
|
};
|
|
46
|
+
|
|
47
|
+
export const MenuGroup = forwardRef(MenuGroupFr);
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
import { memo, forwardRef } from "react";
|
|
1
|
+
import { memo, forwardRef, ForwardedRef } from "react";
|
|
3
2
|
import { useBEM } from "../hooks";
|
|
4
|
-
import { menuClass, menuHeaderClass
|
|
3
|
+
import { menuClass, menuHeaderClass } from "../utils";
|
|
4
|
+
import { BaseProps } from "../index";
|
|
5
5
|
|
|
6
|
-
export const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
}),
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
MenuHeader.propTypes = {
|
|
20
|
-
...stylePropTypes(),
|
|
6
|
+
export const MenuHeaderFr = ({ className, ...restProps }: BaseProps, externalRef: ForwardedRef<HTMLLIElement>) => {
|
|
7
|
+
return (
|
|
8
|
+
<li
|
|
9
|
+
role="presentation"
|
|
10
|
+
{...restProps}
|
|
11
|
+
ref={externalRef}
|
|
12
|
+
className={useBEM({ block: menuClass, element: menuHeaderClass, className })}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
21
15
|
};
|
|
16
|
+
|
|
17
|
+
export const MenuHeader = memo(forwardRef(MenuHeaderFr));
|