@patternfly/react-core 4.208.9 → 4.208.12

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.
Files changed (32) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/esm/helpers/index.d.ts +1 -0
  3. package/dist/esm/helpers/index.d.ts.map +1 -1
  4. package/dist/esm/helpers/index.js +1 -0
  5. package/dist/esm/helpers/index.js.map +1 -1
  6. package/dist/esm/helpers/useInterval.d.ts +6 -0
  7. package/dist/esm/helpers/useInterval.d.ts.map +1 -0
  8. package/dist/esm/helpers/useInterval.js +21 -0
  9. package/dist/esm/helpers/useInterval.js.map +1 -0
  10. package/dist/js/helpers/index.d.ts +1 -0
  11. package/dist/js/helpers/index.d.ts.map +1 -1
  12. package/dist/js/helpers/index.js +1 -0
  13. package/dist/js/helpers/index.js.map +1 -1
  14. package/dist/js/helpers/useInterval.d.ts +6 -0
  15. package/dist/js/helpers/useInterval.d.ts.map +1 -0
  16. package/dist/js/helpers/useInterval.js +26 -0
  17. package/dist/js/helpers/useInterval.js.map +1 -0
  18. package/dist/umd/react-core.css +17 -15
  19. package/dist/umd/react-core.js +22 -0
  20. package/dist/umd/react-core.min.css +92 -90
  21. package/dist/umd/react-core.min.js +1 -1
  22. package/package.json +6 -6
  23. package/src/components/AlertGroup/examples/AlertGroup.md +7 -361
  24. package/src/components/AlertGroup/examples/AlertGroupAsync.tsx +73 -0
  25. package/src/components/AlertGroup/examples/AlertGroupMultipleDynamic.tsx +59 -0
  26. package/src/components/AlertGroup/examples/AlertGroupSingularDynamic.tsx +70 -0
  27. package/src/components/AlertGroup/examples/AlertGroupSingularDynamicOverflow.tsx +89 -0
  28. package/src/components/AlertGroup/examples/AlertGroupStatic.tsx +11 -0
  29. package/src/components/AlertGroup/examples/AlertGroupToast.tsx +69 -0
  30. package/src/components/AlertGroup/examples/AlertGroupToastOverflowCapture.tsx +88 -0
  31. package/src/helpers/index.ts +1 -0
  32. package/src/helpers/useInterval.ts +25 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.208.9",
3
+ "version": "4.208.12",
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.59.9",
38
- "@patternfly/react-styles": "^4.58.9",
39
- "@patternfly/react-tokens": "^4.60.9",
37
+ "@patternfly/react-icons": "^4.59.12",
38
+ "@patternfly/react-styles": "^4.58.12",
39
+ "@patternfly/react-tokens": "^4.60.12",
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.192.6",
46
+ "@patternfly/patternfly": "4.193.0",
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": "c6f914ae9d27bef2b8e14c12de7da5cb7e043614"
63
+ "gitHead": "29bbfb4f27300b3d03b244e41b56fa79a37040d2"
64
64
  }
