@patternfly/react-table 5.3.0-prerelease.2 → 5.3.0-prerelease.20
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 +78 -0
- package/components/package.json +1 -1
- package/deprecated/package.json +1 -1
- package/dist/dynamic/components/Table/package.json +1 -1
- package/dist/dynamic/components/Table/utils/decorators/package.json +1 -1
- package/dist/dynamic/components/Table/utils/package.json +1 -1
- package/dist/dynamic/deprecated/components/Table/base/package.json +1 -1
- package/dist/dynamic/deprecated/components/Table/package.json +1 -1
- package/dist/dynamic/deprecated/components/package.json +1 -1
- package/dist/esm/components/Table/ActionsColumn.d.ts +2 -0
- package/dist/esm/components/Table/ActionsColumn.d.ts.map +1 -1
- package/dist/esm/components/Table/ActionsColumn.js +4 -4
- package/dist/esm/components/Table/ActionsColumn.js.map +1 -1
- package/dist/esm/components/Table/TableTypes.d.ts +2 -0
- package/dist/esm/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/esm/components/Table/Th.d.ts +8 -0
- package/dist/esm/components/Table/Th.d.ts.map +1 -1
- package/dist/esm/components/Table/Th.js +7 -3
- package/dist/esm/components/Table/Th.js.map +1 -1
- package/dist/esm/components/Table/utils/decorators/selectable.js +1 -1
- package/dist/esm/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/esm/demos/DashboardHeader.d.ts +8 -0
- package/dist/esm/demos/DashboardHeader.d.ts.map +1 -0
- package/dist/esm/demos/DashboardHeader.js +77 -0
- package/dist/esm/demos/DashboardHeader.js.map +1 -0
- package/dist/esm/demos/DashboardWrapper.d.ts +85 -0
- package/dist/esm/demos/DashboardWrapper.d.ts.map +1 -0
- package/dist/esm/demos/DashboardWrapper.js +41 -0
- package/dist/esm/demos/DashboardWrapper.js.map +1 -0
- package/dist/esm/demos/index.d.ts +2 -0
- package/dist/esm/demos/index.d.ts.map +1 -1
- package/dist/esm/demos/index.js +2 -0
- package/dist/esm/demos/index.js.map +1 -1
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +0 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/js/components/Table/ActionsColumn.d.ts +2 -0
- package/dist/js/components/Table/ActionsColumn.d.ts.map +1 -1
- package/dist/js/components/Table/ActionsColumn.js +4 -4
- package/dist/js/components/Table/ActionsColumn.js.map +1 -1
- package/dist/js/components/Table/TableTypes.d.ts +2 -0
- package/dist/js/components/Table/TableTypes.d.ts.map +1 -1
- package/dist/js/components/Table/Th.d.ts +8 -0
- package/dist/js/components/Table/Th.d.ts.map +1 -1
- package/dist/js/components/Table/Th.js +7 -3
- package/dist/js/components/Table/Th.js.map +1 -1
- package/dist/js/components/Table/utils/decorators/selectable.js +1 -1
- package/dist/js/components/Table/utils/decorators/selectable.js.map +1 -1
- package/dist/js/demos/DashboardHeader.d.ts +8 -0
- package/dist/js/demos/DashboardHeader.d.ts.map +1 -0
- package/dist/js/demos/DashboardHeader.js +82 -0
- package/dist/js/demos/DashboardHeader.js.map +1 -0
- package/dist/js/demos/DashboardWrapper.d.ts +85 -0
- package/dist/js/demos/DashboardWrapper.d.ts.map +1 -0
- package/dist/js/demos/DashboardWrapper.js +45 -0
- package/dist/js/demos/DashboardWrapper.js.map +1 -0
- package/dist/js/demos/index.d.ts +2 -0
- package/dist/js/demos/index.d.ts.map +1 -1
- package/dist/js/demos/index.js +2 -0
- package/dist/js/demos/index.js.map +1 -1
- package/dist/js/index.d.ts +0 -1
- package/dist/js/index.d.ts.map +1 -1
- package/dist/js/index.js +0 -1
- package/dist/js/index.js.map +1 -1
- package/dist/umd/react-table.min.js +3 -3
- package/package.json +6 -6
- package/src/components/Table/ActionsColumn.tsx +33 -28
- package/src/components/Table/TableTypes.tsx +2 -0
- package/src/components/Table/Th.tsx +20 -2
- package/src/components/Table/__tests__/Th.test.tsx +31 -0
- package/src/components/Table/examples/TableActions.tsx +2 -2
- package/src/components/Table/examples/TableActionsOverflow.tsx +1 -1
- package/src/components/Table/examples/TableCompoundExpandable.tsx +1 -1
- package/src/components/Table/examples/TableDraggable.tsx +2 -2
- package/src/components/Table/examples/TableExpandable.tsx +1 -1
- package/src/components/Table/examples/TableNestedExpandable.tsx +1 -1
- package/src/components/Table/examples/TableNestedStickyHeader.tsx +3 -0
- package/src/components/Table/examples/TableNestedTableExpandable.tsx +1 -1
- package/src/components/Table/examples/TableSelectableRadio.tsx +1 -1
- package/src/components/Table/examples/TableStripedExpandable.tsx +1 -1
- package/src/components/Table/utils/decorators/selectable.tsx +1 -1
- package/src/demos/DashboardHeader.tsx +198 -0
- package/src/demos/DashboardWrapper.tsx +199 -0
- package/src/demos/Table.md +29 -5
- package/src/demos/assets/avatarImg.svg +18 -0
- package/src/demos/assets/index.d.ts +4 -0
- package/src/demos/assets/pf-logo.svg +28 -0
- package/src/demos/examples/TableBulkSelect.tsx +2 -2
- package/src/demos/examples/TableColumnManagement.tsx +1 -1
- package/src/demos/examples/TableCompact.tsx +1 -1
- package/src/demos/examples/TableCompoundExpansion.tsx +4 -3
- package/src/demos/examples/TableEmptyStateDefault.tsx +1 -1
- package/src/demos/examples/TableEmptyStateError.tsx +1 -1
- package/src/demos/examples/TableEmptyStateLoading.tsx +1 -1
- package/src/demos/examples/TableExpandCollapseAll.tsx +1 -1
- package/src/demos/examples/TableSortableResponsive.tsx +2 -2
- package/src/demos/examples/TableStaticBottomPagination.tsx +1 -1
- package/src/demos/examples/TableStickyFirstColumn.tsx +1 -1
- package/src/demos/examples/TableStickyHeader.tsx +1 -1
- package/src/demos/index.ts +2 -0
- package/src/deprecated/components/Table/__tests__/__snapshots__/Table.test.tsx.snap +10 -4
- package/src/index.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-table",
|
|
3
|
-
"version": "5.3.0-prerelease.
|
|
3
|
+
"version": "5.3.0-prerelease.20",
|
|
4
4
|
"description": "This library provides a set of React table components for use with the PatternFly 4",
|
|
5
5
|
"main": "dist/js/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"subpaths": "node ../../scripts/exportSubpaths.js --config subpaths.config.json"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@patternfly/react-core": "^5.3.0-prerelease.
|
|
43
|
-
"@patternfly/react-icons": "^5.3.0-prerelease.
|
|
44
|
-
"@patternfly/react-styles": "^5.3.0-prerelease.
|
|
45
|
-
"@patternfly/react-tokens": "^5.3.0-prerelease.
|
|
42
|
+
"@patternfly/react-core": "^5.3.0-prerelease.19",
|
|
43
|
+
"@patternfly/react-icons": "^5.3.0-prerelease.3",
|
|
44
|
+
"@patternfly/react-styles": "^5.3.0-prerelease.3",
|
|
45
|
+
"@patternfly/react-tokens": "^5.3.0-prerelease.3",
|
|
46
46
|
"lodash": "^4.17.19",
|
|
47
47
|
"tslib": "^2.5.0"
|
|
48
48
|
},
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"react": "^17 || ^18",
|
|
55
55
|
"react-dom": "^17 || ^18"
|
|
56
56
|
},
|
|
57
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "5fc4f385c49deaa2f2835879132bd33869ff73d1"
|
|
58
58
|
}
|
|
@@ -30,6 +30,8 @@ export interface ActionsColumnProps extends Omit<React.HTMLProps<HTMLElement>, '
|
|
|
30
30
|
innerRef?: React.Ref<any>;
|
|
31
31
|
/** Ref to forward to the first item in the popup menu */
|
|
32
32
|
firstActionItemRef?: React.Ref<HTMLButtonElement>;
|
|
33
|
+
/** Flag indicating that the dropdown's onOpenChange callback should not be called. */
|
|
34
|
+
isOnOpenChangeDisabled?: boolean;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
const ActionsColumnBase: React.FunctionComponent<ActionsColumnProps> = ({
|
|
@@ -44,6 +46,7 @@ const ActionsColumnBase: React.FunctionComponent<ActionsColumnProps> = ({
|
|
|
44
46
|
},
|
|
45
47
|
innerRef,
|
|
46
48
|
firstActionItemRef,
|
|
49
|
+
isOnOpenChangeDisabled = false,
|
|
47
50
|
...props
|
|
48
51
|
}: ActionsColumnProps) => {
|
|
49
52
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
@@ -91,7 +94,7 @@ const ActionsColumnBase: React.FunctionComponent<ActionsColumnProps> = ({
|
|
|
91
94
|
|
|
92
95
|
<Dropdown
|
|
93
96
|
isOpen={isOpen}
|
|
94
|
-
onOpenChange={(isOpen: boolean) => setIsOpen(isOpen)}
|
|
97
|
+
onOpenChange={!isOnOpenChangeDisabled ? (isOpen: boolean) => setIsOpen(isOpen) : undefined}
|
|
95
98
|
toggle={(toggleRef: any) =>
|
|
96
99
|
actionsToggle ? (
|
|
97
100
|
actionsToggle({ onToggle, isOpen, isDisabled, toggleRef })
|
|
@@ -116,35 +119,37 @@ const ActionsColumnBase: React.FunctionComponent<ActionsColumnProps> = ({
|
|
|
116
119
|
<DropdownList>
|
|
117
120
|
{items
|
|
118
121
|
.filter((item) => !item.isOutsideDropdown)
|
|
119
|
-
.map(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (tooltipProps?.content) {
|
|
139
|
-
return (
|
|
140
|
-
<Tooltip key={itemKey || index} {...tooltipProps}>
|
|
141
|
-
{item}
|
|
142
|
-
</Tooltip>
|
|
122
|
+
.map(
|
|
123
|
+
({ title, itemKey, onClick, tooltipProps, isSeparator, shouldCloseOnClick = true, ...props }, index) => {
|
|
124
|
+
if (isSeparator) {
|
|
125
|
+
return <Divider key={itemKey || index} data-key={itemKey || index} />;
|
|
126
|
+
}
|
|
127
|
+
const item = (
|
|
128
|
+
<DropdownItem
|
|
129
|
+
onClick={(event: any) => {
|
|
130
|
+
onActionClick(event, onClick);
|
|
131
|
+
shouldCloseOnClick && onToggle();
|
|
132
|
+
}}
|
|
133
|
+
{...props}
|
|
134
|
+
key={itemKey || index}
|
|
135
|
+
data-key={itemKey || index}
|
|
136
|
+
ref={index === 0 ? firstActionItemRef : undefined}
|
|
137
|
+
>
|
|
138
|
+
{title}
|
|
139
|
+
</DropdownItem>
|
|
143
140
|
);
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
|
|
142
|
+
if (tooltipProps?.content) {
|
|
143
|
+
return (
|
|
144
|
+
<Tooltip key={itemKey || index} {...tooltipProps}>
|
|
145
|
+
{item}
|
|
146
|
+
</Tooltip>
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
return item;
|
|
150
|
+
}
|
|
146
151
|
}
|
|
147
|
-
|
|
152
|
+
)}
|
|
148
153
|
</DropdownList>
|
|
149
154
|
</Dropdown>
|
|
150
155
|
</React.Fragment>
|
|
@@ -166,6 +166,8 @@ export interface IAction extends Omit<DropdownItemProps, 'title' | 'onClick'>, P
|
|
|
166
166
|
onClick?: (event: React.MouseEvent, rowIndex: number, rowData: IRowData, extraData: IExtraData) => void;
|
|
167
167
|
/** Flag indicating this action should be placed outside the actions menu, beside the toggle */
|
|
168
168
|
isOutsideDropdown?: boolean;
|
|
169
|
+
/** Flag indicating whether the actions dropdown should close after an item is clicked. */
|
|
170
|
+
shouldCloseOnClick?: boolean;
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
export interface ISeparator extends IAction {
|
|
@@ -56,6 +56,14 @@ export interface ThProps
|
|
|
56
56
|
stickyRightOffset?: string;
|
|
57
57
|
/** Indicates the <th> is part of a subheader of a nested header */
|
|
58
58
|
isSubheader?: boolean;
|
|
59
|
+
/** Visually hidden text accessible only via assistive technologies. This must be passed in if the
|
|
60
|
+
* th is intended to be visually empty, and must be conveyed as a column header text.
|
|
61
|
+
*/
|
|
62
|
+
screenReaderText?: string;
|
|
63
|
+
/** Provides an accessible name to the th. This should only be passed in when the th contains only non-text
|
|
64
|
+
* content, such as a "select all" checkbox or "expand all" toggle.
|
|
65
|
+
*/
|
|
66
|
+
'aria-label'?: string;
|
|
59
67
|
}
|
|
60
68
|
|
|
61
69
|
const ThBase: React.FunctionComponent<ThProps> = ({
|
|
@@ -83,8 +91,17 @@ const ThBase: React.FunctionComponent<ThProps> = ({
|
|
|
83
91
|
stickyLeftOffset,
|
|
84
92
|
stickyRightOffset,
|
|
85
93
|
isSubheader = false,
|
|
94
|
+
screenReaderText,
|
|
95
|
+
'aria-label': ariaLabel,
|
|
86
96
|
...props
|
|
87
97
|
}: ThProps) => {
|
|
98
|
+
if (!children && !screenReaderText && !ariaLabel) {
|
|
99
|
+
// eslint-disable-next-line no-console
|
|
100
|
+
console.warn(
|
|
101
|
+
'Th: Table headers must have an accessible name. If the Th is intended to be visually empty, pass in screenReaderText. If the Th contains only non-text, interactive content such as a checkbox or expand toggle, pass in an aria-label.'
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
88
105
|
const [showTooltip, setShowTooltip] = React.useState(false);
|
|
89
106
|
const [truncated, setTruncated] = React.useState(false);
|
|
90
107
|
const cellRef = innerRef ? innerRef : React.createRef();
|
|
@@ -188,8 +205,9 @@ const ThBase: React.FunctionComponent<ThProps> = ({
|
|
|
188
205
|
onBlur={() => setShowTooltip(false)}
|
|
189
206
|
data-label={dataLabel}
|
|
190
207
|
onMouseEnter={tooltip !== null ? onMouseEnter : onMouseEnterProp}
|
|
191
|
-
scope={component === 'th'
|
|
208
|
+
scope={component === 'th' ? scope : null}
|
|
192
209
|
ref={cellRef}
|
|
210
|
+
aria-label={ariaLabel}
|
|
193
211
|
className={css(
|
|
194
212
|
styles.tableTh,
|
|
195
213
|
className,
|
|
@@ -212,7 +230,7 @@ const ThBase: React.FunctionComponent<ThProps> = ({
|
|
|
212
230
|
} as React.CSSProperties
|
|
213
231
|
})}
|
|
214
232
|
>
|
|
215
|
-
{transformedChildren}
|
|
233
|
+
{transformedChildren || (screenReaderText && <span className="pf-v5-screen-reader">{screenReaderText}</span>)}
|
|
216
234
|
</MergedComponent>
|
|
217
235
|
);
|
|
218
236
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Th } from '../Th';
|
|
4
|
+
|
|
5
|
+
test('Does not render with aria-label by default', () => {
|
|
6
|
+
render(<Th />);
|
|
7
|
+
expect(screen.getByRole('columnheader')).not.toHaveAccessibleName();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('Renders with aria-label when passed in', () => {
|
|
11
|
+
render(<Th aria-label="Test" />);
|
|
12
|
+
expect(screen.getByRole('columnheader')).toHaveAccessibleName('Test');
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('Does not render with screen reader text by default', () => {
|
|
16
|
+
render(<Th />);
|
|
17
|
+
|
|
18
|
+
expect(screen.getByRole('columnheader')).toBeEmptyDOMElement();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('Does not render with screen reader text when children are passed in', () => {
|
|
22
|
+
render(<Th screenReaderText="Test">Heading label</Th>);
|
|
23
|
+
|
|
24
|
+
expect(screen.getByRole('columnheader')).not.toHaveTextContent('Test');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('Renders with screen reader text when screenReaderText is passed in', () => {
|
|
28
|
+
render(<Th screenReaderText="Test" />);
|
|
29
|
+
|
|
30
|
+
expect(screen.getByRole('columnheader')).toHaveTextContent('Test');
|
|
31
|
+
});
|
|
@@ -116,8 +116,8 @@ export const TableActions: React.FunctionComponent = () => {
|
|
|
116
116
|
<Th>{columnNames.prs}</Th>
|
|
117
117
|
<Th>{columnNames.workspaces}</Th>
|
|
118
118
|
<Th>{columnNames.lastCommit}</Th>
|
|
119
|
-
<
|
|
120
|
-
<
|
|
119
|
+
<Th screenReaderText="Primary action" />
|
|
120
|
+
<Th screenReaderText="Secondary action" />
|
|
121
121
|
</Tr>
|
|
122
122
|
</Thead>
|
|
123
123
|
<Tbody>
|
|
@@ -67,7 +67,7 @@ export const TableCompoundExpandable: React.FunctionComponent = () => {
|
|
|
67
67
|
<Th>{columnNames.prs}</Th>
|
|
68
68
|
<Th>{columnNames.workspaces}</Th>
|
|
69
69
|
<Th>{columnNames.lastCommit}</Th>
|
|
70
|
-
<Th />
|
|
70
|
+
<Th screenReaderText="URL" />
|
|
71
71
|
</Tr>
|
|
72
72
|
</Thead>
|
|
73
73
|
{repositories.map((repo: Repository, rowIndex: number) => {
|
|
@@ -140,10 +140,10 @@ export const TableDraggable: React.FunctionComponent = () => {
|
|
|
140
140
|
];
|
|
141
141
|
|
|
142
142
|
return (
|
|
143
|
-
<Table aria-label="Draggable table" className={isDragging
|
|
143
|
+
<Table aria-label="Draggable table" className={isDragging ? styles.modifiers.dragOver : ''}>
|
|
144
144
|
<Thead>
|
|
145
145
|
<Tr>
|
|
146
|
-
<Th />
|
|
146
|
+
<Th screenReaderText="Drag and drop" />
|
|
147
147
|
{columns.map((column, columnIndex) => (
|
|
148
148
|
<Th key={columnIndex}>{column}</Th>
|
|
149
149
|
))}
|
|
@@ -120,7 +120,7 @@ export const TableExpandable: React.FunctionComponent = () => {
|
|
|
120
120
|
<Table aria-label="Expandable table" variant={isExampleCompact ? 'compact' : undefined}>
|
|
121
121
|
<Thead>
|
|
122
122
|
<Tr>
|
|
123
|
-
<Th />
|
|
123
|
+
<Th screenReaderText="Row expansion" />
|
|
124
124
|
<Th width={25}>{columnNames.name}</Th>
|
|
125
125
|
<Th width={10}>{columnNames.branches}</Th>
|
|
126
126
|
<Th width={15}>{columnNames.prs}</Th>
|
|
@@ -64,7 +64,7 @@ export const TableNestedExpandable: React.FunctionComponent = () => {
|
|
|
64
64
|
<Table aria-label="Nested column headers with expandable rows table" gridBreakPoint="">
|
|
65
65
|
<Thead hasNestedHeader>
|
|
66
66
|
<Tr>
|
|
67
|
-
<Th rowSpan={2} />
|
|
67
|
+
<Th screenReaderText="Row expansion" rowSpan={2} />
|
|
68
68
|
<Th width={35} rowSpan={2} hasRightBorder>
|
|
69
69
|
{columnNames.team}
|
|
70
70
|
</Th>
|
|
@@ -154,6 +154,9 @@ export const TableNestedHeaders: React.FunctionComponent = () => {
|
|
|
154
154
|
{columnNames.destination}
|
|
155
155
|
</Th>
|
|
156
156
|
</Tr>
|
|
157
|
+
{/* TODO: Remove the following Tr once Core updates towards https://github.com/patternfly/patternfly/issues/6272
|
|
158
|
+
are made for the v5 branch. For v6 branch the row can be removed immediately.
|
|
159
|
+
*/}
|
|
157
160
|
<Tr isBorderRow aria-hidden="true">
|
|
158
161
|
<Td colSpan={9}></Td>
|
|
159
162
|
</Tr>
|
|
@@ -131,7 +131,7 @@ export const TableExpandable: React.FunctionComponent = () => {
|
|
|
131
131
|
<Table aria-label="Simple table">
|
|
132
132
|
<Thead>
|
|
133
133
|
<Tr>
|
|
134
|
-
<
|
|
134
|
+
<Th screenReaderText="Row expansion" />
|
|
135
135
|
<Th width={20}>{columnNames.name}</Th>
|
|
136
136
|
<Th>{columnNames.branches}</Th>
|
|
137
137
|
<Th>{columnNames.prs}</Th>
|
|
@@ -35,7 +35,7 @@ export const TableSelectableRadio: React.FunctionComponent = () => {
|
|
|
35
35
|
<Table aria-label="Selectable table">
|
|
36
36
|
<Thead>
|
|
37
37
|
<Tr>
|
|
38
|
-
<Th />
|
|
38
|
+
<Th screenReaderText="Row select" />
|
|
39
39
|
<Th>{columnNames.name}</Th>
|
|
40
40
|
<Th>{columnNames.branches}</Th>
|
|
41
41
|
<Th>{columnNames.prs}</Th>
|
|
@@ -115,7 +115,7 @@ export const TableStripedExpandable: React.FunctionComponent = () => {
|
|
|
115
115
|
<Table aria-label="Expandable table" variant={isExampleCompact ? 'compact' : undefined} isStriped isExpandable>
|
|
116
116
|
<Thead>
|
|
117
117
|
<Tr>
|
|
118
|
-
<Th />
|
|
118
|
+
<Th screenReaderText="Row expansion" />
|
|
119
119
|
<Th width={25}>{columnNames.name}</Th>
|
|
120
120
|
<Th width={10}>{columnNames.branches}</Th>
|
|
121
121
|
<Th width={15}>{columnNames.prs}</Th>
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
Avatar,
|
|
4
|
+
Brand,
|
|
5
|
+
Button,
|
|
6
|
+
ButtonVariant,
|
|
7
|
+
Divider,
|
|
8
|
+
Dropdown,
|
|
9
|
+
DropdownGroup,
|
|
10
|
+
DropdownItem,
|
|
11
|
+
DropdownList,
|
|
12
|
+
Masthead,
|
|
13
|
+
MastheadToggle,
|
|
14
|
+
MastheadMain,
|
|
15
|
+
MastheadBrand,
|
|
16
|
+
MastheadContent,
|
|
17
|
+
MenuToggle,
|
|
18
|
+
Toolbar,
|
|
19
|
+
ToolbarContent,
|
|
20
|
+
ToolbarGroup,
|
|
21
|
+
ToolbarItem,
|
|
22
|
+
PageToggleButton
|
|
23
|
+
} from '@patternfly/react-core';
|
|
24
|
+
import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
|
|
25
|
+
import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
|
|
26
|
+
import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon';
|
|
27
|
+
import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon';
|
|
28
|
+
import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
|
|
29
|
+
import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
|
|
30
|
+
import imgAvatar from '@patternfly/react-table/src/demos/assets/avatarImg.svg';
|
|
31
|
+
import pfLogo from '@patternfly/react-table/src/demos/assets/pf-logo.svg';
|
|
32
|
+
|
|
33
|
+
interface DashboardHeaderProps {
|
|
34
|
+
/** Render custom notification badge */
|
|
35
|
+
notificationBadge?: React.ReactNode;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const DashboardHeader: React.FC<DashboardHeaderProps> = ({ notificationBadge }) => {
|
|
39
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
40
|
+
const [isKebabDropdownOpen, setIsKebabDropdownOpen] = useState(false);
|
|
41
|
+
const [isFullKebabDropdownOpen, setIsFullKebabDropdownOpen] = useState(false);
|
|
42
|
+
|
|
43
|
+
const kebabDropdownItems = (
|
|
44
|
+
<>
|
|
45
|
+
<DropdownItem>
|
|
46
|
+
<CogIcon /> Settings
|
|
47
|
+
</DropdownItem>
|
|
48
|
+
<DropdownItem>
|
|
49
|
+
<HelpIcon /> Help
|
|
50
|
+
</DropdownItem>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const userDropdownItems = (
|
|
55
|
+
<>
|
|
56
|
+
<DropdownItem key="group 2 profile">My profile</DropdownItem>
|
|
57
|
+
<DropdownItem key="group 2 user">User management</DropdownItem>
|
|
58
|
+
<DropdownItem key="group 2 logout">Logout</DropdownItem>
|
|
59
|
+
</>
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const onDropdownToggle = () => {
|
|
63
|
+
setIsDropdownOpen(!isDropdownOpen);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const onDropdownSelect = () => {
|
|
67
|
+
setIsDropdownOpen(false);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const onKebabDropdownToggle = () => {
|
|
71
|
+
setIsKebabDropdownOpen(!isKebabDropdownOpen);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const onKebabDropdownSelect = () => {
|
|
75
|
+
setIsKebabDropdownOpen(false);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const onFullKebabToggle = () => {
|
|
79
|
+
setIsFullKebabDropdownOpen(!isFullKebabDropdownOpen);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const onFullKebabSelect = () => {
|
|
83
|
+
setIsFullKebabDropdownOpen(false);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Masthead>
|
|
88
|
+
<MastheadToggle>
|
|
89
|
+
<PageToggleButton variant="plain" aria-label="Global navigation">
|
|
90
|
+
<BarsIcon />
|
|
91
|
+
</PageToggleButton>
|
|
92
|
+
</MastheadToggle>
|
|
93
|
+
<MastheadMain>
|
|
94
|
+
<MastheadBrand>
|
|
95
|
+
<Brand src={pfLogo} alt="PatternFly" heights={{ default: '36px' }} />
|
|
96
|
+
</MastheadBrand>
|
|
97
|
+
</MastheadMain>
|
|
98
|
+
<MastheadContent>
|
|
99
|
+
<Toolbar id="toolbar" isFullHeight isStatic>
|
|
100
|
+
<ToolbarContent>
|
|
101
|
+
<ToolbarGroup
|
|
102
|
+
variant="icon-button-group"
|
|
103
|
+
align={{ default: 'alignRight' }}
|
|
104
|
+
spacer={{ default: 'spacerNone', md: 'spacerMd' }}
|
|
105
|
+
>
|
|
106
|
+
{notificationBadge ?? (
|
|
107
|
+
<ToolbarItem>
|
|
108
|
+
<Button
|
|
109
|
+
aria-label="Notifications"
|
|
110
|
+
variant={ButtonVariant.plain}
|
|
111
|
+
icon={<BellIcon />}
|
|
112
|
+
onClick={() => {}}
|
|
113
|
+
/>
|
|
114
|
+
</ToolbarItem>
|
|
115
|
+
)}
|
|
116
|
+
<ToolbarGroup variant="icon-button-group" visibility={{ default: 'hidden', lg: 'visible' }}>
|
|
117
|
+
<ToolbarItem>
|
|
118
|
+
<Button aria-label="Settings" variant={ButtonVariant.plain} icon={<CogIcon />} />
|
|
119
|
+
</ToolbarItem>
|
|
120
|
+
<ToolbarItem>
|
|
121
|
+
<Button aria-label="Help" variant={ButtonVariant.plain} icon={<QuestionCircleIcon />} />
|
|
122
|
+
</ToolbarItem>
|
|
123
|
+
</ToolbarGroup>
|
|
124
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible', lg: 'hidden' }}>
|
|
125
|
+
<Dropdown
|
|
126
|
+
isOpen={isKebabDropdownOpen}
|
|
127
|
+
onSelect={onKebabDropdownSelect}
|
|
128
|
+
onOpenChange={setIsKebabDropdownOpen}
|
|
129
|
+
popperProps={{ position: 'right' }}
|
|
130
|
+
toggle={(toggleRef: React.RefObject<any>) => (
|
|
131
|
+
<MenuToggle
|
|
132
|
+
ref={toggleRef}
|
|
133
|
+
isExpanded={isKebabDropdownOpen}
|
|
134
|
+
onClick={onKebabDropdownToggle}
|
|
135
|
+
variant="plain"
|
|
136
|
+
aria-label="Settings and help"
|
|
137
|
+
>
|
|
138
|
+
<EllipsisVIcon aria-hidden="true" />
|
|
139
|
+
</MenuToggle>
|
|
140
|
+
)}
|
|
141
|
+
>
|
|
142
|
+
<DropdownList>{kebabDropdownItems}</DropdownList>
|
|
143
|
+
</Dropdown>
|
|
144
|
+
</ToolbarItem>
|
|
145
|
+
<ToolbarItem visibility={{ md: 'hidden' }}>
|
|
146
|
+
<Dropdown
|
|
147
|
+
isOpen={isFullKebabDropdownOpen}
|
|
148
|
+
onSelect={onFullKebabSelect}
|
|
149
|
+
onOpenChange={setIsFullKebabDropdownOpen}
|
|
150
|
+
popperProps={{ position: 'right' }}
|
|
151
|
+
toggle={(toggleRef: React.RefObject<any>) => (
|
|
152
|
+
<MenuToggle
|
|
153
|
+
ref={toggleRef}
|
|
154
|
+
isExpanded={isFullKebabDropdownOpen}
|
|
155
|
+
onClick={onFullKebabToggle}
|
|
156
|
+
variant="plain"
|
|
157
|
+
aria-label="Toolbar menu"
|
|
158
|
+
>
|
|
159
|
+
<EllipsisVIcon aria-hidden="true" />
|
|
160
|
+
</MenuToggle>
|
|
161
|
+
)}
|
|
162
|
+
>
|
|
163
|
+
<DropdownGroup key="group 2" aria-label="User actions">
|
|
164
|
+
<DropdownList>{userDropdownItems}</DropdownList>
|
|
165
|
+
</DropdownGroup>
|
|
166
|
+
<Divider />
|
|
167
|
+
<DropdownList>{kebabDropdownItems}</DropdownList>
|
|
168
|
+
</Dropdown>
|
|
169
|
+
</ToolbarItem>
|
|
170
|
+
</ToolbarGroup>
|
|
171
|
+
<ToolbarItem visibility={{ default: 'hidden', md: 'visible' }}>
|
|
172
|
+
<Dropdown
|
|
173
|
+
isOpen={isDropdownOpen}
|
|
174
|
+
onSelect={onDropdownSelect}
|
|
175
|
+
onOpenChange={setIsDropdownOpen}
|
|
176
|
+
popperProps={{ position: 'right' }}
|
|
177
|
+
toggle={(toggleRef: React.RefObject<any>) => (
|
|
178
|
+
<MenuToggle
|
|
179
|
+
ref={toggleRef}
|
|
180
|
+
isExpanded={isDropdownOpen}
|
|
181
|
+
onClick={onDropdownToggle}
|
|
182
|
+
icon={<Avatar src={imgAvatar} alt="" />}
|
|
183
|
+
isFullHeight
|
|
184
|
+
>
|
|
185
|
+
Ned Username
|
|
186
|
+
</MenuToggle>
|
|
187
|
+
)}
|
|
188
|
+
>
|
|
189
|
+
<DropdownList>{userDropdownItems}</DropdownList>
|
|
190
|
+
</Dropdown>
|
|
191
|
+
</ToolbarItem>
|
|
192
|
+
</ToolbarContent>
|
|
193
|
+
</Toolbar>
|
|
194
|
+
</MastheadContent>
|
|
195
|
+
</Masthead>
|
|
196
|
+
);
|
|
197
|
+
};
|
|
198
|
+
DashboardHeader.displayName = 'DashboardHeader';
|