@spaced-out/ui-design-system 0.1.47 → 0.1.48-beta.1
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/.cspell/custom-words.txt +2 -0
- package/.github/workflows/publish_to_npm.yml +1 -1
- package/CHANGELOG.md +14 -0
- package/design-tokens/color/app-color.json +3 -0
- package/lib/components/Badge/Badge.js +6 -1
- package/lib/components/Badge/Badge.js.flow +10 -0
- package/lib/components/SubMenu/SubMenu.js +18 -156
- package/lib/components/SubMenu/SubMenu.js.flow +37 -239
- package/lib/components/SubMenu/SubMenu.module.css +131 -25
- package/lib/components/SubMenu/SubMenuGroup.js +108 -0
- package/lib/components/SubMenu/SubMenuGroup.js.flow +156 -0
- package/lib/components/SubMenu/SubMenuItem.js +121 -0
- package/lib/components/SubMenu/SubMenuItem.js.flow +170 -0
- package/lib/components/SubMenu/SubMenuLink.js +62 -0
- package/lib/components/SubMenu/SubMenuLink.js.flow +89 -0
- package/lib/components/SubMenu/index.js +41 -34
- package/lib/components/SubMenu/index.js.flow +4 -9
- package/lib/styles/index.css +2 -0
- package/lib/styles/index.js +5 -3
- package/lib/styles/index.js.flow +2 -0
- package/lib/styles/variables/_color.css +2 -0
- package/lib/styles/variables/_color.js +3 -1
- package/lib/styles/variables/_color.js.flow +2 -0
- package/package.json +1 -1
|
@@ -1,20 +1,36 @@
|
|
|
1
|
-
@value ( size34, size60, sizeFluid, sizeFullViewportHeight) from '../../styles/variables/_size.css';
|
|
1
|
+
@value ( size34, size60, size300, sizeFluid, sizeFullViewportHeight) from '../../styles/variables/_size.css';
|
|
2
2
|
|
|
3
3
|
@value (
|
|
4
4
|
colorFillNone,
|
|
5
5
|
colorFillPrimary,
|
|
6
6
|
colorFocusPrimary,
|
|
7
|
+
colorNeutralDark,
|
|
7
8
|
colorNeutralDarkest,
|
|
8
9
|
colorTextInverseSecondary,
|
|
9
10
|
colorTextInversePrimary,
|
|
10
11
|
colorSubMenuBackgroundDefault,
|
|
12
|
+
colorSideMenuIconDefault,
|
|
11
13
|
colorSideMenuIconActive,
|
|
12
14
|
colorSuccess,
|
|
13
15
|
colorFocusDanger
|
|
14
|
-
|
|
15
|
-
@value ( spaceNone, spaceXXSmall, spaceXSmall, spaceSmall, spaceMedium ) from '../../styles/variables/_space.css';
|
|
16
|
+
) from '../../styles/variables/_color.css';
|
|
16
17
|
|
|
17
|
-
@value (
|
|
18
|
+
@value (
|
|
19
|
+
spaceNone,
|
|
20
|
+
spaceXXSmall,
|
|
21
|
+
spaceXSmall,
|
|
22
|
+
spaceSmall,
|
|
23
|
+
spaceMedium,
|
|
24
|
+
spaceLarge
|
|
25
|
+
) from '../../styles/variables/_space.css';
|
|
26
|
+
|
|
27
|
+
@value (
|
|
28
|
+
borderWidthPrimary,
|
|
29
|
+
borderWidthTertiary,
|
|
30
|
+
borderWidthNone,
|
|
31
|
+
borderRadiusSmall,
|
|
32
|
+
borderRadiusNone
|
|
33
|
+
) from '../../styles/variables/_border.css';
|
|
18
34
|
|
|
19
35
|
.subMenuWrapper {
|
|
20
36
|
background: colorSubMenuBackgroundDefault;
|
|
@@ -27,10 +43,19 @@
|
|
|
27
43
|
}
|
|
28
44
|
|
|
29
45
|
.subMenuTitleAndButton {
|
|
46
|
+
height: size60;
|
|
30
47
|
display: flex;
|
|
31
48
|
align-items: center;
|
|
32
49
|
justify-content: space-between;
|
|
33
50
|
border-bottom: borderWidthPrimary solid colorNeutralDarkest;
|
|
51
|
+
margin: spaceNone spaceNone spaceXXSmall spaceXXSmall;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.subMenuTitleWrapper {
|
|
55
|
+
display: flex;
|
|
56
|
+
flex-direction: row;
|
|
57
|
+
align-items: center;
|
|
58
|
+
padding: spaceSmall;
|
|
34
59
|
}
|
|
35
60
|
|
|
36
61
|
.subMenuCloseButton {
|
|
@@ -50,26 +75,34 @@
|
|
|
50
75
|
display: flex;
|
|
51
76
|
flex-direction: row;
|
|
52
77
|
align-items: center;
|
|
53
|
-
padding: spaceMedium;
|
|
78
|
+
padding: spaceMedium spaceXSmall;
|
|
54
79
|
}
|
|
55
80
|
|
|
56
81
|
.menuChildWrap {
|
|
57
82
|
margin: spaceNone spaceSmall;
|
|
58
|
-
border-bottom: borderWidthPrimary solid colorNeutralDarkest;
|
|
59
83
|
}
|
|
60
84
|
|
|
61
85
|
.menuChildWrap:last-child {
|
|
62
86
|
border-bottom: none;
|
|
63
87
|
}
|
|
64
88
|
|
|
65
|
-
.subMenuGroupWrapper
|
|
89
|
+
.subMenuGroupWrapper,
|
|
90
|
+
.subMenuLinkWrapper {
|
|
66
91
|
display: flex;
|
|
67
92
|
flex-direction: column;
|
|
68
|
-
|
|
93
|
+
margin: spaceXXSmall spaceNone;
|
|
69
94
|
flex: auto;
|
|
70
95
|
}
|
|
71
96
|
|
|
72
|
-
.
|
|
97
|
+
.subMenuGroupWrapper {
|
|
98
|
+
background: colorNeutralDarkest;
|
|
99
|
+
border-radius: borderRadiusSmall;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.subMenuGroupHeader,
|
|
103
|
+
.subMenuLink {
|
|
104
|
+
color: colorSideMenuIconDefault;
|
|
105
|
+
background: colorSubMenuBackgroundDefault;
|
|
73
106
|
display: flex;
|
|
74
107
|
flex-direction: row;
|
|
75
108
|
justify-content: space-between;
|
|
@@ -78,24 +111,89 @@
|
|
|
78
111
|
border-radius: borderRadiusSmall;
|
|
79
112
|
}
|
|
80
113
|
|
|
81
|
-
.subMenuGroupHeader:
|
|
114
|
+
.subMenuGroupHeader:hover,
|
|
115
|
+
.subMenuLink:hover {
|
|
116
|
+
background: colorNeutralDarkest;
|
|
117
|
+
.groupTitle,
|
|
118
|
+
.menuLinkTitle {
|
|
119
|
+
color: colorTextInversePrimary;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.subMenuGroupHeader:focus-visible,
|
|
124
|
+
.subMenuGroup:focus-visible,
|
|
125
|
+
.subMenuLink:focus-visible {
|
|
82
126
|
outline: none;
|
|
83
127
|
}
|
|
84
128
|
|
|
85
|
-
.subMenuGroupHeader.collapsible:focus
|
|
129
|
+
.subMenuGroupHeader.collapsible:focus,
|
|
130
|
+
.subMenuLink:focus {
|
|
86
131
|
box-shadow: borderWidthNone borderWidthNone borderWidthNone
|
|
87
132
|
borderWidthTertiary colorFocusPrimary;
|
|
88
133
|
}
|
|
89
134
|
|
|
90
|
-
.
|
|
91
|
-
|
|
135
|
+
.subMenuGroupHeader:not(.collapsible) {
|
|
136
|
+
background: colorNeutralDarkest;
|
|
92
137
|
}
|
|
93
138
|
|
|
94
|
-
.
|
|
139
|
+
.subMenuGroupHeader.collapsed,
|
|
140
|
+
.subMenuLink.collapsed {
|
|
141
|
+
background: colorNeutralDarkest;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.subMenuGroupHeader.highlightedMenu {
|
|
145
|
+
border: borderWidthPrimary solid colorNeutralDark;
|
|
146
|
+
margin: calc(-1 * (borderWidthPrimary));
|
|
147
|
+
.groupTitle {
|
|
148
|
+
color: colorTextInversePrimary;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.subMenuLink.highlightedMenu {
|
|
153
|
+
background: colorNeutralDarkest;
|
|
154
|
+
.menuLinkTitle {
|
|
155
|
+
color: colorTextInversePrimary;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.groupTitleWrapper {
|
|
160
|
+
display: flex;
|
|
161
|
+
gap: spaceXXSmall;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.groupIconWrapper {
|
|
165
|
+
display: flex;
|
|
166
|
+
position: relative;
|
|
167
|
+
padding-right: spaceXSmall;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.statusIndicatorWrapper {
|
|
171
|
+
position: absolute;
|
|
172
|
+
top: calc(-1 * (spaceXXSmall));
|
|
173
|
+
right: spaceNone;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.groupTitle,
|
|
177
|
+
.menuLinkTitle {
|
|
178
|
+
color: colorTextInverseSecondary;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.menuLinkIcon {
|
|
182
|
+
margin-right: spaceXSmall;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.subMenuGroup,
|
|
186
|
+
.subMenuFocusWrapper {
|
|
187
|
+
outline: none;
|
|
95
188
|
display: flex;
|
|
96
189
|
flex-direction: column;
|
|
97
|
-
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.subMenuGroup {
|
|
193
|
+
margin: spaceXSmall spaceXXSmall;
|
|
98
194
|
gap: spaceXXSmall;
|
|
195
|
+
background: colorNeutralDarkest;
|
|
196
|
+
border-radius: borderRadiusSmall;
|
|
99
197
|
}
|
|
100
198
|
|
|
101
199
|
.subMenuGroup.collapsed {
|
|
@@ -105,19 +203,18 @@
|
|
|
105
203
|
.menuItem {
|
|
106
204
|
display: flex;
|
|
107
205
|
flex-direction: row;
|
|
108
|
-
background: colorSubMenuBackgroundDefault;
|
|
109
206
|
color: colorTextInverseSecondary;
|
|
110
207
|
flex-direction: row;
|
|
111
|
-
gap: spaceXSmall;
|
|
112
208
|
justify-content: space-between;
|
|
209
|
+
gap: spaceXSmall;
|
|
113
210
|
align-items: center;
|
|
114
211
|
flex: auto;
|
|
115
212
|
height: size34;
|
|
116
213
|
min-height: size34;
|
|
117
214
|
border-radius: borderRadiusSmall;
|
|
118
|
-
width: sizeFluid;
|
|
119
215
|
cursor: pointer;
|
|
120
|
-
padding:
|
|
216
|
+
padding: spaceXXSmall;
|
|
217
|
+
margin: spaceXXSmall;
|
|
121
218
|
box-sizing: border-box;
|
|
122
219
|
}
|
|
123
220
|
|
|
@@ -130,7 +227,6 @@
|
|
|
130
227
|
}
|
|
131
228
|
|
|
132
229
|
.menuItem:focus {
|
|
133
|
-
background: colorNeutralDarkest;
|
|
134
230
|
box-shadow: borderWidthNone borderWidthNone borderWidthNone
|
|
135
231
|
borderWidthTertiary colorFocusPrimary;
|
|
136
232
|
}
|
|
@@ -140,10 +236,18 @@
|
|
|
140
236
|
}
|
|
141
237
|
|
|
142
238
|
.menuItem.selected {
|
|
143
|
-
background: colorNeutralDarkest;
|
|
144
239
|
color: colorTextInversePrimary;
|
|
145
240
|
}
|
|
146
241
|
|
|
242
|
+
.menuItem.selected::before {
|
|
243
|
+
position: absolute;
|
|
244
|
+
content: '';
|
|
245
|
+
border-radius: borderRadiusSmall;
|
|
246
|
+
background-color: colorFillPrimary;
|
|
247
|
+
width: spaceXXSmall;
|
|
248
|
+
height: spaceMedium;
|
|
249
|
+
}
|
|
250
|
+
|
|
147
251
|
.menuItem.disabled {
|
|
148
252
|
pointer-events: none;
|
|
149
253
|
}
|
|
@@ -151,15 +255,17 @@
|
|
|
151
255
|
.menuIconName {
|
|
152
256
|
display: flex;
|
|
153
257
|
flex-direction: row;
|
|
154
|
-
|
|
258
|
+
align-items: center;
|
|
259
|
+
gap: spaceXXSmall;
|
|
260
|
+
padding-left: spaceSmall;
|
|
261
|
+
margin-left: spaceXXSmall;
|
|
155
262
|
}
|
|
156
263
|
|
|
157
264
|
.subMenuItemText {
|
|
158
265
|
color: inherit;
|
|
159
|
-
margin-right: spaceSmall;
|
|
160
266
|
}
|
|
161
267
|
|
|
162
|
-
.
|
|
268
|
+
.subMenuItemBadges {
|
|
163
269
|
display: flex;
|
|
164
|
-
|
|
270
|
+
align-items: center;
|
|
165
271
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SubMenuGroup = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
9
|
+
var _FocusManagerWithArrowKeyNavigation = require("../FocusManagerWithArrowKeyNavigation");
|
|
10
|
+
var _Icon = require("../Icon");
|
|
11
|
+
var _StatusIndicator = require("../StatusIndicator");
|
|
12
|
+
var _Text = require("../Text");
|
|
13
|
+
var _SubMenuModule = _interopRequireDefault(require("./SubMenu.module.css"));
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
16
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
17
|
+
|
|
18
|
+
const SubMenuGroup = _ref => {
|
|
19
|
+
let {
|
|
20
|
+
children,
|
|
21
|
+
groupTitle,
|
|
22
|
+
groupIcon,
|
|
23
|
+
groupIconSize,
|
|
24
|
+
groupIconType,
|
|
25
|
+
collapsible = false,
|
|
26
|
+
disabled = false,
|
|
27
|
+
onChange,
|
|
28
|
+
selectedMenuKey,
|
|
29
|
+
status,
|
|
30
|
+
classNames
|
|
31
|
+
} = _ref;
|
|
32
|
+
const isSubMenuGroupChildSelected = React.Children.toArray(children).some(child => child.props.menuKey === selectedMenuKey);
|
|
33
|
+
const [collapsed, setCollapsed] = React.useState(!isSubMenuGroupChildSelected);
|
|
34
|
+
const collapseHandler = () => {
|
|
35
|
+
collapsible && setCollapsed(!collapsed);
|
|
36
|
+
};
|
|
37
|
+
const onMenuItemChangeHandler = value => {
|
|
38
|
+
onChange && onChange(value);
|
|
39
|
+
};
|
|
40
|
+
const onKeyDownHandlerHeader = e => {
|
|
41
|
+
if (e.key === 'Enter') {
|
|
42
|
+
collapseHandler();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const childrenWithProps = React.Children.map(children, child => {
|
|
46
|
+
if ( /*#__PURE__*/React.isValidElement(child)) {
|
|
47
|
+
const {
|
|
48
|
+
disabled: disabledChild
|
|
49
|
+
} = child.props;
|
|
50
|
+
return /*#__PURE__*/React.cloneElement(child, {
|
|
51
|
+
selectedMenuKey,
|
|
52
|
+
onChange: onMenuItemChangeHandler,
|
|
53
|
+
disabled: disabledChild || disabled
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return child;
|
|
57
|
+
});
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
setCollapsed(!isSubMenuGroupChildSelected);
|
|
60
|
+
}, [selectedMenuKey]);
|
|
61
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
className: (0, _classify.default)(_SubMenuModule.default.subMenuGroupWrapper, classNames?.wrapper)
|
|
63
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
64
|
+
className: (0, _classify.default)(_SubMenuModule.default.subMenuGroupHeader, {
|
|
65
|
+
[_SubMenuModule.default.collapsible]: collapsible
|
|
66
|
+
}, {
|
|
67
|
+
[_SubMenuModule.default.highlightedMenu]: isSubMenuGroupChildSelected
|
|
68
|
+
}, {
|
|
69
|
+
[_SubMenuModule.default.collapsed]: !collapsed
|
|
70
|
+
}, classNames?.groupHeader),
|
|
71
|
+
onClick: collapseHandler,
|
|
72
|
+
onKeyDown: onKeyDownHandlerHeader,
|
|
73
|
+
tabIndex: disabled ? '-1' : 0
|
|
74
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
75
|
+
className: _SubMenuModule.default.groupTitleWrapper
|
|
76
|
+
}, (!!groupIcon || !!status) && /*#__PURE__*/React.createElement("div", {
|
|
77
|
+
className: _SubMenuModule.default.groupIconWrapper
|
|
78
|
+
}, !!groupIcon && /*#__PURE__*/React.createElement(_Icon.Icon, {
|
|
79
|
+
color: _Text.TEXT_COLORS.inverseSecondary,
|
|
80
|
+
name: groupIcon,
|
|
81
|
+
type: groupIconType,
|
|
82
|
+
size: groupIconSize,
|
|
83
|
+
className: _SubMenuModule.default.groupIcon
|
|
84
|
+
}), !!status && collapsed && /*#__PURE__*/React.createElement("div", {
|
|
85
|
+
className: (0, _classify.default)(_SubMenuModule.default.statusIndicatorWrapper)
|
|
86
|
+
}, /*#__PURE__*/React.createElement(_StatusIndicator.StatusIndicator, {
|
|
87
|
+
status: status,
|
|
88
|
+
className: _SubMenuModule.default.statusIndicatorWrapper
|
|
89
|
+
}))), /*#__PURE__*/React.createElement(_Text.ButtonTextMedium, {
|
|
90
|
+
color: _Text.TEXT_COLORS.inverseSecondary,
|
|
91
|
+
className: _SubMenuModule.default.groupTitle
|
|
92
|
+
}, groupTitle)), collapsible && /*#__PURE__*/React.createElement(_Icon.Icon, {
|
|
93
|
+
color: _Text.TEXT_COLORS.inverseSecondary,
|
|
94
|
+
name: collapsed ? 'chevron-down' : 'chevron-up',
|
|
95
|
+
size: "small"
|
|
96
|
+
})), /*#__PURE__*/React.createElement("div", {
|
|
97
|
+
className: (0, _classify.default)(_SubMenuModule.default.subMenuGroup, {
|
|
98
|
+
[_SubMenuModule.default.collapsed]: collapsible && collapsed
|
|
99
|
+
}, classNames?.menuGroup)
|
|
100
|
+
}, /*#__PURE__*/React.createElement(_FocusManagerWithArrowKeyNavigation.FocusManagerWithArrowKeyNavigation, {
|
|
101
|
+
classNames: {
|
|
102
|
+
wrapper: (0, _classify.default)(_SubMenuModule.default.subMenuFocusWrapper)
|
|
103
|
+
},
|
|
104
|
+
focusItemOnOpen: true,
|
|
105
|
+
loop: true
|
|
106
|
+
}, childrenWithProps)));
|
|
107
|
+
};
|
|
108
|
+
exports.SubMenuGroup = SubMenuGroup;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
//@flow strict
|
|
2
|
+
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
import classify from '../../utils/classify';
|
|
6
|
+
import {FocusManagerWithArrowKeyNavigation} from '../FocusManagerWithArrowKeyNavigation';
|
|
7
|
+
import type {IconSize, IconType} from '../Icon';
|
|
8
|
+
import {Icon} from '../Icon';
|
|
9
|
+
import type {StatusSemanticType} from '../StatusIndicator';
|
|
10
|
+
import {StatusIndicator} from '../StatusIndicator';
|
|
11
|
+
import {ButtonTextMedium, TEXT_COLORS} from '../Text';
|
|
12
|
+
|
|
13
|
+
import css from './SubMenu.module.css';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
type ClassNames = $ReadOnly<{
|
|
17
|
+
wrapper?: string,
|
|
18
|
+
groupHeader?: string,
|
|
19
|
+
menuGroup?: string,
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
export type SubMenuGroupProps = {
|
|
23
|
+
children?: React.Node,
|
|
24
|
+
groupTitle?: string,
|
|
25
|
+
groupIcon?: string,
|
|
26
|
+
groupIconSize?: IconSize,
|
|
27
|
+
groupIconType?: IconType,
|
|
28
|
+
collapsible?: boolean,
|
|
29
|
+
disabled?: boolean,
|
|
30
|
+
onChange?: (value: string) => mixed,
|
|
31
|
+
selectedMenuKey?: string,
|
|
32
|
+
status?: StatusSemanticType,
|
|
33
|
+
classNames?: ClassNames,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export const SubMenuGroup = ({
|
|
37
|
+
children,
|
|
38
|
+
groupTitle,
|
|
39
|
+
groupIcon,
|
|
40
|
+
groupIconSize,
|
|
41
|
+
groupIconType,
|
|
42
|
+
collapsible = false,
|
|
43
|
+
disabled = false,
|
|
44
|
+
onChange,
|
|
45
|
+
selectedMenuKey,
|
|
46
|
+
status,
|
|
47
|
+
classNames,
|
|
48
|
+
}: SubMenuGroupProps): React.Node => {
|
|
49
|
+
const isSubMenuGroupChildSelected = React.Children.toArray(children).some(
|
|
50
|
+
(child) => child.props.menuKey === selectedMenuKey,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const [collapsed, setCollapsed] = React.useState(
|
|
54
|
+
!isSubMenuGroupChildSelected,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const collapseHandler = () => {
|
|
58
|
+
collapsible && setCollapsed(!collapsed);
|
|
59
|
+
};
|
|
60
|
+
const onMenuItemChangeHandler = (value) => {
|
|
61
|
+
onChange && onChange(value);
|
|
62
|
+
};
|
|
63
|
+
const onKeyDownHandlerHeader = (e) => {
|
|
64
|
+
if (e.key === 'Enter') {
|
|
65
|
+
collapseHandler();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const childrenWithProps = React.Children.map(children, (child) => {
|
|
69
|
+
if (React.isValidElement(child)) {
|
|
70
|
+
const {disabled: disabledChild} = child.props;
|
|
71
|
+
return React.cloneElement(child, {
|
|
72
|
+
selectedMenuKey,
|
|
73
|
+
onChange: onMenuItemChangeHandler,
|
|
74
|
+
disabled: disabledChild || disabled,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return child;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
setCollapsed(!isSubMenuGroupChildSelected);
|
|
82
|
+
}, [selectedMenuKey]);
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<div className={classify(css.subMenuGroupWrapper, classNames?.wrapper)}>
|
|
86
|
+
<div
|
|
87
|
+
className={classify(
|
|
88
|
+
css.subMenuGroupHeader,
|
|
89
|
+
{[css.collapsible]: collapsible},
|
|
90
|
+
{[css.highlightedMenu]: isSubMenuGroupChildSelected},
|
|
91
|
+
{[css.collapsed]: !collapsed},
|
|
92
|
+
classNames?.groupHeader,
|
|
93
|
+
)}
|
|
94
|
+
onClick={collapseHandler}
|
|
95
|
+
onKeyDown={onKeyDownHandlerHeader}
|
|
96
|
+
tabIndex={disabled ? '-1' : 0}
|
|
97
|
+
>
|
|
98
|
+
<div className={css.groupTitleWrapper}>
|
|
99
|
+
{(!!groupIcon || !!status) && (
|
|
100
|
+
<div className={css.groupIconWrapper}>
|
|
101
|
+
{!!groupIcon && (
|
|
102
|
+
<Icon
|
|
103
|
+
color={TEXT_COLORS.inverseSecondary}
|
|
104
|
+
name={groupIcon}
|
|
105
|
+
type={groupIconType}
|
|
106
|
+
size={groupIconSize}
|
|
107
|
+
className={css.groupIcon}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
110
|
+
{!!status && collapsed && (
|
|
111
|
+
<div className={classify(css.statusIndicatorWrapper)}>
|
|
112
|
+
<StatusIndicator
|
|
113
|
+
status={status}
|
|
114
|
+
className={css.statusIndicatorWrapper}
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
)}
|
|
118
|
+
</div>
|
|
119
|
+
)}
|
|
120
|
+
<ButtonTextMedium
|
|
121
|
+
color={TEXT_COLORS.inverseSecondary}
|
|
122
|
+
className={css.groupTitle}
|
|
123
|
+
>
|
|
124
|
+
{groupTitle}
|
|
125
|
+
</ButtonTextMedium>
|
|
126
|
+
</div>
|
|
127
|
+
{collapsible && (
|
|
128
|
+
<Icon
|
|
129
|
+
color={TEXT_COLORS.inverseSecondary}
|
|
130
|
+
name={collapsed ? 'chevron-down' : 'chevron-up'}
|
|
131
|
+
size="small"
|
|
132
|
+
/>
|
|
133
|
+
)}
|
|
134
|
+
</div>
|
|
135
|
+
<div
|
|
136
|
+
className={classify(
|
|
137
|
+
css.subMenuGroup,
|
|
138
|
+
{
|
|
139
|
+
[css.collapsed]: collapsible && collapsed,
|
|
140
|
+
},
|
|
141
|
+
classNames?.menuGroup,
|
|
142
|
+
)}
|
|
143
|
+
>
|
|
144
|
+
<FocusManagerWithArrowKeyNavigation
|
|
145
|
+
classNames={{
|
|
146
|
+
wrapper: classify(css.subMenuFocusWrapper),
|
|
147
|
+
}}
|
|
148
|
+
focusItemOnOpen={true}
|
|
149
|
+
loop={true}
|
|
150
|
+
>
|
|
151
|
+
{childrenWithProps}
|
|
152
|
+
</FocusManagerWithArrowKeyNavigation>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SubMenuItemText = exports.SubMenuItemIcon = exports.SubMenuItemBadges = exports.SubMenuItemAction = exports.SubMenuItem = void 0;
|
|
7
|
+
var React = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _classify = _interopRequireDefault(require("../../utils/classify"));
|
|
9
|
+
var _Icon = require("../Icon");
|
|
10
|
+
var _Text = require("../Text");
|
|
11
|
+
var _Truncate = require("../Truncate");
|
|
12
|
+
var _SubMenuModule = _interopRequireDefault(require("./SubMenu.module.css"));
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
15
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
16
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
17
|
+
const SubMenuItemIcon = _ref => {
|
|
18
|
+
let {
|
|
19
|
+
className,
|
|
20
|
+
...props
|
|
21
|
+
} = _ref;
|
|
22
|
+
return /*#__PURE__*/React.createElement(_Icon.Icon, _extends({}, props, {
|
|
23
|
+
size: "small",
|
|
24
|
+
color: _Text.TEXT_COLORS.inverseSecondary,
|
|
25
|
+
className: (0, _classify.default)(_SubMenuModule.default.menuIcon, className)
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
28
|
+
exports.SubMenuItemIcon = SubMenuItemIcon;
|
|
29
|
+
SubMenuItemIcon.displayName = 'SubMenuItemIcon';
|
|
30
|
+
const SubMenuItemText = _ref2 => {
|
|
31
|
+
let {
|
|
32
|
+
children,
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
} = _ref2;
|
|
36
|
+
return /*#__PURE__*/React.createElement(_Text.ButtonTextMedium, _extends({}, props, {
|
|
37
|
+
className: (0, _classify.default)(_SubMenuModule.default.subMenuItemText, className),
|
|
38
|
+
color: _Text.TEXT_COLORS.inversePrimary
|
|
39
|
+
}), /*#__PURE__*/React.createElement(_Truncate.Truncate, {
|
|
40
|
+
showFullTextOnHover: true
|
|
41
|
+
}, children));
|
|
42
|
+
};
|
|
43
|
+
exports.SubMenuItemText = SubMenuItemText;
|
|
44
|
+
SubMenuItemText.displayName = 'SubMenuItemText';
|
|
45
|
+
const SubMenuItemBadges = _ref3 => {
|
|
46
|
+
let {
|
|
47
|
+
children,
|
|
48
|
+
className,
|
|
49
|
+
...props
|
|
50
|
+
} = _ref3;
|
|
51
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, props, {
|
|
52
|
+
className: (0, _classify.default)(_SubMenuModule.default.subMenuItemBadges, className)
|
|
53
|
+
}), children);
|
|
54
|
+
};
|
|
55
|
+
exports.SubMenuItemBadges = SubMenuItemBadges;
|
|
56
|
+
SubMenuItemBadges.displayName = 'SubMenuItemBadges';
|
|
57
|
+
const SubMenuItemAction = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
58
|
+
let {
|
|
59
|
+
children,
|
|
60
|
+
className,
|
|
61
|
+
...props
|
|
62
|
+
} = _ref4;
|
|
63
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, props, {
|
|
64
|
+
className: (0, _classify.default)(_SubMenuModule.default.actionItems, className),
|
|
65
|
+
ref: ref
|
|
66
|
+
}), children);
|
|
67
|
+
});
|
|
68
|
+
exports.SubMenuItemAction = SubMenuItemAction;
|
|
69
|
+
SubMenuItemAction.displayName = 'SubMenuItemAction';
|
|
70
|
+
const SubMenuItem = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
|
|
71
|
+
let {
|
|
72
|
+
children,
|
|
73
|
+
selectedMenuKey,
|
|
74
|
+
disabled,
|
|
75
|
+
classNames,
|
|
76
|
+
onChange,
|
|
77
|
+
menuKey,
|
|
78
|
+
...props
|
|
79
|
+
} = _ref5;
|
|
80
|
+
const onChangeHandler = () => {
|
|
81
|
+
if (!disabled) {
|
|
82
|
+
onChange?.(menuKey);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const onKeyDownHandler = e => {
|
|
86
|
+
if (e.key === 'Enter') {
|
|
87
|
+
onChangeHandler();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
const selected = selectedMenuKey === menuKey;
|
|
91
|
+
const getNamedComp = comp => {
|
|
92
|
+
const childrenArray = React.Children.toArray(children);
|
|
93
|
+
if (childrenArray.length) {
|
|
94
|
+
const nodes = [];
|
|
95
|
+
for (const child of childrenArray) {
|
|
96
|
+
if (child?.type?.displayName === comp) {
|
|
97
|
+
nodes.push( /*#__PURE__*/React.cloneElement(child, {
|
|
98
|
+
selected,
|
|
99
|
+
disabled
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return nodes.length > 1 ? nodes : nodes[0];
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, props, {
|
|
108
|
+
className: (0, _classify.default)(_SubMenuModule.default.menuItem, {
|
|
109
|
+
[_SubMenuModule.default.selected]: selected,
|
|
110
|
+
[_SubMenuModule.default.disabled]: disabled
|
|
111
|
+
}, classNames?.wrapper),
|
|
112
|
+
onKeyDown: onKeyDownHandler,
|
|
113
|
+
onClick: onChangeHandler,
|
|
114
|
+
tabIndex: disabled ? '-1' : 0,
|
|
115
|
+
disabled: disabled,
|
|
116
|
+
ref: ref
|
|
117
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
118
|
+
className: _SubMenuModule.default.menuIconName
|
|
119
|
+
}, getNamedComp('SubMenuItemIcon'), getNamedComp('SubMenuItemText'), getNamedComp('SubMenuItemBadges')), getNamedComp('SubMenuItemAction'));
|
|
120
|
+
});
|
|
121
|
+
exports.SubMenuItem = SubMenuItem;
|