@@ -8,389 +8,35 @@ propComponents: ['Alert', 'AlertGroup', 'AlertActionCloseButton', 'AlertActionLi
8
8
  ## Examples
9
9
  ### Static alert group
10
10
  These alerts appear on page load and are discoverable from within the normal page content flow, and will not be announced individually/explicitly to assistive technology.
11
- ```js
12
- import React from 'react';
13
- import { Alert, AlertGroup } from '@patternfly/react-core';
14
-
15
- class StaticAlertGroup extends React.Component {
16
- render() {
17
- return (
18
- <React.Fragment>
19
- <AlertGroup>
20
- <Alert title="Success alert" variant="success" isInline />
21
- <Alert title="Info alert" variant="info" isInline/>
22
- </AlertGroup>
23
- </React.Fragment>
24
- );
25
- }
26
- }
11
+ ```ts file="./AlertGroupStatic.tsx"
27
12
  ```
28
13
 
29
14
  ### Toast alert group
30
15
  Alerts asynchronously appended into dynamic AlertGroups with `isLiveRegion` will be announced to assistive technology at the moment the change happens, following the strategy used for aria-atomic, which defaults to false. This means only changes of type "addition" will be announced.
31
- ```js
32
- import React from 'react';
33
- import { Alert, AlertGroup, AlertActionCloseButton, AlertVariant, InputGroup } from '@patternfly/react-core';
34
- class ToastAlertGroup extends React.Component {
35
- constructor() {
36
- super();
37
- this.state = { alerts: [] };
38
- this.addAlert = (title, variant, key) => {
39
- this.setState({
40
- alerts: [ ...this.state.alerts, { title: title, variant: variant, key }]
41
- });
42
- };
43
- this.removeAlert = key => {
44
- this.setState({ alerts: [...this.state.alerts.filter(el => el.key !== key)] });
45
- };
46
- }
47
- render() {
48
- const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
49
- const getUniqueId = () => (new Date().getTime());
50
- const addSuccessAlert = () => { this.addAlert('Toast success alert', 'success', getUniqueId()) };
51
- const addDangerAlert = () => { this.addAlert('Toast danger alert', 'danger', getUniqueId()) };
52
- const addInfoAlert = () => { this.addAlert('Toast info alert', 'info', getUniqueId()) };
53
- return (
54
- <React.Fragment>
55
- <InputGroup style={{ marginBottom: '16px' }}>
56
- <button onClick={addSuccessAlert} type="button" className={btnClasses}>Add toast success alert</button>
57
- <button onClick={addDangerAlert} type="button" className={btnClasses}>Add toast danger alert</button>
58
- <button onClick={addInfoAlert} type="button" className={btnClasses}>Add toast info alert</button>
59
- </InputGroup>
60
- <AlertGroup isToast isLiveRegion>
61
- {this.state.alerts.map(({key, variant, title}) => (
62
- <Alert
63
- variant={AlertVariant[variant]}
64
- title={title}
65
- actionClose={
66
- <AlertActionCloseButton
67
- title={title}
68
- variantLabel={`${variant} alert`}
69
- onClose={() => this.removeAlert(key)}
70
- />
71
- }
72
- key={key} />
73
- ))}
74
- </AlertGroup>
75
- </React.Fragment>
76
- );
77
- }
78
- }
16
+ ```ts file="./AlertGroupToast.tsx"
79
17
  ```
80
18
 
81
19
  ### Toast alert group with overflow capture
82
20
  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
- }
21
+ ```ts file="AlertGroupToastOverflowCapture.tsx" isBeta
152
22
  ```
153
23
 
154
24
  ### Singular dynamic alert group
155
25
  This alert will appear in the page, most likely in response to a user action.
