@patternfly/react-core 4.266.3 → 4.267.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/CHANGELOG.md +19 -0
- package/dist/esm/components/Menu/Menu.d.ts +1 -0
- package/dist/esm/components/Menu/Menu.d.ts.map +1 -1
- package/dist/esm/components/Menu/Menu.js +17 -4
- package/dist/esm/components/Menu/Menu.js.map +1 -1
- package/dist/js/components/Menu/Menu.d.ts +1 -0
- package/dist/js/components/Menu/Menu.d.ts.map +1 -1
- package/dist/js/components/Menu/Menu.js +17 -4
- package/dist/js/components/Menu/Menu.js.map +1 -1
- package/dist/umd/react-core.min.js +1 -1
- package/package.json +6 -6
- package/src/components/Menu/Menu.tsx +20 -4
- package/src/components/Menu/examples/Menu.md +5 -0
- package/src/components/Menu/examples/MenuFilterDrilldown.tsx +123 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.267.1",
|
|
4
4
|
"description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -51,16 +51,16 @@
|
|
|
51
51
|
"generate": "node scripts/copyStyles.js"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@patternfly/react-icons": "^4.93.
|
|
55
|
-
"@patternfly/react-styles": "^4.92.
|
|
56
|
-
"@patternfly/react-tokens": "^4.94.
|
|
54
|
+
"@patternfly/react-icons": "^4.93.3",
|
|
55
|
+
"@patternfly/react-styles": "^4.92.3",
|
|
56
|
+
"@patternfly/react-tokens": "^4.94.3",
|
|
57
57
|
"focus-trap": "6.9.2",
|
|
58
58
|
"react-dropzone": "9.0.0",
|
|
59
59
|
"tippy.js": "5.1.2",
|
|
60
60
|
"tslib": "^2.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@patternfly/patternfly": "4.222.
|
|
63
|
+
"@patternfly/patternfly": "4.222.4",
|
|
64
64
|
"@rollup/plugin-commonjs": "^21.0.0",
|
|
65
65
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
66
66
|
"@rollup/plugin-replace": "^3.0.0",
|
|
@@ -77,5 +77,5 @@
|
|
|
77
77
|
"react": "^16.8 || ^17 || ^18",
|
|
78
78
|
"react-dom": "^16.8 || ^17 || ^18"
|
|
79
79
|
},
|
|
80
|
-
"gitHead": "
|
|
80
|
+
"gitHead": "67e1ec39d3b8a95bd7e2092bb1c1b788a66ffe5f"
|
|
81
81
|
}
|
|
@@ -71,6 +71,7 @@ export interface MenuState {
|
|
|
71
71
|
transitionMoveTarget: HTMLElement;
|
|
72
72
|
flyoutRef: React.Ref<HTMLLIElement> | null;
|
|
73
73
|
disableHover: boolean;
|
|
74
|
+
currentDrilldownMenuId: string;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
class MenuBase extends React.Component<MenuProps, MenuState> {
|
|
@@ -98,7 +99,8 @@ class MenuBase extends React.Component<MenuProps, MenuState> {
|
|
|
98
99
|
searchInputValue: '',
|
|
99
100
|
transitionMoveTarget: null,
|
|
100
101
|
flyoutRef: null,
|
|
101
|
-
disableHover: false
|
|
102
|
+
disableHover: false,
|
|
103
|
+
currentDrilldownMenuId: this.props.id
|
|
102
104
|
};
|
|
103
105
|
|
|
104
106
|
allowTabFirstItem() {
|
|
@@ -155,9 +157,19 @@ class MenuBase extends React.Component<MenuProps, MenuState> {
|
|
|
155
157
|
this.setState({ transitionMoveTarget: null });
|
|
156
158
|
} else {
|
|
157
159
|
const nextMenu = current.querySelector('#' + this.props.activeMenu) || current || null;
|
|
158
|
-
const
|
|
160
|
+
const nextMenuChildren = Array.from(nextMenu.getElementsByTagName('UL')[0].children);
|
|
161
|
+
|
|
162
|
+
if (!this.state.currentDrilldownMenuId || nextMenu.id !== this.state.currentDrilldownMenuId) {
|
|
163
|
+
this.setState({ currentDrilldownMenuId: nextMenu.id });
|
|
164
|
+
} else {
|
|
165
|
+
// if the drilldown transition ends on the same menu, do not focus the first item
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const nextTarget = nextMenuChildren.filter(
|
|
159
170
|
el => !(el.classList.contains('pf-m-disabled') || el.classList.contains('pf-c-divider'))
|
|
160
171
|
)[0].firstChild;
|
|
172
|
+
|
|
161
173
|
(nextTarget as HTMLElement).focus();
|
|
162
174
|
(nextTarget as HTMLElement).tabIndex = 0;
|
|
163
175
|
}
|
|
@@ -284,12 +296,16 @@ class MenuBase extends React.Component<MenuProps, MenuState> {
|
|
|
284
296
|
additionalKeyHandler={this.handleExtraKeys}
|
|
285
297
|
createNavigableElements={this.createNavigableElements}
|
|
286
298
|
isActiveElement={(element: Element) =>
|
|
287
|
-
document.activeElement.closest('li') === element ||
|
|
299
|
+
document.activeElement.closest('li') === element || // if element is a basic MenuItem
|
|
288
300
|
document.activeElement.parentElement === element ||
|
|
301
|
+
document.activeElement.closest('.pf-c-menu__search') === element || // if element is a MenuInput
|
|
289
302
|
(document.activeElement.closest('ol') && document.activeElement.closest('ol').firstChild === element)
|
|
290
303
|
}
|
|
291
304
|
getFocusableElement={(navigableElement: Element) =>
|
|
292
|
-
navigableElement.querySelector('input') ||
|
|
305
|
+
(navigableElement.tagName === 'DIV' && navigableElement.querySelector('input')) || // for MenuInput
|
|
306
|
+
((navigableElement.firstChild as Element).tagName === 'LABEL' &&
|
|
307
|
+
navigableElement.querySelector('input')) || // for MenuItem checkboxes
|
|
308
|
+
(navigableElement.firstChild as Element)
|
|
293
309
|
}
|
|
294
310
|
noHorizontalArrowHandling={
|
|
295
311
|
document.activeElement &&
|
|
@@ -105,6 +105,11 @@ To render an initially drilled in menu, the `menuDrilledIn`, `drilldownPath`, an
|
|
|
105
105
|
```ts file="MenuWithDrilldownBreadcrumbs.tsx" isBeta
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### With drilldown and inline filter
|
|
109
|
+
|
|
110
|
+
```ts file="MenuFilterDrilldown.tsx"
|
|
111
|
+
```
|
|
112
|
+
|
|
108
113
|
### Scrollable
|
|
109
114
|
|
|
110
115
|
```ts file="MenuScrollable.tsx"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Menu,
|
|
4
|
+
MenuContent,
|
|
5
|
+
MenuList,
|
|
6
|
+
MenuItem,
|
|
7
|
+
Divider,
|
|
8
|
+
DrilldownMenu,
|
|
9
|
+
MenuInput,
|
|
10
|
+
SearchInput
|
|
11
|
+
} from '@patternfly/react-core';
|
|
12
|
+
|
|
13
|
+
export const MenuWithDrilldown: React.FunctionComponent = () => {
|
|
14
|
+
const [menuDrilledIn, setMenuDrilledIn] = React.useState<string[]>([]);
|
|
15
|
+
const [drilldownPath, setDrilldownPath] = React.useState<string[]>([]);
|
|
16
|
+
const [menuHeights, setMenuHeights] = React.useState<any>({});
|
|
17
|
+
const [activeMenu, setActiveMenu] = React.useState<string>('filter_drilldown-rootMenu');
|
|
18
|
+
|
|
19
|
+
const drillIn = (fromMenuId: string, toMenuId: string, pathId: string) => {
|
|
20
|
+
setMenuDrilledIn([...menuDrilledIn, fromMenuId]);
|
|
21
|
+
setDrilldownPath([...drilldownPath, pathId]);
|
|
22
|
+
setActiveMenu(toMenuId);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const drillOut = (toMenuId: string) => {
|
|
26
|
+
const menuDrilledInSansLast = menuDrilledIn.slice(0, menuDrilledIn.length - 1);
|
|
27
|
+
const pathSansLast = drilldownPath.slice(0, drilldownPath.length - 1);
|
|
28
|
+
setMenuDrilledIn(menuDrilledInSansLast);
|
|
29
|
+
setDrilldownPath(pathSansLast);
|
|
30
|
+
setActiveMenu(toMenuId);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const setHeight = (menuId: string, height: number) => {
|
|
34
|
+
if (
|
|
35
|
+
menuHeights[menuId] === undefined ||
|
|
36
|
+
(menuId !== 'filter_drilldown-rootMenu' && menuHeights[menuId] !== height)
|
|
37
|
+
) {
|
|
38
|
+
setMenuHeights({ ...menuHeights, [menuId]: height });
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const searchRef = React.createRef<HTMLInputElement>();
|
|
43
|
+
const [startInput, setStartInput] = React.useState('');
|
|
44
|
+
|
|
45
|
+
const handleStartTextInputChange = (value: string) => {
|
|
46
|
+
setStartInput(value);
|
|
47
|
+
searchRef?.current?.focus();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const startDrillItems = [
|
|
51
|
+
{
|
|
52
|
+
item: 'Application grouping',
|
|
53
|
+
rest: { description: 'Description text' }
|
|
54
|
+
},
|
|
55
|
+
{ item: 'Labels' },
|
|
56
|
+
{ item: 'Annotations' },
|
|
57
|
+
{ item: 'Count' },
|
|
58
|
+
{ item: 'Count 2' },
|
|
59
|
+
{ item: 'Count 3' },
|
|
60
|
+
{ item: 'Other' }
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
const mapped = startDrillItems
|
|
64
|
+
.filter(opt => !startInput || opt.item.toLowerCase().includes(startInput.toString().toLowerCase()))
|
|
65
|
+
.map((opt, index) => (
|
|
66
|
+
<MenuItem key={opt.item} itemId={index} {...opt.rest}>
|
|
67
|
+
{opt.item}
|
|
68
|
+
</MenuItem>
|
|
69
|
+
));
|
|
70
|
+
if (startInput && mapped.length === 0) {
|
|
71
|
+
mapped.push(
|
|
72
|
+
<MenuItem isDisabled key="no result">
|
|
73
|
+
No results found
|
|
74
|
+
</MenuItem>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Menu
|
|
80
|
+
id="filter_drilldown-rootMenu"
|
|
81
|
+
containsDrilldown
|
|
82
|
+
drilldownItemPath={drilldownPath}
|
|
83
|
+
drilledInMenus={menuDrilledIn}
|
|
84
|
+
activeMenu={activeMenu}
|
|
85
|
+
onDrillIn={drillIn}
|
|
86
|
+
onDrillOut={drillOut}
|
|
87
|
+
onGetMenuHeight={setHeight}
|
|
88
|
+
>
|
|
89
|
+
<MenuContent menuHeight={`${menuHeights[activeMenu]}px`}>
|
|
90
|
+
<MenuList>
|
|
91
|
+
<MenuItem
|
|
92
|
+
itemId="filter_group:start_rollout"
|
|
93
|
+
direction="down"
|
|
94
|
+
drilldownMenu={
|
|
95
|
+
<DrilldownMenu id="filter_drilldown-drilldownMenuStart">
|
|
96
|
+
<MenuItem itemId="filter_group:start_rollout_breadcrumb" direction="up">
|
|
97
|
+
Start rollout
|
|
98
|
+
</MenuItem>
|
|
99
|
+
<Divider component="li" />
|
|
100
|
+
<MenuInput>
|
|
101
|
+
<SearchInput
|
|
102
|
+
ref={searchRef}
|
|
103
|
+
value={startInput}
|
|
104
|
+
aria-label="Filter menu items"
|
|
105
|
+
type="search"
|
|
106
|
+
onChange={value => handleStartTextInputChange(value)}
|
|
107
|
+
/>
|
|
108
|
+
</MenuInput>
|
|
109
|
+
<Divider component="li" />
|
|
110
|
+
{mapped}
|
|
111
|
+
</DrilldownMenu>
|
|
112
|
+
}
|
|
113
|
+
>
|
|
114
|
+
Start rollout
|
|
115
|
+
</MenuItem>
|
|
116
|
+
<MenuItem itemId="item-a">Item B</MenuItem>
|
|
117
|
+
<MenuItem itemId="item-b">Item C</MenuItem>
|
|
118
|
+
<MenuItem itemId="item-c">Item D</MenuItem>
|
|
119
|
+
</MenuList>
|
|
120
|
+
</MenuContent>
|
|
121
|
+
</Menu>
|
|
122
|
+
);
|
|
123
|
+
};
|