@ltht-react/menu 2.0.162 → 2.0.164
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/README.md +15 -15
- package/lib/molecules/action-menu.js +11 -5
- package/lib/molecules/action-menu.js.map +1 -1
- package/package.json +6 -5
- package/src/index.tsx +4 -4
- package/src/molecules/action-menu.tsx +220 -211
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# Input
|
|
2
|
-
|
|
3
|
-
<!-- STORY -->
|
|
4
|
-
|
|
5
|
-
### Import
|
|
6
|
-
|
|
7
|
-
```js
|
|
8
|
-
import Menu from '@ltht-react/menu'
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
### Usage
|
|
12
|
-
|
|
13
|
-
```jsx
|
|
14
|
-
<Menu />
|
|
15
|
-
```
|
|
1
|
+
# Input
|
|
2
|
+
|
|
3
|
+
<!-- STORY -->
|
|
4
|
+
|
|
5
|
+
### Import
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import Menu from '@ltht-react/menu'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Usage
|
|
12
|
+
|
|
13
|
+
```jsx
|
|
14
|
+
<Menu />
|
|
15
|
+
```
|
|
@@ -60,6 +60,7 @@ var styles_1 = require("@ltht-react/styles");
|
|
|
60
60
|
var focus_trap_react_1 = __importDefault(require("focus-trap-react"));
|
|
61
61
|
var react_1 = require("react");
|
|
62
62
|
var react_popper_1 = require("react-popper");
|
|
63
|
+
var utils_1 = require("@ltht-react/utils");
|
|
63
64
|
var defaultMenuButtonProps = {
|
|
64
65
|
type: 'icon',
|
|
65
66
|
iconProps: {
|
|
@@ -77,6 +78,7 @@ var StyledLeftIcon = (0, styled_1.default)(icon_1.default)(templateObject_7 || (
|
|
|
77
78
|
var StyledMenuButtonWrapper = styled_1.default.div(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n display: inline-block;\n"], ["\n display: inline-block;\n"])));
|
|
78
79
|
var ActionMenu = function (_a) {
|
|
79
80
|
var actions = _a.actions, _b = _a.menuButtonOptions, menuButtonOptions = _b === void 0 ? defaultMenuButtonProps : _b, _c = _a.id, id = _c === void 0 ? 'action-menu-button' : _c, _d = _a.popupStyle, popupStyle = _d === void 0 ? {} : _d, _e = _a.popupPlacement, popupPlacement = _e === void 0 ? 'bottom-start' : _e, rest = __rest(_a, ["actions", "menuButtonOptions", "id", "popupStyle", "popupPlacement"]);
|
|
81
|
+
var menuItemIdPrefix = id ? "".concat(id, "-") : '';
|
|
80
82
|
var popperRef = (0, react_1.useRef)(null);
|
|
81
83
|
var _f = (0, react_1.useState)(null), popperElement = _f[0], setPopperElement = _f[1];
|
|
82
84
|
var _g = (0, react_1.useState)(null), containerElement = _g[0], setContainerElement = _g[1];
|
|
@@ -113,11 +115,15 @@ var ActionMenu = function (_a) {
|
|
|
113
115
|
}, id: id, "data-testid": id }))), menuButtonOptions.type === 'button' && ((0, jsx_runtime_1.jsx)(button_1.default, __assign({}, menuButtonOptions.buttonProps, rest, { onClick: function (e) {
|
|
114
116
|
e.stopPropagation();
|
|
115
117
|
menuButtonClickHandler();
|
|
116
|
-
}, id: id, "data-testid": id, children: menuButtonOptions.text }))), showMenu && ((0, jsx_runtime_1.jsx)(StyledCard, __assign({ tabIndex: -1, ref: setPopperElement, style: __assign(__assign({}, popper.styles.popper), popupStyle) }, popper.attributes.popper, { children: (0, jsx_runtime_1.jsx)(StyledUnorderedList, { role: "menu", "aria-labelledby": id, children: actions.map(function (action, idx) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
}, id: id, "data-testid": id, children: menuButtonOptions.text }))), showMenu && ((0, jsx_runtime_1.jsx)(StyledCard, __assign({ tabIndex: -1, ref: setPopperElement, style: __assign(__assign({}, popper.styles.popper), popupStyle) }, popper.attributes.popper, { children: (0, jsx_runtime_1.jsx)(StyledUnorderedList, { role: "menu", "aria-labelledby": id, children: actions.map(function (action, idx) {
|
|
119
|
+
var textId = (0, utils_1.stringToHtmlId)(action.text);
|
|
120
|
+
var actionMenuItemId = "".concat(menuItemIdPrefix, "action-menu-item-").concat(textId, "-").concat(idx);
|
|
121
|
+
return ((0, jsx_runtime_1.jsxs)(StyledListItem, { "data-testid": actionMenuItemId, id: actionMenuItemId, role: "menuitem", onClick: function (e) {
|
|
122
|
+
e.stopPropagation();
|
|
123
|
+
menuButtonClickHandler();
|
|
124
|
+
action.clickHandler();
|
|
125
|
+
}, children: [(0, jsx_runtime_1.jsx)(StyledListItemIcon, { children: action.leftIcon && (0, jsx_runtime_1.jsx)(StyledLeftIcon, __assign({}, action.leftIcon)) }), (0, jsx_runtime_1.jsx)(StyledListItemContent, { children: action.text }), (0, jsx_runtime_1.jsx)(StyledListItemIcon, { children: action.rightIcon && (0, jsx_runtime_1.jsx)(StyledRightIcon, __assign({}, action.rightIcon)) })] }, "menu-action-".concat(idx)));
|
|
126
|
+
}) }) })))] }) }) }));
|
|
121
127
|
};
|
|
122
128
|
exports.default = ActionMenu;
|
|
123
129
|
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-menu.js","sourceRoot":"","sources":["../../src/molecules/action-menu.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2DAAoC;AACpC,+EAAyE;AACzE,uDAA8D;AAC9D,6CAAiG;AACjG,sEAAwC;AACxC,+BAAuE;AACvE,6CAAwC;
|
|
1
|
+
{"version":3,"file":"action-menu.js","sourceRoot":"","sources":["../../src/molecules/action-menu.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ltht-react/menu",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.164",
|
|
4
4
|
"description": "ltht-react styled Menu component.",
|
|
5
5
|
"author": "LTHT",
|
|
6
6
|
"homepage": "",
|
|
@@ -28,12 +28,13 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@emotion/react": "^11.0.0",
|
|
30
30
|
"@emotion/styled": "^11.0.0",
|
|
31
|
-
"@ltht-react/button": "^2.0.
|
|
32
|
-
"@ltht-react/icon": "^2.0.
|
|
33
|
-
"@ltht-react/styles": "^2.0.
|
|
31
|
+
"@ltht-react/button": "^2.0.164",
|
|
32
|
+
"@ltht-react/icon": "^2.0.164",
|
|
33
|
+
"@ltht-react/styles": "^2.0.164",
|
|
34
|
+
"@ltht-react/utils": "^2.0.164",
|
|
34
35
|
"focus-trap-react": "^10.0.0",
|
|
35
36
|
"react": "^18.2.0",
|
|
36
37
|
"react-popper": "^2.3.0"
|
|
37
38
|
},
|
|
38
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "60633c8ef7fc6da5513b54d519588de94d6d52dc"
|
|
39
40
|
}
|
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import ActionMenu, { ActionMenuOption } from './molecules/action-menu'
|
|
2
|
-
|
|
3
|
-
export default ActionMenu
|
|
4
|
-
export { ActionMenuOption }
|
|
1
|
+
import ActionMenu, { ActionMenuOption } from './molecules/action-menu'
|
|
2
|
+
|
|
3
|
+
export default ActionMenu
|
|
4
|
+
export { ActionMenuOption }
|
|
@@ -1,211 +1,220 @@
|
|
|
1
|
-
import styled from '@emotion/styled'
|
|
2
|
-
import Button, { ButtonProps } from '@ltht-react/button/lib/atoms/button'
|
|
3
|
-
import Icon, { IconButton, IconProps } from '@ltht-react/icon'
|
|
4
|
-
import { BTN_COLOURS, CSS_RESET, PopUp, TableDataWithPopUp, getZIndex } from '@ltht-react/styles'
|
|
5
|
-
import FocusTrap from 'focus-trap-react'
|
|
6
|
-
import { FC, HTMLAttributes, useRef, useState, useEffect } from 'react'
|
|
7
|
-
import { usePopper } from 'react-popper'
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
margin-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
margin-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
{action
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
1
|
+
import styled from '@emotion/styled'
|
|
2
|
+
import Button, { ButtonProps } from '@ltht-react/button/lib/atoms/button'
|
|
3
|
+
import Icon, { IconButton, IconProps } from '@ltht-react/icon'
|
|
4
|
+
import { BTN_COLOURS, CSS_RESET, PopUp, TableDataWithPopUp, getZIndex } from '@ltht-react/styles'
|
|
5
|
+
import FocusTrap from 'focus-trap-react'
|
|
6
|
+
import { FC, HTMLAttributes, useRef, useState, useEffect } from 'react'
|
|
7
|
+
import { usePopper } from 'react-popper'
|
|
8
|
+
import { stringToHtmlId } from '@ltht-react/utils'
|
|
9
|
+
|
|
10
|
+
const defaultMenuButtonProps: IconButtonMenuProps = {
|
|
11
|
+
type: 'icon',
|
|
12
|
+
iconProps: {
|
|
13
|
+
type: 'ellipsis-vertical',
|
|
14
|
+
size: 'large',
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const StyledUnorderedList = styled.ul`
|
|
19
|
+
${CSS_RESET}
|
|
20
|
+
list-style-type: none;
|
|
21
|
+
padding: 0;
|
|
22
|
+
margin: 0;
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
const StyledListItem = styled.li`
|
|
26
|
+
${CSS_RESET}
|
|
27
|
+
background-color: 'white';
|
|
28
|
+
padding: 0.5rem;
|
|
29
|
+
line-height: 1em;
|
|
30
|
+
display: flex;
|
|
31
|
+
border-radius: 4px;
|
|
32
|
+
|
|
33
|
+
&:hover {
|
|
34
|
+
background: ${BTN_COLOURS.PRIMARY.VALUE};
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
color: white;
|
|
37
|
+
}
|
|
38
|
+
`
|
|
39
|
+
|
|
40
|
+
const StyledListItemIcon = styled.div`
|
|
41
|
+
flex-basis: 25%;
|
|
42
|
+
`
|
|
43
|
+
|
|
44
|
+
const StyledListItemContent = styled.div`
|
|
45
|
+
flex: 1;
|
|
46
|
+
text-align: left;
|
|
47
|
+
`
|
|
48
|
+
|
|
49
|
+
const StyledCard = styled.div`
|
|
50
|
+
${CSS_RESET}
|
|
51
|
+
display: inline-block;
|
|
52
|
+
min-width: 10rem;
|
|
53
|
+
z-index: 1;
|
|
54
|
+
background: white;
|
|
55
|
+
border-radius: 4px;
|
|
56
|
+
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.04), 0px 4px 5px rgba(0, 0, 0, 0.06), 0px 2px 4px -1px rgba(0, 0, 0, 0.09);
|
|
57
|
+
`
|
|
58
|
+
|
|
59
|
+
const StyledRightIcon = styled(Icon)`
|
|
60
|
+
margin-right: 0.5rem;
|
|
61
|
+
margin-left: 3rem;
|
|
62
|
+
`
|
|
63
|
+
|
|
64
|
+
const StyledLeftIcon = styled(Icon)`
|
|
65
|
+
margin-right: 0.5rem;
|
|
66
|
+
margin-left: 0.5rem;
|
|
67
|
+
`
|
|
68
|
+
|
|
69
|
+
const StyledMenuButtonWrapper = styled.div`
|
|
70
|
+
display: inline-block;
|
|
71
|
+
`
|
|
72
|
+
|
|
73
|
+
const ActionMenu: FC<IProps> = ({
|
|
74
|
+
actions,
|
|
75
|
+
menuButtonOptions = defaultMenuButtonProps,
|
|
76
|
+
id = 'action-menu-button',
|
|
77
|
+
popupStyle = {},
|
|
78
|
+
popupPlacement = 'bottom-start',
|
|
79
|
+
...rest
|
|
80
|
+
}) => {
|
|
81
|
+
const menuItemIdPrefix = id ? `${id}-` : ''
|
|
82
|
+
const popperRef = useRef<HTMLDivElement>(null)
|
|
83
|
+
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null)
|
|
84
|
+
const [containerElement, setContainerElement] = useState<HTMLDivElement | null>(null)
|
|
85
|
+
|
|
86
|
+
const popper = usePopper(popperRef.current, popperElement, {
|
|
87
|
+
placement: popupPlacement,
|
|
88
|
+
strategy: 'fixed',
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const closePopper = () => {
|
|
92
|
+
setShowMenu(false)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const [showMenu, setShowMenu] = useState(false)
|
|
96
|
+
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
if (containerElement?.parentElement?.style) {
|
|
99
|
+
containerElement.parentElement.style.zIndex = showMenu
|
|
100
|
+
? `${getZIndex(PopUp)}`
|
|
101
|
+
: `${getZIndex(TableDataWithPopUp)}`
|
|
102
|
+
}
|
|
103
|
+
}, [containerElement, showMenu])
|
|
104
|
+
|
|
105
|
+
const menuButtonClickHandler = () => {
|
|
106
|
+
setShowMenu(!showMenu)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<div ref={setContainerElement}>
|
|
111
|
+
<FocusTrap
|
|
112
|
+
active={showMenu}
|
|
113
|
+
focusTrapOptions={{
|
|
114
|
+
tabbableOptions: {
|
|
115
|
+
displayCheck: 'none',
|
|
116
|
+
},
|
|
117
|
+
initialFocus: false,
|
|
118
|
+
allowOutsideClick: false,
|
|
119
|
+
clickOutsideDeactivates: true,
|
|
120
|
+
onDeactivate: closePopper,
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
<StyledMenuButtonWrapper ref={popperRef}>
|
|
124
|
+
{menuButtonOptions.type === 'icon' && (
|
|
125
|
+
<IconButton
|
|
126
|
+
iconProps={menuButtonOptions.iconProps}
|
|
127
|
+
text={menuButtonOptions.text}
|
|
128
|
+
{...rest}
|
|
129
|
+
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
130
|
+
e.stopPropagation()
|
|
131
|
+
menuButtonClickHandler()
|
|
132
|
+
}}
|
|
133
|
+
id={id}
|
|
134
|
+
data-testid={id}
|
|
135
|
+
/>
|
|
136
|
+
)}
|
|
137
|
+
{menuButtonOptions.type === 'button' && (
|
|
138
|
+
<Button
|
|
139
|
+
{...menuButtonOptions.buttonProps}
|
|
140
|
+
{...rest}
|
|
141
|
+
onClick={(e: React.MouseEvent<HTMLButtonElement>) => {
|
|
142
|
+
e.stopPropagation()
|
|
143
|
+
menuButtonClickHandler()
|
|
144
|
+
}}
|
|
145
|
+
id={id}
|
|
146
|
+
data-testid={id}
|
|
147
|
+
>
|
|
148
|
+
{menuButtonOptions.text}
|
|
149
|
+
</Button>
|
|
150
|
+
)}
|
|
151
|
+
{showMenu && (
|
|
152
|
+
<StyledCard
|
|
153
|
+
tabIndex={-1}
|
|
154
|
+
ref={setPopperElement}
|
|
155
|
+
style={{ ...popper.styles.popper, ...popupStyle }}
|
|
156
|
+
{...popper.attributes.popper}
|
|
157
|
+
>
|
|
158
|
+
<StyledUnorderedList role="menu" aria-labelledby={id}>
|
|
159
|
+
{actions.map((action, idx) => {
|
|
160
|
+
const textId = stringToHtmlId(action.text)
|
|
161
|
+
const actionMenuItemId = `${menuItemIdPrefix}action-menu-item-${textId}-${idx}`
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<StyledListItem
|
|
165
|
+
data-testid={actionMenuItemId}
|
|
166
|
+
id={actionMenuItemId}
|
|
167
|
+
role="menuitem"
|
|
168
|
+
key={`menu-action-${idx}`}
|
|
169
|
+
onClick={(e) => {
|
|
170
|
+
e.stopPropagation()
|
|
171
|
+
menuButtonClickHandler()
|
|
172
|
+
action.clickHandler()
|
|
173
|
+
}}
|
|
174
|
+
>
|
|
175
|
+
<StyledListItemIcon>
|
|
176
|
+
{action.leftIcon && <StyledLeftIcon {...action.leftIcon} />}
|
|
177
|
+
</StyledListItemIcon>
|
|
178
|
+
<StyledListItemContent>{action.text}</StyledListItemContent>
|
|
179
|
+
<StyledListItemIcon>
|
|
180
|
+
{action.rightIcon && <StyledRightIcon {...action.rightIcon} />}
|
|
181
|
+
</StyledListItemIcon>
|
|
182
|
+
</StyledListItem>
|
|
183
|
+
)
|
|
184
|
+
})}
|
|
185
|
+
</StyledUnorderedList>
|
|
186
|
+
</StyledCard>
|
|
187
|
+
)}
|
|
188
|
+
</StyledMenuButtonWrapper>
|
|
189
|
+
</FocusTrap>
|
|
190
|
+
</div>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
interface IProps extends HTMLAttributes<HTMLButtonElement> {
|
|
195
|
+
actions: ActionMenuOption[]
|
|
196
|
+
menuButtonOptions?: IconButtonMenuProps | ButtonMenuProps
|
|
197
|
+
popupStyle?: React.CSSProperties
|
|
198
|
+
popupPlacement?: 'bottom-start' | 'right-start'
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
interface IconButtonMenuProps {
|
|
202
|
+
type: 'icon'
|
|
203
|
+
iconProps: IconProps
|
|
204
|
+
text?: string
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
interface ButtonMenuProps {
|
|
208
|
+
type: 'button'
|
|
209
|
+
buttonProps: ButtonProps
|
|
210
|
+
text: string
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export interface ActionMenuOption {
|
|
214
|
+
text: string
|
|
215
|
+
clickHandler: () => void
|
|
216
|
+
leftIcon?: IconProps
|
|
217
|
+
rightIcon?: IconProps
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default ActionMenu
|