156
- ```js
157
- import React from 'react';
158
- import { Alert, AlertGroup, AlertVariant, AlertActionCloseButton, InputGroup } from '@patternfly/react-core';
159
- class SingularAdditiveAlertGroup extends React.Component {
160
- constructor() {
161
- super();
162
- this.state = {
163
- alerts: []
164
- }
165
- }
166
- render() {
167
- const addAlert = (title, variant, key) => {
168
- this.setState({ alerts: [...this.state.alerts, { title: title, variant: variant, key }] });
169
- };
170
- const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
171
- const getUniqueId = () => (new Date().getTime());
172
- const addSuccessAlert = () => { addAlert('Single success alert', 'success', getUniqueId()) };
173
- const addDangerAlert = () => { addAlert('Single danger alert', 'danger', getUniqueId()) };
174
- const addInfoAlert = () => { addAlert('Single info alert', 'info', getUniqueId()) };
175
- this.removeAlert = key => {
176
- this.setState({ alerts: [...this.state.alerts.filter(el => el.key !== key)] });
177
- };
178
- return (
179
- <React.Fragment>
180
- <InputGroup style={{ marginBottom: '16px' }}>
181
- <button onClick={addSuccessAlert} type="button" className={btnClasses}>Add single success alert</button>
182
- <button onClick={addDangerAlert} type="button" className={btnClasses}>Add single danger alert</button>
183
- <button onClick={addInfoAlert} type="button" className={btnClasses}>Add single info alert</button>
184
- </InputGroup>
185
- <AlertGroup isLiveRegion>
186
- {this.state.alerts.map(({ title, variant, key }) => (
187
- <Alert
188
- isInline
189
- variant={AlertVariant[variant]}
190
- title={title}
191
- key={key}
192
- actionClose={
193
- <AlertActionCloseButton
194
- title={title}
195
- variantLabel={`${variant} alert`}
196
- onClose={() => this.removeAlert(key)}
197
- />
198
- }/>
199
- ))}
200
- </AlertGroup>
201
- </React.Fragment>
202
- );
203
- }
204
- }
26
+ ```ts file="./AlertGroupSingularDynamic.tsx"
205
27
  ```
206
28
 
207
29
  ### Singular dynamic alert group with overflow message
208
30
  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
- }
31
+ ```ts file="AlertGroupSingularDynamicOverflow.tsx" isBeta
279
32
  ```
280
33
 
281
34
  ### Multiple dynamic alert group
282
35
  These alerts will appear in the page, most likely in response to a user action.
283
- ```js
284
- import React from 'react';
285
- import { Alert, AlertGroup, AlertVariant, AlertActionCloseButton, InputGroup } from '@patternfly/react-core';
286
- class MultipleAdditiveAlertGroup extends React.Component {
287
- constructor() {
288
- super();
289
- this.state = {
290
- alerts: []
291
- }
292
- }
293
- render() {
294
- const addAlerts = (incomingAlerts) => {
295
- this.setState({ alerts: [...this.state.alerts, ...incomingAlerts] });
296
- };
297
- const getUniqueId = () => (
298
- (String.fromCharCode(65 + Math.floor(Math.random() * 26))+ Date.now())
299
- );
300
- const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
301
- const addAlertCollection = () => {
302
- addAlerts([
303
- { title: 'First alert notification.', variant: 'success', key: getUniqueId() },
304
- { title: 'Second alert notification.', variant: 'warning', key: getUniqueId() },
305
- { title: 'Third alert notification.', variant: 'danger', key: getUniqueId() }
306
- ])
307
- };
308
- this.removeAlert = key => {
309
- this.setState({ alerts: [...this.state.alerts.filter(el => el.key !== key)] });
310
- };
311
- return (
312
- <React.Fragment>
313
- <InputGroup style={{ marginBottom: '16px' }}>
314
- <button onClick={addAlertCollection} type="button" className={btnClasses}>Add alert collection</button>
315
- </InputGroup>
316
- <AlertGroup isToast isLiveRegion>
317
- {this.state.alerts.map(({ title, variant, key, action }) => (
318
- <Alert
319
- variant={AlertVariant[variant]}
320
- title={title}
321
- key={key}
322
- actionClose={
323
- <AlertActionCloseButton
324
- title={title}
325
- variantLabel={`${variant} alert`}
326
- onClose={() => this.removeAlert(key)}
327
- />
328
- }/>
329
- ))}
330
- </AlertGroup>
331
- </React.Fragment>
332
- );
333
- }
334
- }
36
+ ```ts file="./AlertGroupMultipleDynamic.tsx"
335
37
  ```
336
38
 
337
39
  ### Async alert group
338
40
  This shows how an alert could be triggered by an asynchronous event in the application. Note how you can customize how the alert will be announced to assistive technology. See the alert group accessibility tab for more information.
