@patternfly/react-core 4.198.16 → 4.198.19
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 +24 -0
- package/dist/esm/components/AlertGroup/AlertGroup.d.ts +4 -0
- package/dist/esm/components/AlertGroup/AlertGroup.d.ts.map +1 -1
- package/dist/esm/components/AlertGroup/AlertGroup.js +2 -2
- package/dist/esm/components/AlertGroup/AlertGroup.js.map +1 -1
- package/dist/esm/components/AlertGroup/AlertGroupInline.d.ts.map +1 -1
- package/dist/esm/components/AlertGroup/AlertGroupInline.js +5 -2
- package/dist/esm/components/AlertGroup/AlertGroupInline.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadMain.d.ts +10 -2
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadMain.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadMain.js +9 -2
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadMain.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatus.d.ts +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatus.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatus.js +21 -2
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatus.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitle.d.ts +6 -2
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitle.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitle.js +9 -2
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitle.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitleIcon.d.ts +2 -0
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitleIcon.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitleIcon.js +2 -4
- package/dist/esm/components/MultipleFileUpload/MultipleFileUploadTitleIcon.js.map +1 -1
- package/dist/esm/components/MultipleFileUpload/index.d.ts +0 -6
- package/dist/esm/components/MultipleFileUpload/index.d.ts.map +1 -1
- package/dist/esm/components/MultipleFileUpload/index.js +0 -6
- package/dist/esm/components/MultipleFileUpload/index.js.map +1 -1
- package/dist/esm/components/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/esm/components/NumberInput/NumberInput.js +2 -2
- package/dist/esm/components/NumberInput/NumberInput.js.map +1 -1
- package/dist/js/components/AlertGroup/AlertGroup.d.ts +4 -0
- package/dist/js/components/AlertGroup/AlertGroup.d.ts.map +1 -1
- package/dist/js/components/AlertGroup/AlertGroup.js +2 -2
- package/dist/js/components/AlertGroup/AlertGroup.js.map +1 -1
- package/dist/js/components/AlertGroup/AlertGroupInline.d.ts.map +1 -1
- package/dist/js/components/AlertGroup/AlertGroupInline.js +5 -2
- package/dist/js/components/AlertGroup/AlertGroupInline.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadMain.d.ts +10 -2
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadMain.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadMain.js +9 -2
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadMain.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatus.d.ts +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatus.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatus.js +21 -2
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatus.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitle.d.ts +6 -2
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitle.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitle.js +9 -2
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitle.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitleIcon.d.ts +2 -0
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitleIcon.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitleIcon.js +2 -4
- package/dist/js/components/MultipleFileUpload/MultipleFileUploadTitleIcon.js.map +1 -1
- package/dist/js/components/MultipleFileUpload/index.d.ts +0 -6
- package/dist/js/components/MultipleFileUpload/index.d.ts.map +1 -1
- package/dist/js/components/MultipleFileUpload/index.js +0 -6
- package/dist/js/components/MultipleFileUpload/index.js.map +1 -1
- package/dist/js/components/NumberInput/NumberInput.d.ts.map +1 -1
- package/dist/js/components/NumberInput/NumberInput.js +2 -2
- package/dist/js/components/NumberInput/NumberInput.js.map +1 -1
- package/dist/styles/assets/images/img_pie-chart-with-legend.png +0 -0
- package/dist/styles/assets/images/status-icon-sprite.svg +38 -0
- package/dist/umd/react-core.css +244 -47
- package/dist/umd/react-core.js +77 -49
- package/dist/umd/react-core.min.css +316 -119
- package/dist/umd/react-core.min.js +4 -4
- package/package.json +6 -6
- package/src/components/AlertGroup/AlertGroup.tsx +13 -2
- package/src/components/AlertGroup/AlertGroupInline.tsx +9 -0
- package/src/components/AlertGroup/__tests__/AlertGroup.test.tsx +15 -0
- package/src/components/AlertGroup/__tests__/__snapshots__/AlertGroup.test.tsx.snap +93 -1
- package/src/components/AlertGroup/examples/AlertGroup.md +147 -0
- package/src/components/MultipleFileUpload/MultipleFileUploadMain.tsx +29 -8
- package/src/components/MultipleFileUpload/MultipleFileUploadStatus.tsx +24 -4
- package/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +1 -1
- package/src/components/MultipleFileUpload/MultipleFileUploadTitle.tsx +19 -5
- package/src/components/MultipleFileUpload/MultipleFileUploadTitleIcon.tsx +4 -3
- package/src/components/MultipleFileUpload/__tests__/MultipleFileUploadMain.test.tsx +19 -2
- package/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitle.test.tsx +17 -2
- package/src/components/MultipleFileUpload/__tests__/MultipleFileUploadTitleIcon.test.tsx +1 -1
- package/src/components/MultipleFileUpload/__tests__/__snapshots__/MultipleFileUploadMain.test.tsx.snap +198 -2
- package/src/components/MultipleFileUpload/__tests__/__snapshots__/MultipleFileUploadTitle.test.tsx.snap +62 -4
- package/src/components/MultipleFileUpload/__tests__/__snapshots__/MultipleFileUploadTitleIcon.test.tsx.snap +2 -50
- package/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +7 -60
- package/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx +48 -74
- package/src/components/MultipleFileUpload/index.ts +0 -6
- package/src/components/NumberInput/NumberInput.tsx +3 -2
- package/src/components/NumberInput/examples/NumberInput.md +78 -5
- package/src/demos/MultipleFileUploadDemos.md +16 -0
- package/src/{components/MultipleFileUpload/examples/MultipleFileUploadHorizontal.tsx → demos/examples/MultipleFileUpload/MultipleFileUploadRejectedFile.tsx} +60 -64
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patternfly/react-core",
|
|
3
|
-
"version": "4.198.
|
|
3
|
+
"version": "4.198.19",
|
|
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",
|
|
@@ -34,16 +34,16 @@
|
|
|
34
34
|
"generate": "node scripts/copyStyles.js"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@patternfly/react-icons": "^4.49.
|
|
38
|
-
"@patternfly/react-styles": "^4.48.
|
|
39
|
-
"@patternfly/react-tokens": "^4.50.
|
|
37
|
+
"@patternfly/react-icons": "^4.49.19",
|
|
38
|
+
"@patternfly/react-styles": "^4.48.19",
|
|
39
|
+
"@patternfly/react-tokens": "^4.50.19",
|
|
40
40
|
"focus-trap": "6.2.2",
|
|
41
41
|
"react-dropzone": "9.0.0",
|
|
42
42
|
"tippy.js": "5.1.2",
|
|
43
43
|
"tslib": "^2.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
|
-
"@patternfly/patternfly": "4.
|
|
46
|
+
"@patternfly/patternfly": "4.183.1",
|
|
47
47
|
"@rollup/plugin-commonjs": "^21.0.0",
|
|
48
48
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
|
49
49
|
"@rollup/plugin-replace": "^3.0.0",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"react": "^16.8.0 || ^17.0.0",
|
|
61
61
|
"react-dom": "^16.8.0 || ^17.0.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "5b472303da22cb9c67e9977b3933f6576c27ac01"
|
|
64
64
|
}
|
|
@@ -14,6 +14,10 @@ export interface AlertGroupProps extends Omit<React.HTMLProps<HTMLUListElement>,
|
|
|
14
14
|
isLiveRegion?: boolean;
|
|
15
15
|
/** Determine where the alert is appended to */
|
|
16
16
|
appendTo?: HTMLElement | (() => HTMLElement);
|
|
17
|
+
/** Function to call if user clicks on overflow message */
|
|
18
|
+
onOverflowClick?: () => void;
|
|
19
|
+
/** Custom text to show for the overflow message */
|
|
20
|
+
overflowMessage?: string;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
interface AlertGroupState {
|
|
@@ -49,9 +53,16 @@ export class AlertGroup extends React.Component<AlertGroupProps, AlertGroupState
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
render() {
|
|
52
|
-
const { className, children, isToast, isLiveRegion, ...props } = this.props;
|
|
56
|
+
const { className, children, isToast, isLiveRegion, onOverflowClick, overflowMessage, ...props } = this.props;
|
|
53
57
|
const alertGroup = (
|
|
54
|
-
<AlertGroupInline
|
|
58
|
+
<AlertGroupInline
|
|
59
|
+
onOverflowClick={onOverflowClick}
|
|
60
|
+
className={className}
|
|
61
|
+
isToast={isToast}
|
|
62
|
+
isLiveRegion={isLiveRegion}
|
|
63
|
+
overflowMessage={overflowMessage}
|
|
64
|
+
{...props}
|
|
65
|
+
>
|
|
55
66
|
{children}
|
|
56
67
|
</AlertGroupInline>
|
|
57
68
|
);
|
|
@@ -8,6 +8,8 @@ export const AlertGroupInline: React.FunctionComponent<AlertGroupProps> = ({
|
|
|
8
8
|
children,
|
|
9
9
|
isToast,
|
|
10
10
|
isLiveRegion,
|
|
11
|
+
onOverflowClick,
|
|
12
|
+
overflowMessage,
|
|
11
13
|
...rest
|
|
12
14
|
}: AlertGroupProps) => (
|
|
13
15
|
<ul
|
|
@@ -19,6 +21,13 @@ export const AlertGroupInline: React.FunctionComponent<AlertGroupProps> = ({
|
|
|
19
21
|
{React.Children.toArray(children).map((Alert: React.ReactNode, index: number) => (
|
|
20
22
|
<li key={index}>{Alert}</li>
|
|
21
23
|
))}
|
|
24
|
+
{overflowMessage && (
|
|
25
|
+
<li>
|
|
26
|
+
<button onClick={onOverflowClick} className={css(styles.alertGroupOverflowButton)}>
|
|
27
|
+
{overflowMessage}
|
|
28
|
+
</button>
|
|
29
|
+
</li>
|
|
30
|
+
)}
|
|
22
31
|
</ul>
|
|
23
32
|
);
|
|
24
33
|
AlertGroupInline.displayName = 'AlertGroupInline';
|
|
@@ -28,6 +28,21 @@ test('Alert Group works with n children', () => {
|
|
|
28
28
|
expect(view).toBeTruthy();
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
+
test('Alert group overflow shows up', () => {
|
|
32
|
+
const overflowMessage = "View 2 more alerts";
|
|
33
|
+
const onOverflowClick = jest.fn();
|
|
34
|
+
const wrapper = mount(
|
|
35
|
+
<AlertGroup overflowMessage={overflowMessage} onOverflowClick={onOverflowClick}>
|
|
36
|
+
<Alert variant="danger" title="alert title" />
|
|
37
|
+
</AlertGroup>
|
|
38
|
+
)
|
|
39
|
+
expect(wrapper.find('.pf-c-alert-group > li')).toHaveLength(2);
|
|
40
|
+
expect(wrapper.find('.pf-c-alert-group__overflow-button').text()).toContain(overflowMessage);
|
|
41
|
+
expect(wrapper).toMatchSnapshot();
|
|
42
|
+
wrapper.find('.pf-c-alert-group__overflow-button').simulate('click');
|
|
43
|
+
expect(onOverflowClick).toBeCalled();
|
|
44
|
+
});
|
|
45
|
+
|
|
31
46
|
test('Standard Alert Group is not a toast alert group', () => {
|
|
32
47
|
const wrapper = mount(
|
|
33
48
|
<AlertGroup>
|
|
@@ -8,6 +8,95 @@ exports[`Alert Group should match snapshot 1`] = `
|
|
|
8
8
|
</div>
|
|
9
9
|
`;
|
|
10
10
|
|
|
11
|
+
exports[`Alert group overflow shows up 1`] = `
|
|
12
|
+
<AlertGroup
|
|
13
|
+
onOverflowClick={[MockFunction]}
|
|
14
|
+
overflowMessage="View 2 more alerts"
|
|
15
|
+
>
|
|
16
|
+
<AlertGroupInline
|
|
17
|
+
onOverflowClick={[MockFunction]}
|
|
18
|
+
overflowMessage="View 2 more alerts"
|
|
19
|
+
>
|
|
20
|
+
<ul
|
|
21
|
+
aria-atomic={null}
|
|
22
|
+
aria-live={null}
|
|
23
|
+
className="pf-c-alert-group"
|
|
24
|
+
>
|
|
25
|
+
<li
|
|
26
|
+
key="0"
|
|
27
|
+
>
|
|
28
|
+
<Alert
|
|
29
|
+
key=".0"
|
|
30
|
+
title="alert title"
|
|
31
|
+
variant="danger"
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
aria-label="Danger Alert"
|
|
35
|
+
className="pf-c-alert pf-m-danger"
|
|
36
|
+
data-ouia-component-id="OUIA-Generated-Alert-danger-1"
|
|
37
|
+
data-ouia-component-type="PF4/Alert"
|
|
38
|
+
data-ouia-safe={true}
|
|
39
|
+
onMouseEnter={[Function]}
|
|
40
|
+
onMouseLeave={[Function]}
|
|
41
|
+
>
|
|
42
|
+
<AlertIcon
|
|
43
|
+
variant="danger"
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
className="pf-c-alert__icon"
|
|
47
|
+
>
|
|
48
|
+
<ExclamationCircleIcon
|
|
49
|
+
color="currentColor"
|
|
50
|
+
noVerticalAlign={false}
|
|
51
|
+
size="sm"
|
|
52
|
+
>
|
|
53
|
+
<svg
|
|
54
|
+
aria-hidden={true}
|
|
55
|
+
aria-labelledby={null}
|
|
56
|
+
fill="currentColor"
|
|
57
|
+
height="1em"
|
|
58
|
+
role="img"
|
|
59
|
+
style={
|
|
60
|
+
Object {
|
|
61
|
+
"verticalAlign": "-0.125em",
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
viewBox="0 0 512 512"
|
|
65
|
+
width="1em"
|
|
66
|
+
>
|
|
67
|
+
<path
|
|
68
|
+
d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
|
|
69
|
+
/>
|
|
70
|
+
</svg>
|
|
71
|
+
</ExclamationCircleIcon>
|
|
72
|
+
</div>
|
|
73
|
+
</AlertIcon>
|
|
74
|
+
<h4
|
|
75
|
+
className="pf-c-alert__title"
|
|
76
|
+
>
|
|
77
|
+
<span
|
|
78
|
+
className="pf-u-screen-reader"
|
|
79
|
+
>
|
|
80
|
+
Danger alert:
|
|
81
|
+
</span>
|
|
82
|
+
alert title
|
|
83
|
+
</h4>
|
|
84
|
+
</div>
|
|
85
|
+
</Alert>
|
|
86
|
+
</li>
|
|
87
|
+
<li>
|
|
88
|
+
<button
|
|
89
|
+
className="pf-c-alert-group__overflow-button"
|
|
90
|
+
onClick={[MockFunction]}
|
|
91
|
+
>
|
|
92
|
+
View 2 more alerts
|
|
93
|
+
</button>
|
|
94
|
+
</li>
|
|
95
|
+
</ul>
|
|
96
|
+
</AlertGroupInline>
|
|
97
|
+
</AlertGroup>
|
|
98
|
+
`;
|
|
99
|
+
|
|
11
100
|
exports[`Standard Alert Group is not a toast alert group 1`] = `
|
|
12
101
|
<AlertGroup>
|
|
13
102
|
<AlertGroupInline>
|
|
@@ -27,7 +116,7 @@ exports[`Standard Alert Group is not a toast alert group 1`] = `
|
|
|
27
116
|
<div
|
|
28
117
|
aria-label="Danger Alert"
|
|
29
118
|
className="pf-c-alert pf-m-danger"
|
|
30
|
-
data-ouia-component-id="OUIA-Generated-Alert-danger-
|
|
119
|
+
data-ouia-component-id="OUIA-Generated-Alert-danger-2"
|
|
31
120
|
data-ouia-component-type="PF4/Alert"
|
|
32
121
|
data-ouia-safe={true}
|
|
33
122
|
onMouseEnter={[Function]}
|
|
@@ -215,6 +304,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
|
|
|
215
304
|
<AlertGroup
|
|
216
305
|
appendTo={
|
|
217
306
|
<body>
|
|
307
|
+
<div />
|
|
218
308
|
<div />
|
|
219
309
|
<div>
|
|
220
310
|
<ul
|
|
@@ -420,6 +510,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
|
|
|
420
510
|
<AlertGroupInline
|
|
421
511
|
appendTo={
|
|
422
512
|
<body>
|
|
513
|
+
<div />
|
|
423
514
|
<div />
|
|
424
515
|
<div>
|
|
425
516
|
<ul
|
|
@@ -547,6 +638,7 @@ exports[`alertgroup closes when alerts are closed 1`] = `
|
|
|
547
638
|
<ul
|
|
548
639
|
appendTo={
|
|
549
640
|
<body>
|
|
641
|
+
<div />
|
|
550
642
|
<div />
|
|
551
643
|
<div>
|
|
552
644
|
<ul
|
|
@@ -78,6 +78,79 @@ class ToastAlertGroup extends React.Component {
|
|
|
78
78
|
}
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
### Toast alert group with overflow capture
|
|
82
|
+
After a specified number of alerts displayed is reached, we will see an overflow message instead of new alerts. Alerts asynchronously appended into dynamic AlertGroups with `isLiveRegion` will be announced to assistive technology at the moment the change happens. When the overflow message appears or is updated in AlertGroups with `isLiveRegion`, the `View 1 more alert` text will be read, but the alert message will not be read. screen reader user or keyboard user will need a way to navigate to and reveal the hidden alerts before they disappear. Alternatively, there should be a place that notifications or alerts are collected to be viewed or read later. In this example we are showing a max of 4 alerts.
|
|
83
|
+
```js isBeta
|
|
84
|
+
import React from 'react';
|
|
85
|
+
import { Alert, AlertGroup, AlertActionCloseButton, AlertVariant, InputGroup } from '@patternfly/react-core';
|
|
86
|
+
class ToastAlertGroup extends React.Component {
|
|
87
|
+
constructor() {
|
|
88
|
+
super();
|
|
89
|
+
this.state = {
|
|
90
|
+
alerts: [],
|
|
91
|
+
maxDisplayed: "4",
|
|
92
|
+
overflowMessage: ''
|
|
93
|
+
};
|
|
94
|
+
this.getOverflowMessage = (alertsNumber) => {
|
|
95
|
+
const overflow = alertsNumber - this.state.maxDisplayed;
|
|
96
|
+
if (overflow > 0) {
|
|
97
|
+
return "View " + (overflow) + " more alerts";
|
|
98
|
+
}
|
|
99
|
+
return '';
|
|
100
|
+
};
|
|
101
|
+
this.addAlert = (title, variant, key) => {
|
|
102
|
+
this.setState({
|
|
103
|
+
...this.state,
|
|
104
|
+
alerts: [ ...this.state.alerts, { title: title, variant: variant, key }],
|
|
105
|
+
overflowMessage: this.getOverflowMessage(this.state.alerts.length + 1)
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
this.removeAlert = key => {
|
|
109
|
+
const newAlerts = [...this.state.alerts.filter(el => el.key !== key)];
|
|
110
|
+
this.setState({
|
|
111
|
+
...this.state,
|
|
112
|
+
alerts: newAlerts,
|
|
113
|
+
overflowMessage: this.getOverflowMessage(newAlerts.length)
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
render() {
|
|
118
|
+
const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
|
|
119
|
+
const getUniqueId = () => (new Date().getTime());
|
|
120
|
+
const addSuccessAlert = () => { this.addAlert('Toast success alert', 'success', getUniqueId()) };
|
|
121
|
+
const addDangerAlert = () => { this.addAlert('Toast danger alert', 'danger', getUniqueId()) };
|
|
122
|
+
const addInfoAlert = () => { this.addAlert('Toast info alert', 'info', getUniqueId()) };
|
|
123
|
+
const onOverflowClick = () => {
|
|
124
|
+
console.log('Overflow message clicked');
|
|
125
|
+
};
|
|
126
|
+
return (
|
|
127
|
+
<React.Fragment>
|
|
128
|
+
<InputGroup style={{ marginBottom: '16px' }}>
|
|
129
|
+
<button onClick={addSuccessAlert} type="button" className={btnClasses}>Add toast success alert</button>
|
|
130
|
+
<button onClick={addDangerAlert} type="button" className={btnClasses}>Add toast danger alert</button>
|
|
131
|
+
<button onClick={addInfoAlert} type="button" className={btnClasses}>Add toast info alert</button>
|
|
132
|
+
</InputGroup>
|
|
133
|
+
<AlertGroup isToast isLiveRegion onOverflowClick={onOverflowClick} overflowMessage={this.state.overflowMessage}>
|
|
134
|
+
{this.state.alerts.slice(0, this.state.maxDisplayed).map(({key, variant, title}) => (
|
|
135
|
+
<Alert
|
|
136
|
+
variant={AlertVariant[variant]}
|
|
137
|
+
title={title}
|
|
138
|
+
actionClose={
|
|
139
|
+
<AlertActionCloseButton
|
|
140
|
+
title={title}
|
|
141
|
+
variantLabel={`${variant} alert`}
|
|
142
|
+
onClose={() => this.removeAlert(key)}
|
|
143
|
+
/>
|
|
144
|
+
}
|
|
145
|
+
key={key} />
|
|
146
|
+
))}
|
|
147
|
+
</AlertGroup>
|
|
148
|
+
</React.Fragment>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
81
154
|
### Singular dynamic alert group
|
|
82
155
|
This alert will appear in the page, most likely in response to a user action.
|
|
83
156
|
```js
|
|
@@ -131,6 +204,80 @@ class SingularAdditiveAlertGroup extends React.Component {
|
|
|
131
204
|
}
|
|
132
205
|
```
|
|
133
206
|
|
|
207
|
+
### Singular dynamic alert group with overflow message
|
|
208
|
+
This alert will appear in the page, most likely in response to a user action. In this example we are showing a max of 4 alerts.
|
|
209
|
+
```js isBeta
|
|
210
|
+
import React from 'react';
|
|
211
|
+
import { Alert, AlertGroup, AlertVariant, AlertActionCloseButton, InputGroup } from '@patternfly/react-core';
|
|
212
|
+
class SingularAdditiveAlertGroup extends React.Component {
|
|
213
|
+
constructor() {
|
|
214
|
+
super();
|
|
215
|
+
this.state = {
|
|
216
|
+
alerts: [],
|
|
217
|
+
maxDisplayed: "4",
|
|
218
|
+
overflowMessage: ''
|
|
219
|
+
};
|
|
220
|
+
this.getOverflowMessage = (alertsNumber) => {
|
|
221
|
+
const overflow = alertsNumber - this.state.maxDisplayed;
|
|
222
|
+
if (overflow > 0) {
|
|
223
|
+
return "View " + (overflow) + " more alerts";
|
|
224
|
+
}
|
|
225
|
+
return '';
|
|
226
|
+
};
|
|
227
|
+
this.addAlert = (title, variant, key) => {
|
|
228
|
+
this.setState({
|
|
229
|
+
...this.state,
|
|
230
|
+
alerts: [ ...this.state.alerts, { title: title, variant: variant, key }],
|
|
231
|
+
overflowMessage: this.getOverflowMessage(this.state.alerts.length + 1)
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
this.removeAlert = key => {
|
|
235
|
+
const newAlerts = [...this.state.alerts.filter(el => el.key !== key)];
|
|
236
|
+
this.setState({
|
|
237
|
+
...this.state,
|
|
238
|
+
alerts: newAlerts,
|
|
239
|
+
overflowMessage: this.getOverflowMessage(newAlerts.length)
|
|
240
|
+
});
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
render() {
|
|
244
|
+
const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
|
|
245
|
+
const getUniqueId = () => (new Date().getTime());
|
|
246
|
+
const addSuccessAlert = () => { this.addAlert('Single success alert', 'success', getUniqueId()) };
|
|
247
|
+
const addDangerAlert = () => { this.addAlert('Single danger alert', 'danger', getUniqueId()) };
|
|
248
|
+
const addInfoAlert = () => { this.addAlert('Single info alert', 'info', getUniqueId()) };
|
|
249
|
+
const onOverflowClick = () => {
|
|
250
|
+
console.log('Overflow message clicked');
|
|
251
|
+
};
|
|
252
|
+
return (
|
|
253
|
+
<React.Fragment>
|
|
254
|
+
<InputGroup style={{ marginBottom: '16px' }}>
|
|
255
|
+
<button onClick={addSuccessAlert} type="button" className={btnClasses}>Add single success alert</button>
|
|
256
|
+
<button onClick={addDangerAlert} type="button" className={btnClasses}>Add single danger alert</button>
|
|
257
|
+
<button onClick={addInfoAlert} type="button" className={btnClasses}>Add single info alert</button>
|
|
258
|
+
</InputGroup>
|
|
259
|
+
<AlertGroup isLiveRegion overflowMessage={this.state.overflowMessage} onOverflowClick={onOverflowClick}>
|
|
260
|
+
{this.state.alerts.slice(0, this.state.maxDisplayed).map(({ title, variant, key }) => (
|
|
261
|
+
<Alert
|
|
262
|
+
isInline
|
|
263
|
+
variant={AlertVariant[variant]}
|
|
264
|
+
title={title}
|
|
265
|
+
key={key}
|
|
266
|
+
actionClose={
|
|
267
|
+
<AlertActionCloseButton
|
|
268
|
+
title={title}
|
|
269
|
+
variantLabel={`${variant} alert`}
|
|
270
|
+
onClose={() => this.removeAlert(key)}
|
|
271
|
+
/>
|
|
272
|
+
}/>
|
|
273
|
+
))}
|
|
274
|
+
</AlertGroup>
|
|
275
|
+
</React.Fragment>
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
134
281
|
### Multiple dynamic alert group
|
|
135
282
|
These alerts will appear in the page, most likely in response to a user action.
|
|
136
283
|
```js
|
|
@@ -1,22 +1,43 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
|
+
import { MultipleFileUploadTitle } from './MultipleFileUploadTitle';
|
|
5
|
+
import { MultipleFileUploadButton } from './MultipleFileUploadButton';
|
|
6
|
+
import { MultipleFileUploadInfo } from './MultipleFileUploadInfo';
|
|
4
7
|
|
|
5
8
|
export interface MultipleFileUploadMainProps extends React.HTMLProps<HTMLDivElement> {
|
|
6
|
-
/** Content rendered inside multiple file upload main */
|
|
7
|
-
children?: React.ReactNode;
|
|
8
9
|
/** Class to add to outer div */
|
|
9
10
|
className?: string;
|
|
11
|
+
/** Content rendered inside the title icon div */
|
|
12
|
+
titleIcon?: React.ReactNode;
|
|
13
|
+
/** Content rendered inside the title text div */
|
|
14
|
+
titleText?: React.ReactNode;
|
|
15
|
+
/** Content rendered inside the title text separator div */
|
|
16
|
+
titleTextSeparator?: React.ReactNode;
|
|
17
|
+
/** Content rendered inside the info div */
|
|
18
|
+
infoText?: React.ReactNode;
|
|
19
|
+
/** Flag to prevent the upload button from being rendered */
|
|
20
|
+
isUploadButtonHidden?: boolean;
|
|
10
21
|
}
|
|
11
22
|
|
|
12
23
|
export const MultipleFileUploadMain: React.FunctionComponent<MultipleFileUploadMainProps> = ({
|
|
13
24
|
className,
|
|
14
|
-
|
|
25
|
+
titleIcon,
|
|
26
|
+
titleText,
|
|
27
|
+
titleTextSeparator,
|
|
28
|
+
infoText,
|
|
29
|
+
isUploadButtonHidden,
|
|
15
30
|
...props
|
|
16
|
-
}: MultipleFileUploadMainProps) =>
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
31
|
+
}: MultipleFileUploadMainProps) => {
|
|
32
|
+
const showTitle = !!titleIcon || !!titleText || !!titleTextSeparator;
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className={css(styles.multipleFileUploadMain, className)} {...props}>
|
|
36
|
+
{showTitle && <MultipleFileUploadTitle icon={titleIcon} text={titleText} textSeparator={titleTextSeparator} />}
|
|
37
|
+
{isUploadButtonHidden || <MultipleFileUploadButton />}
|
|
38
|
+
{!!infoText && <MultipleFileUploadInfo>{infoText}</MultipleFileUploadInfo>}
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
21
42
|
|
|
22
43
|
MultipleFileUploadMain.displayName = 'MultipleFileUploadMain';
|
|
@@ -2,6 +2,9 @@ import * as React from 'react';
|
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
4
|
import { ExpandableSection } from '../ExpandableSection';
|
|
5
|
+
import InProgressIcon from '@patternfly/react-icons/dist/esm/icons/in-progress-icon';
|
|
6
|
+
import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle-icon';
|
|
7
|
+
import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon';
|
|
5
8
|
|
|
6
9
|
export interface MultipleFileUploadStatusProps extends React.HTMLProps<HTMLDivElement> {
|
|
7
10
|
/** Content rendered inside multi file upload status list */
|
|
@@ -11,7 +14,7 @@ export interface MultipleFileUploadStatusProps extends React.HTMLProps<HTMLDivEl
|
|
|
11
14
|
/** String to show in the status toggle */
|
|
12
15
|
statusToggleText?: string;
|
|
13
16
|
/** Icon to show in the status toggle */
|
|
14
|
-
statusToggleIcon?: React.ReactNode;
|
|
17
|
+
statusToggleIcon?: 'danger' | 'success' | 'inProgress' | React.ReactNode;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
20
|
export const MultipleFileUploadStatus: React.FunctionComponent<MultipleFileUploadStatusProps> = ({
|
|
@@ -21,15 +24,32 @@ export const MultipleFileUploadStatus: React.FunctionComponent<MultipleFileUploa
|
|
|
21
24
|
statusToggleIcon,
|
|
22
25
|
...props
|
|
23
26
|
}: MultipleFileUploadStatusProps) => {
|
|
27
|
+
const [icon, setIcon] = React.useState<React.ReactNode>();
|
|
28
|
+
const [isOpen, setIsOpen] = React.useState(true);
|
|
29
|
+
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
switch (statusToggleIcon) {
|
|
32
|
+
case 'danger':
|
|
33
|
+
setIcon(<TimesCircleIcon />);
|
|
34
|
+
break;
|
|
35
|
+
case 'success':
|
|
36
|
+
setIcon(<CheckCircleIcon />);
|
|
37
|
+
break;
|
|
38
|
+
case 'inProgress':
|
|
39
|
+
setIcon(<InProgressIcon />);
|
|
40
|
+
break;
|
|
41
|
+
default:
|
|
42
|
+
setIcon(statusToggleIcon);
|
|
43
|
+
}
|
|
44
|
+
}, [statusToggleIcon]);
|
|
45
|
+
|
|
24
46
|
const toggle = (
|
|
25
47
|
<div className={styles.multipleFileUploadStatusProgress}>
|
|
26
|
-
<div className={styles.multipleFileUploadStatusProgressIcon}>{
|
|
48
|
+
<div className={styles.multipleFileUploadStatusProgressIcon}>{icon}</div>
|
|
27
49
|
<div className={styles.multipleFileUploadStatusItemProgressText}>{statusToggleText}</div>
|
|
28
50
|
</div>
|
|
29
51
|
);
|
|
30
52
|
|
|
31
|
-
const [isOpen, setIsOpen] = React.useState(true);
|
|
32
|
-
|
|
33
53
|
const toggleExpandableSection = () => {
|
|
34
54
|
setIsOpen(!isOpen);
|
|
35
55
|
};
|
|
@@ -65,7 +65,7 @@ export const MultipleFileUploadStatusItem: React.FunctionComponent<MultipleFileU
|
|
|
65
65
|
progressAriaLabelledBy,
|
|
66
66
|
buttonAriaLabel = 'Remove from list',
|
|
67
67
|
...props
|
|
68
|
-
}) => {
|
|
68
|
+
}: MultipleFileUploadStatusItemProps) => {
|
|
69
69
|
const [loadPercentage, setLoadPercentage] = React.useState(0);
|
|
70
70
|
const [loadResult, setLoadResult] = React.useState<undefined | 'danger' | 'success'>();
|
|
71
71
|
|
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
|
-
|
|
4
|
+
import { MultipleFileUploadTitleIcon } from './MultipleFileUploadTitleIcon';
|
|
5
|
+
import { MultipleFileUploadTitleText } from './MultipleFileUploadTitleText';
|
|
6
|
+
import { MultipleFileUploadTitleTextSeparator } from './MultipleFileUploadTitleTextSeparator';
|
|
5
7
|
export interface MultipleFileUploadTitleProps extends React.HTMLProps<HTMLDivElement> {
|
|
6
|
-
/** Content rendered inside multiple file upload title */
|
|
7
|
-
children?: React.ReactNode;
|
|
8
8
|
/** Class to add to outer div */
|
|
9
9
|
className?: string;
|
|
10
|
+
/** Content rendered inside the title icon div */
|
|
11
|
+
icon?: React.ReactNode;
|
|
12
|
+
/** Content rendered inside the title text div */
|
|
13
|
+
text?: React.ReactNode;
|
|
14
|
+
/** Content rendered inside the title text separator div */
|
|
15
|
+
textSeparator?: React.ReactNode;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
export const MultipleFileUploadTitle: React.FunctionComponent<MultipleFileUploadTitleProps> = ({
|
|
13
19
|
className,
|
|
14
|
-
|
|
20
|
+
icon,
|
|
21
|
+
text = '',
|
|
22
|
+
textSeparator = '',
|
|
15
23
|
...props
|
|
16
24
|
}: MultipleFileUploadTitleProps) => (
|
|
17
25
|
<div className={css(styles.multipleFileUploadTitle, className)} {...props}>
|
|
18
|
-
{
|
|
26
|
+
{icon && <MultipleFileUploadTitleIcon>{icon}</MultipleFileUploadTitleIcon>}
|
|
27
|
+
{text && (
|
|
28
|
+
<MultipleFileUploadTitleText>
|
|
29
|
+
{`${text} `}
|
|
30
|
+
{textSeparator && <MultipleFileUploadTitleTextSeparator>{textSeparator}</MultipleFileUploadTitleTextSeparator>}
|
|
31
|
+
</MultipleFileUploadTitleText>
|
|
32
|
+
)}
|
|
19
33
|
</div>
|
|
20
34
|
);
|
|
21
35
|
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styles from '@patternfly/react-styles/css/components/MultipleFileUpload/multiple-file-upload';
|
|
3
3
|
import { css } from '@patternfly/react-styles';
|
|
4
|
-
import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon';
|
|
5
|
-
|
|
6
4
|
export interface MultipleFileUploadTitleIconProps extends React.HTMLProps<HTMLDivElement> {
|
|
5
|
+
/** Content rendered inside multiple file upload title icon */
|
|
6
|
+
children?: React.ReactNode;
|
|
7
7
|
/** Class to add to outer div */
|
|
8
8
|
className?: string;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export const MultipleFileUploadTitleIcon: React.FunctionComponent<MultipleFileUploadTitleIconProps> = ({
|
|
12
|
+
children,
|
|
12
13
|
className,
|
|
13
14
|
...props
|
|
14
15
|
}: MultipleFileUploadTitleIconProps) => (
|
|
15
16
|
<div className={css(styles.multipleFileUploadTitleIcon, className)} {...props}>
|
|
16
|
-
|
|
17
|
+
{children}
|
|
17
18
|
</div>
|
|
18
19
|
);
|
|
19
20
|
|
|
@@ -4,12 +4,29 @@ import { MultipleFileUploadMain } from '../MultipleFileUploadMain';
|
|
|
4
4
|
|
|
5
5
|
describe('MultipleFileUploadMain', () => {
|
|
6
6
|
test('renders with expected class names', () => {
|
|
7
|
-
const view = mount(<MultipleFileUploadMain
|
|
7
|
+
const view = mount(<MultipleFileUploadMain />);
|
|
8
8
|
expect(view).toMatchSnapshot();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
test('renders custom class names', () => {
|
|
12
|
-
const view = mount(<MultipleFileUploadMain className="test"
|
|
12
|
+
const view = mount(<MultipleFileUploadMain className="test" />);
|
|
13
|
+
expect(view).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('passes props to the title as expected', () => {
|
|
17
|
+
const view = mount(
|
|
18
|
+
<MultipleFileUploadMain titleIcon="icon" titleText="title text" titleTextSeparator="title test separator" />
|
|
19
|
+
);
|
|
20
|
+
expect(view).toMatchSnapshot();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('renders without the button when expected', () => {
|
|
24
|
+
const view = mount(<MultipleFileUploadMain isUploadButtonHidden />);
|
|
25
|
+
expect(view).toMatchSnapshot();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('passes props to the info component as expected', () => {
|
|
29
|
+
const view = mount(<MultipleFileUploadMain infoText="info text" />);
|
|
13
30
|
expect(view).toMatchSnapshot();
|
|
14
31
|
});
|
|
15
32
|
});
|
|
@@ -4,12 +4,27 @@ import { MultipleFileUploadTitle } from '../MultipleFileUploadTitle';
|
|
|
4
4
|
|
|
5
5
|
describe('MultipleFileUploadTitle', () => {
|
|
6
6
|
test('renders with expected class names', () => {
|
|
7
|
-
const view = mount(<MultipleFileUploadTitle
|
|
7
|
+
const view = mount(<MultipleFileUploadTitle />);
|
|
8
8
|
expect(view).toMatchSnapshot();
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
test('renders custom class names', () => {
|
|
12
|
-
const view = mount(<MultipleFileUploadTitle className="test"
|
|
12
|
+
const view = mount(<MultipleFileUploadTitle className="test" />);
|
|
13
|
+
expect(view).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('renders with title icon', () => {
|
|
17
|
+
const view = mount(<MultipleFileUploadTitle icon="icon" />);
|
|
18
|
+
expect(view).toMatchSnapshot();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('renders with title text', () => {
|
|
22
|
+
const view = mount(<MultipleFileUploadTitle text="text" />);
|
|
23
|
+
expect(view).toMatchSnapshot();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('renders with title text separator', () => {
|
|
27
|
+
const view = mount(<MultipleFileUploadTitle text="text" textSeparator="text separator" />);
|
|
13
28
|
expect(view).toMatchSnapshot();
|
|
14
29
|
});
|
|
15
30
|
});
|
|
@@ -4,7 +4,7 @@ import { MultipleFileUploadTitleIcon } from '../MultipleFileUploadTitleIcon';
|
|
|
4
4
|
|
|
5
5
|
describe('MultipleFileUploadTitleIcon', () => {
|
|
6
6
|
test('renders with expected class names', () => {
|
|
7
|
-
const view = mount(<MultipleFileUploadTitleIcon
|
|
7
|
+
const view = mount(<MultipleFileUploadTitleIcon>Foo</MultipleFileUploadTitleIcon>);
|
|
8
8
|
expect(view).toMatchSnapshot();
|
|
9
9
|
});
|
|
10
10
|
|