339
- ```js
340
- import React from 'react';
341
- import { Alert, AlertGroup, AlertActionCloseButton, AlertVariant, InputGroup } from '@patternfly/react-core';
342
- class AsyncAdditiveAlertGroup extends React.Component {
343
- constructor() {
344
- super();
345
- this.state = {
346
- alerts: [],
347
- timer: null
348
- }
349
- this.stopAsyncAlerts = () => { clearInterval(this.state.timer); }
350
- }
351
- componentWillUnmount() { this.stopAsyncAlerts(); }
352
- render() {
353
- const addAlerts = (incomingAlerts) => { this.setState({ alerts: [...this.state.alerts, ...incomingAlerts] }); };
354
- const getUniqueId = () => (new Date().getTime());
355
- const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
356
- this.removeAlert = key => {
357
- this.setState({ alerts: [...this.state.alerts.filter(el => el.key !== key)] });
358
- };
359
- const startAsyncAlerts = () => {
360
- let timerValue = setInterval(() => {
361
- addAlerts([
362
- {
363
- title: `Async notification ${this.state.alerts.length + 1} was added to the queue.`,
364
- variant: 'danger',
365
- key: getUniqueId()
366
- }
367
- ])
368
- }, 4500);
369
- this.setState({timer: timerValue});
370
- };
371
- return (
372
- <React.Fragment>
373
- <InputGroup style={{ marginBottom: '16px' }}>
374
- <button onClick={startAsyncAlerts} type="button" className={btnClasses}>Start async alerts</button>
375
- <button onClick={this.stopAsyncAlerts} type="button" className={btnClasses}>Stop async alerts</button>
376
- </InputGroup>
377
- <AlertGroup isToast isLiveRegion aria-live="assertive">
378
- {this.state.alerts.map(({ title, variant, key }) => (
379
- <Alert
380
- variant={AlertVariant[variant]}
381
- title={title}
382
- key={key}
383
- actionClose={
384
- <AlertActionCloseButton
385
- title={title}
386
- variantLabel={`${variant} alert`}
387
- onClose={() => this.removeAlert(key)}
388
- />
389
- }/>
390
- ))}
391
- </AlertGroup>
392
- </React.Fragment>
393
- );
394
- }
395
- }
41
+ ```ts file="./AlertGroupAsync.tsx"
396
42
  ```
@@ -0,0 +1,73 @@
1
+ import React from 'react';
2
+ import {
3
+ Alert,
4
+ AlertProps,
5
+ AlertGroup,
6
+ AlertActionCloseButton,
7
+ AlertVariant,
8
+ InputGroup,
9
+ useInterval
10
+ } from '@patternfly/react-core';
11
+
12
+ export const AlertGroupAsync: React.FunctionComponent = () => {
13
+ const [alerts, setAlerts] = React.useState<Partial<AlertProps>[]>([]);
14
+ const [isRunning, setIsRunning] = React.useState(false);
15
+
16
+ const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
17
+
18
+ const getUniqueId = () => new Date().getTime();
19
+
20
+ const addAlert = () => {
21
+ setAlerts(prevAlerts => [
22
+ ...prevAlerts,
23
+ {
24
+ title: `Async notification ${prevAlerts.length + 1} was added to the queue.`,
25
+ variant: 'danger',
26
+ key: getUniqueId()
27
+ }
28
+ ]);
29
+ };
30
+
31
+ const removeAlert = (key: React.Key) => {
32
+ setAlerts(prevAlerts => [...prevAlerts.filter(alert => alert.key !== key)]);
33
+ };
34
+
35
+ const startAsyncAlerts = () => {
36
+ setIsRunning(true);
37
+ };
38
+
39
+ const stopAsyncAlerts = () => {
40
+ setIsRunning(false);
41
+ };
42
+
43
+ useInterval(addAlert, isRunning ? 4500 : null);
44
+
45
+ return (
46
+ <React.Fragment>
47
+ <InputGroup style={{ marginBottom: '16px' }}>
48
+ <button onClick={startAsyncAlerts} type="button" className={btnClasses}>
49
+ Start async alerts
50
+ </button>
51
+ <button onClick={stopAsyncAlerts} type="button" className={btnClasses}>
52
+ Stop async alerts
53
+ </button>
54
+ </InputGroup>
55
+ <AlertGroup isToast isLiveRegion aria-live="assertive">
56
+ {alerts.map(({ title, variant, key }) => (
57
+ <Alert
58
+ variant={AlertVariant[variant]}
59
+ title={title}
60
+ key={key}
61
+ actionClose={
62
+ <AlertActionCloseButton
63
+ title={title as string}
64
+ variantLabel={`${variant} alert`}
65
+ onClose={() => removeAlert(key)}
66
+ />
67
+ }
68
+ />
69
+ ))}
70
+ </AlertGroup>
71
+ </React.Fragment>
72
+ );
73
+ };
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import {
3
+ Alert,
4
+ AlertProps,
5
+ AlertGroup,
6
+ AlertActionCloseButton,
7
+ AlertVariant,
8
+ InputGroup
9
+ } from '@patternfly/react-core';
10
+
11
+ export const AlertGroupMultipleDynamic: React.FunctionComponent = () => {
12
+ const [alerts, setAlerts] = React.useState<Partial<AlertProps>[]>([]);
13
+
14
+ const addAlerts = (incomingAlerts: Partial<AlertProps>[]) => {
15
+ setAlerts(prevAlerts => [...prevAlerts, ...incomingAlerts]);
16
+ };
17
+
18
+ const removeAlert = (key: React.Key) => {
19
+ setAlerts(prevAlerts => [...prevAlerts.filter(alert => alert.key !== key)]);
20
+ };
21
+
22
+ const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
23
+
24
+ const getUniqueId = () => String.fromCharCode(65 + Math.floor(Math.random() * 26)) + Date.now();
25
+
26
+ const addAlertCollection = () => {
27
+ addAlerts([
28
+ { title: 'First alert notification.', variant: 'success', key: getUniqueId() },
29
+ { title: 'Second alert notification.', variant: 'warning', key: getUniqueId() },
30
+ { title: 'Third alert notification.', variant: 'danger', key: getUniqueId() }
31
+ ]);
32
+ };
33
+
34
+ return (
35
+ <React.Fragment>
36
+ <InputGroup style={{ marginBottom: '16px' }}>
37
+ <button onClick={addAlertCollection} type="button" className={btnClasses}>
38
+ Add alert collection
39
+ </button>
40
+ </InputGroup>
41
+ <AlertGroup isToast isLiveRegion>
42
+ {alerts.map(({ title, variant, key }) => (
43
+ <Alert
44
+ variant={AlertVariant[variant]}
45
+ title={title}
46
+ key={key}
47
+ actionClose={
48
+ <AlertActionCloseButton
49
+ title={title as string}
50
+ variantLabel={`${variant} alert`}
51
+ onClose={() => removeAlert(key)}
52
+ />
53
+ }
54
+ />
55
+ ))}
56
+ </AlertGroup>
57
+ </React.Fragment>
58
+ );
59
+ };
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import {
3
+ Alert,
4
+ AlertProps,
5
+ AlertGroup,
6
+ AlertActionCloseButton,
7
+ AlertVariant,
8
+ InputGroup
9
+ } from '@patternfly/react-core';
10
+
11
+ export const AlertGroupSingularDynamic: React.FunctionComponent = () => {
12
+ const [alerts, setAlerts] = React.useState<Partial<AlertProps>[]>([]);
13
+
14
+ const addAlert = (title: string, variant: AlertProps['variant'], key: React.Key) => {
15
+ setAlerts(prevAlerts => [...prevAlerts, { title, variant, key }]);
16
+ };
17
+
18
+ const removeAlert = (key: React.Key) => {
19
+ setAlerts(prevAlerts => [...prevAlerts.filter(alert => alert.key !== key)]);
20
+ };
21
+
22
+ const btnClasses = ['pf-c-button', 'pf-m-secondary'].join(' ');
23
+
24
+ const getUniqueId = () => new Date().getTime();
25
+
26
+ const addSuccessAlert = () => {
27
+ addAlert('Toast success alert', 'success', getUniqueId());
28
+ };
29
+
30
+ const addDangerAlert = () => {
31
+ addAlert('Toast danger alert', 'danger', getUniqueId());
32
+ };
33
+
34
+ const addInfoAlert = () => {
35
+ addAlert('Toast info alert', 'info', getUniqueId());
36
+ };
37
+
38
+ return (
39
+ <React.Fragment>
40
+ <InputGroup style={{ marginBottom: '16px' }}>
41
+ <button onClick={addSuccessAlert} type="button" className={btnClasses}>
42
+ Add single success alert
43
+ </button>
44
+ <button onClick={addDangerAlert} type="button" className={btnClasses}>
45
+ Add single danger alert
46
+ </button>
47
+ <button onClick={addInfoAlert} type="button" className={btnClasses}>
48
+ Add single info alert
49
+ </button>
50
+ </InputGroup>
51
+ <AlertGroup isLiveRegion>
52
+ {alerts.map(({ title, variant, key }) => (
53
+ <Alert
54
+ isInline
55
+ variant={AlertVariant[variant]}
56
+ title={title}
57
+ key={key}
58
+ actionClose={
59
+ <AlertActionCloseButton
60
+ title={title as string}
61
+ variantLabel={`${variant} alert`}
62
+ onClose={() => removeAlert(key)}
63
+ />
64
+ }
65
+ />
66
+ ))}
67
+ </AlertGroup>
68
+ </React.Fragment>
69
+ );
70
+ };