@instructure/ui-alerts 8.28.1-snapshot-2 → 8.28.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 +5 -2
- package/es/Alert/index.js +20 -45
- package/lib/Alert/index.js +19 -48
- package/package.json +16 -16
- package/src/Alert/index.tsx +41 -52
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Alert/index.d.ts +3 -4
- package/types/Alert/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [8.28.1
|
|
6
|
+
## [8.28.1](https://github.com/instructure/instructure-ui/compare/v8.28.0...v8.28.1) (2022-09-12)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* support react 18 ([972bb93](https://github.com/instructure/instructure-ui/commit/972bb93d2835fcca3548d624b1ba2497661b4243))
|
|
9
12
|
|
|
10
13
|
|
|
11
14
|
|
package/es/Alert/index.js
CHANGED
|
@@ -35,8 +35,7 @@ import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
|
|
35
35
|
import { IconCheckMarkSolid, IconInfoBorderlessSolid, IconWarningBorderlessSolid, IconNoSolid } from '@instructure/ui-icons';
|
|
36
36
|
import { Transition } from '@instructure/ui-motion';
|
|
37
37
|
import { logError as error } from '@instructure/console';
|
|
38
|
-
import {
|
|
39
|
-
import { withStyle, jsx, InstUISettingsProvider } from '@instructure/emotion';
|
|
38
|
+
import { withStyle, jsx } from '@instructure/emotion';
|
|
40
39
|
import generateStyle from './styles';
|
|
41
40
|
import generateComponentTheme from './theme';
|
|
42
41
|
import { propTypes, allowedProps } from './props';
|
|
@@ -96,6 +95,7 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
96
95
|
}
|
|
97
96
|
};
|
|
98
97
|
|
|
98
|
+
this.srid = this.props.deterministicId();
|
|
99
99
|
this.state = {
|
|
100
100
|
open: true
|
|
101
101
|
};
|
|
@@ -140,36 +140,12 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
140
140
|
const liveRegion = this.getLiveRegion();
|
|
141
141
|
|
|
142
142
|
if (liveRegion) {
|
|
143
|
-
this.srid = this.props.deterministicId();
|
|
144
143
|
const div = document.createElement('div');
|
|
145
144
|
div.setAttribute('id', this.srid);
|
|
146
|
-
this.renderScreenreeaderAlert(div);
|
|
147
145
|
liveRegion.appendChild(div);
|
|
148
146
|
}
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
updateScreenreaderAlert() {
|
|
152
|
-
if (this.getLiveRegion()) {
|
|
153
|
-
const div = document.getElementById(this.srid);
|
|
154
|
-
|
|
155
|
-
if (div) {
|
|
156
|
-
ReactDOM.render(null, div, () => {
|
|
157
|
-
this.renderScreenreeaderAlert(div);
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
renderScreenreeaderAlert(div) {
|
|
164
|
-
const content = this.createScreenreaderContentNode();
|
|
165
|
-
ReactDOM.render( // since ScreenReaderContent gets rendered outside the app,
|
|
166
|
-
// and uses the withStyle decorator, we need to provide a theme for it,
|
|
167
|
-
// otherwise throws warning (any theme, doesn't use any theme variables)
|
|
168
|
-
jsx(InstUISettingsProvider, {
|
|
169
|
-
theme: canvas
|
|
170
|
-
}, content), div);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
149
|
removeScreenreaderAlert() {
|
|
174
150
|
const liveRegion = this.getLiveRegion();
|
|
175
151
|
|
|
@@ -177,8 +153,6 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
177
153
|
const div = document.getElementById(this.srid);
|
|
178
154
|
|
|
179
155
|
if (div) {
|
|
180
|
-
var _div$parentNode;
|
|
181
|
-
|
|
182
156
|
// Accessibility attributes must be removed for the deletion of the node
|
|
183
157
|
// and then reapplied because JAWS/IE will not respect the
|
|
184
158
|
// "aria-relevant" attribute and read when the node is deleted if
|
|
@@ -186,8 +160,6 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
186
160
|
liveRegion.removeAttribute('aria-live');
|
|
187
161
|
liveRegion.removeAttribute('aria-relevant');
|
|
188
162
|
liveRegion.removeAttribute('aria-atomic');
|
|
189
|
-
ReactDOM.unmountComponentAtNode(div);
|
|
190
|
-
div === null || div === void 0 ? void 0 : (_div$parentNode = div.parentNode) === null || _div$parentNode === void 0 ? void 0 : _div$parentNode.removeChild(div);
|
|
191
163
|
this.initLiveRegion(liveRegion);
|
|
192
164
|
}
|
|
193
165
|
}
|
|
@@ -204,7 +176,10 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
204
176
|
}
|
|
205
177
|
|
|
206
178
|
this.handleTimeout();
|
|
207
|
-
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
componentWillUnmount() {
|
|
182
|
+
this.clearTimeouts();
|
|
208
183
|
}
|
|
209
184
|
|
|
210
185
|
componentDidUpdate(prevProps) {
|
|
@@ -216,18 +191,9 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
216
191
|
// this outside world is asking us to close the alert, which needs to
|
|
217
192
|
// take place internally so the transition runs
|
|
218
193
|
this.close();
|
|
219
|
-
} else {
|
|
220
|
-
if (this.props.children !== prevProps.children) {
|
|
221
|
-
this.updateScreenreaderAlert();
|
|
222
|
-
}
|
|
223
194
|
}
|
|
224
195
|
}
|
|
225
196
|
|
|
226
|
-
componentWillUnmount() {
|
|
227
|
-
this.removeScreenreaderAlert();
|
|
228
|
-
this.clearTimeouts();
|
|
229
|
-
}
|
|
230
|
-
|
|
231
197
|
renderIcon() {
|
|
232
198
|
var _this$props$styles;
|
|
233
199
|
|
|
@@ -265,24 +231,33 @@ let Alert = (_dec = withDeterministicId(), _dec2 = withStyle(generateStyle, gene
|
|
|
265
231
|
}, this.props.children), this.renderCloseButton());
|
|
266
232
|
}
|
|
267
233
|
|
|
234
|
+
createScreenReaderPortal(liveRegion) {
|
|
235
|
+
const open = this.state.open;
|
|
236
|
+
return open ? /*#__PURE__*/ReactDOM.createPortal(jsx("div", {
|
|
237
|
+
id: this.srid
|
|
238
|
+
}, this.createScreenreaderContentNode()), liveRegion) : null;
|
|
239
|
+
}
|
|
240
|
+
|
|
268
241
|
render() {
|
|
269
|
-
|
|
242
|
+
const liveRegion = this.getLiveRegion();
|
|
243
|
+
const screenReaderContent = liveRegion ? this.createScreenReaderPortal(liveRegion) : null; // Don't render anything if screen reader only
|
|
244
|
+
|
|
270
245
|
if (this.props.screenReaderOnly) {
|
|
271
246
|
error(!!this.getLiveRegion(), `[Alert] The 'screenReaderOnly' prop must be used in conjunction with 'liveRegion'.`);
|
|
272
|
-
return
|
|
247
|
+
return screenReaderContent;
|
|
273
248
|
}
|
|
274
249
|
|
|
275
250
|
if (this.props.transition === 'none') {
|
|
276
|
-
return this.state.open ? this.renderAlert() : null;
|
|
251
|
+
return this.state.open ? jsx(React.Fragment, null, screenReaderContent, this.renderAlert()) : null;
|
|
277
252
|
}
|
|
278
253
|
|
|
279
|
-
return jsx(Transition, {
|
|
254
|
+
return jsx(React.Fragment, null, screenReaderContent, jsx(Transition, {
|
|
280
255
|
type: this.props.transition,
|
|
281
256
|
transitionOnMount: true,
|
|
282
257
|
in: this.state.open,
|
|
283
258
|
unmountOnExit: true,
|
|
284
259
|
onExited: this.onExitTransition
|
|
285
|
-
}, this.renderAlert());
|
|
260
|
+
}, this.renderAlert()));
|
|
286
261
|
}
|
|
287
262
|
|
|
288
263
|
}, _class2.displayName = "Alert", _class2.componentId = 'Alert', _class2.propTypes = propTypes, _class2.allowedProps = allowedProps, _class2.defaultProps = {
|
package/lib/Alert/index.js
CHANGED
|
@@ -37,8 +37,6 @@ var _Transition = require("@instructure/ui-motion/lib/Transition");
|
|
|
37
37
|
|
|
38
38
|
var _console = require("@instructure/console");
|
|
39
39
|
|
|
40
|
-
var _uiThemes = require("@instructure/ui-themes");
|
|
41
|
-
|
|
42
40
|
var _emotion = require("@instructure/emotion");
|
|
43
41
|
|
|
44
42
|
var _styles = _interopRequireDefault(require("./styles"));
|
|
@@ -104,6 +102,7 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
104
102
|
}
|
|
105
103
|
};
|
|
106
104
|
|
|
105
|
+
this.srid = this.props.deterministicId();
|
|
107
106
|
this.state = {
|
|
108
107
|
open: true
|
|
109
108
|
};
|
|
@@ -148,37 +147,12 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
148
147
|
const liveRegion = this.getLiveRegion();
|
|
149
148
|
|
|
150
149
|
if (liveRegion) {
|
|
151
|
-
this.srid = this.props.deterministicId();
|
|
152
150
|
const div = document.createElement('div');
|
|
153
151
|
div.setAttribute('id', this.srid);
|
|
154
|
-
this.renderScreenreeaderAlert(div);
|
|
155
152
|
liveRegion.appendChild(div);
|
|
156
153
|
}
|
|
157
154
|
}
|
|
158
155
|
|
|
159
|
-
updateScreenreaderAlert() {
|
|
160
|
-
if (this.getLiveRegion()) {
|
|
161
|
-
const div = document.getElementById(this.srid);
|
|
162
|
-
|
|
163
|
-
if (div) {
|
|
164
|
-
_reactDom.default.render(null, div, () => {
|
|
165
|
-
this.renderScreenreeaderAlert(div);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
renderScreenreeaderAlert(div) {
|
|
172
|
-
const content = this.createScreenreaderContentNode();
|
|
173
|
-
|
|
174
|
-
_reactDom.default.render( // since ScreenReaderContent gets rendered outside the app,
|
|
175
|
-
// and uses the withStyle decorator, we need to provide a theme for it,
|
|
176
|
-
// otherwise throws warning (any theme, doesn't use any theme variables)
|
|
177
|
-
(0, _emotion.jsx)(_emotion.InstUISettingsProvider, {
|
|
178
|
-
theme: _uiThemes.canvas
|
|
179
|
-
}, content), div);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
156
|
removeScreenreaderAlert() {
|
|
183
157
|
const liveRegion = this.getLiveRegion();
|
|
184
158
|
|
|
@@ -186,8 +160,6 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
186
160
|
const div = document.getElementById(this.srid);
|
|
187
161
|
|
|
188
162
|
if (div) {
|
|
189
|
-
var _div$parentNode;
|
|
190
|
-
|
|
191
163
|
// Accessibility attributes must be removed for the deletion of the node
|
|
192
164
|
// and then reapplied because JAWS/IE will not respect the
|
|
193
165
|
// "aria-relevant" attribute and read when the node is deleted if
|
|
@@ -195,10 +167,6 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
195
167
|
liveRegion.removeAttribute('aria-live');
|
|
196
168
|
liveRegion.removeAttribute('aria-relevant');
|
|
197
169
|
liveRegion.removeAttribute('aria-atomic');
|
|
198
|
-
|
|
199
|
-
_reactDom.default.unmountComponentAtNode(div);
|
|
200
|
-
|
|
201
|
-
div === null || div === void 0 ? void 0 : (_div$parentNode = div.parentNode) === null || _div$parentNode === void 0 ? void 0 : _div$parentNode.removeChild(div);
|
|
202
170
|
this.initLiveRegion(liveRegion);
|
|
203
171
|
}
|
|
204
172
|
}
|
|
@@ -215,7 +183,10 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
215
183
|
}
|
|
216
184
|
|
|
217
185
|
this.handleTimeout();
|
|
218
|
-
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
componentWillUnmount() {
|
|
189
|
+
this.clearTimeouts();
|
|
219
190
|
}
|
|
220
191
|
|
|
221
192
|
componentDidUpdate(prevProps) {
|
|
@@ -227,18 +198,9 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
227
198
|
// this outside world is asking us to close the alert, which needs to
|
|
228
199
|
// take place internally so the transition runs
|
|
229
200
|
this.close();
|
|
230
|
-
} else {
|
|
231
|
-
if (this.props.children !== prevProps.children) {
|
|
232
|
-
this.updateScreenreaderAlert();
|
|
233
|
-
}
|
|
234
201
|
}
|
|
235
202
|
}
|
|
236
203
|
|
|
237
|
-
componentWillUnmount() {
|
|
238
|
-
this.removeScreenreaderAlert();
|
|
239
|
-
this.clearTimeouts();
|
|
240
|
-
}
|
|
241
|
-
|
|
242
204
|
renderIcon() {
|
|
243
205
|
var _this$props$styles;
|
|
244
206
|
|
|
@@ -276,24 +238,33 @@ let Alert = (_dec = (0, _withDeterministicId.withDeterministicId)(), _dec2 = (0,
|
|
|
276
238
|
}, this.props.children), this.renderCloseButton());
|
|
277
239
|
}
|
|
278
240
|
|
|
241
|
+
createScreenReaderPortal(liveRegion) {
|
|
242
|
+
const open = this.state.open;
|
|
243
|
+
return open ? /*#__PURE__*/_reactDom.default.createPortal((0, _emotion.jsx)("div", {
|
|
244
|
+
id: this.srid
|
|
245
|
+
}, this.createScreenreaderContentNode()), liveRegion) : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
279
248
|
render() {
|
|
280
|
-
|
|
249
|
+
const liveRegion = this.getLiveRegion();
|
|
250
|
+
const screenReaderContent = liveRegion ? this.createScreenReaderPortal(liveRegion) : null; // Don't render anything if screen reader only
|
|
251
|
+
|
|
281
252
|
if (this.props.screenReaderOnly) {
|
|
282
253
|
(0, _console.logError)(!!this.getLiveRegion(), `[Alert] The 'screenReaderOnly' prop must be used in conjunction with 'liveRegion'.`);
|
|
283
|
-
return
|
|
254
|
+
return screenReaderContent;
|
|
284
255
|
}
|
|
285
256
|
|
|
286
257
|
if (this.props.transition === 'none') {
|
|
287
|
-
return this.state.open ? this.renderAlert() : null;
|
|
258
|
+
return this.state.open ? (0, _emotion.jsx)(_react.default.Fragment, null, screenReaderContent, this.renderAlert()) : null;
|
|
288
259
|
}
|
|
289
260
|
|
|
290
|
-
return (0, _emotion.jsx)(_Transition.Transition, {
|
|
261
|
+
return (0, _emotion.jsx)(_react.default.Fragment, null, screenReaderContent, (0, _emotion.jsx)(_Transition.Transition, {
|
|
291
262
|
type: this.props.transition,
|
|
292
263
|
transitionOnMount: true,
|
|
293
264
|
in: this.state.open,
|
|
294
265
|
unmountOnExit: true,
|
|
295
266
|
onExited: this.onExitTransition
|
|
296
|
-
}, this.renderAlert());
|
|
267
|
+
}, this.renderAlert()));
|
|
297
268
|
}
|
|
298
269
|
|
|
299
270
|
}, _class2.displayName = "Alert", _class2.componentId = 'Alert', _class2.propTypes = _props.propTypes, _class2.allowedProps = _props.allowedProps, _class2.defaultProps = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-alerts",
|
|
3
|
-
"version": "8.28.1
|
|
3
|
+
"version": "8.28.1",
|
|
4
4
|
"description": "An alert component",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -23,24 +23,24 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-babel-preset": "8.28.1
|
|
27
|
-
"@instructure/ui-color-utils": "8.28.1
|
|
28
|
-
"@instructure/ui-test-utils": "8.28.1
|
|
26
|
+
"@instructure/ui-babel-preset": "8.28.1",
|
|
27
|
+
"@instructure/ui-color-utils": "8.28.1",
|
|
28
|
+
"@instructure/ui-test-utils": "8.28.1"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@babel/runtime": "^7.13.10",
|
|
32
|
-
"@instructure/console": "8.28.1
|
|
33
|
-
"@instructure/emotion": "8.28.1
|
|
34
|
-
"@instructure/shared-types": "8.28.1
|
|
35
|
-
"@instructure/ui-a11y-content": "8.28.1
|
|
36
|
-
"@instructure/ui-buttons": "8.28.1
|
|
37
|
-
"@instructure/ui-icons": "8.28.1
|
|
38
|
-
"@instructure/ui-motion": "8.28.1
|
|
39
|
-
"@instructure/ui-react-utils": "8.28.1
|
|
40
|
-
"@instructure/ui-themes": "8.28.1
|
|
41
|
-
"@instructure/ui-utils": "8.28.1
|
|
42
|
-
"@instructure/ui-view": "8.28.1
|
|
43
|
-
"@instructure/uid": "8.28.1
|
|
32
|
+
"@instructure/console": "8.28.1",
|
|
33
|
+
"@instructure/emotion": "8.28.1",
|
|
34
|
+
"@instructure/shared-types": "8.28.1",
|
|
35
|
+
"@instructure/ui-a11y-content": "8.28.1",
|
|
36
|
+
"@instructure/ui-buttons": "8.28.1",
|
|
37
|
+
"@instructure/ui-icons": "8.28.1",
|
|
38
|
+
"@instructure/ui-motion": "8.28.1",
|
|
39
|
+
"@instructure/ui-react-utils": "8.28.1",
|
|
40
|
+
"@instructure/ui-themes": "8.28.1",
|
|
41
|
+
"@instructure/ui-utils": "8.28.1",
|
|
42
|
+
"@instructure/ui-view": "8.28.1",
|
|
43
|
+
"@instructure/uid": "8.28.1",
|
|
44
44
|
"keycode": "^2",
|
|
45
45
|
"prop-types": "^15"
|
|
46
46
|
},
|
package/src/Alert/index.tsx
CHANGED
|
@@ -42,8 +42,7 @@ import {
|
|
|
42
42
|
} from '@instructure/ui-icons'
|
|
43
43
|
import { Transition } from '@instructure/ui-motion'
|
|
44
44
|
import { logError as error } from '@instructure/console'
|
|
45
|
-
import {
|
|
46
|
-
import { withStyle, jsx, InstUISettingsProvider } from '@instructure/emotion'
|
|
45
|
+
import { withStyle, jsx } from '@instructure/emotion'
|
|
47
46
|
|
|
48
47
|
import generateStyle from './styles'
|
|
49
48
|
import generateComponentTheme from './theme'
|
|
@@ -80,13 +79,14 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
80
79
|
constructor(props: AlertProps) {
|
|
81
80
|
super(props)
|
|
82
81
|
|
|
82
|
+
this.srid = this.props.deterministicId!()
|
|
83
83
|
this.state = {
|
|
84
84
|
open: true
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
_timeouts: ReturnType<typeof setTimeout>[] = []
|
|
89
|
-
srid
|
|
89
|
+
srid: string
|
|
90
90
|
|
|
91
91
|
variantUI = {
|
|
92
92
|
error: IconNoSolid,
|
|
@@ -169,38 +169,13 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
169
169
|
createScreenreaderAlert() {
|
|
170
170
|
const liveRegion = this.getLiveRegion()
|
|
171
171
|
if (liveRegion) {
|
|
172
|
-
this.srid = this.props.deterministicId!()
|
|
173
|
-
|
|
174
172
|
const div = document.createElement('div')
|
|
175
173
|
div.setAttribute('id', this.srid)
|
|
176
174
|
|
|
177
|
-
this.renderScreenreeaderAlert(div)
|
|
178
175
|
liveRegion.appendChild(div)
|
|
179
176
|
}
|
|
180
177
|
}
|
|
181
178
|
|
|
182
|
-
updateScreenreaderAlert() {
|
|
183
|
-
if (this.getLiveRegion()) {
|
|
184
|
-
const div = document.getElementById(this.srid!) as HTMLDivElement
|
|
185
|
-
if (div) {
|
|
186
|
-
ReactDOM.render(null as any, div, () => {
|
|
187
|
-
this.renderScreenreeaderAlert(div)
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
renderScreenreeaderAlert(div: HTMLDivElement) {
|
|
194
|
-
const content = this.createScreenreaderContentNode()
|
|
195
|
-
ReactDOM.render(
|
|
196
|
-
// since ScreenReaderContent gets rendered outside the app,
|
|
197
|
-
// and uses the withStyle decorator, we need to provide a theme for it,
|
|
198
|
-
// otherwise throws warning (any theme, doesn't use any theme variables)
|
|
199
|
-
<InstUISettingsProvider theme={canvas}>{content}</InstUISettingsProvider>,
|
|
200
|
-
div
|
|
201
|
-
)
|
|
202
|
-
}
|
|
203
|
-
|
|
204
179
|
removeScreenreaderAlert() {
|
|
205
180
|
const liveRegion = this.getLiveRegion()
|
|
206
181
|
if (liveRegion) {
|
|
@@ -214,9 +189,6 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
214
189
|
liveRegion.removeAttribute('aria-relevant')
|
|
215
190
|
liveRegion.removeAttribute('aria-atomic')
|
|
216
191
|
|
|
217
|
-
ReactDOM.unmountComponentAtNode(div)
|
|
218
|
-
div?.parentNode?.removeChild(div)
|
|
219
|
-
|
|
220
192
|
this.initLiveRegion(liveRegion)
|
|
221
193
|
}
|
|
222
194
|
}
|
|
@@ -239,7 +211,10 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
239
211
|
}
|
|
240
212
|
|
|
241
213
|
this.handleTimeout()
|
|
242
|
-
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
componentWillUnmount() {
|
|
217
|
+
this.clearTimeouts()
|
|
243
218
|
}
|
|
244
219
|
|
|
245
220
|
componentDidUpdate(prevProps: AlertProps) {
|
|
@@ -248,18 +223,9 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
248
223
|
// this outside world is asking us to close the alert, which needs to
|
|
249
224
|
// take place internally so the transition runs
|
|
250
225
|
this.close()
|
|
251
|
-
} else {
|
|
252
|
-
if (this.props.children !== prevProps.children) {
|
|
253
|
-
this.updateScreenreaderAlert()
|
|
254
|
-
}
|
|
255
226
|
}
|
|
256
227
|
}
|
|
257
228
|
|
|
258
|
-
componentWillUnmount() {
|
|
259
|
-
this.removeScreenreaderAlert()
|
|
260
|
-
this.clearTimeouts()
|
|
261
|
-
}
|
|
262
|
-
|
|
263
229
|
renderIcon() {
|
|
264
230
|
const Icon = this.variantUI[this.props.variant!]
|
|
265
231
|
return (
|
|
@@ -301,7 +267,22 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
301
267
|
)
|
|
302
268
|
}
|
|
303
269
|
|
|
270
|
+
createScreenReaderPortal(liveRegion: Element) {
|
|
271
|
+
const { open } = this.state
|
|
272
|
+
|
|
273
|
+
return open
|
|
274
|
+
? ReactDOM.createPortal(
|
|
275
|
+
<div id={this.srid}>{this.createScreenreaderContentNode()}</div>,
|
|
276
|
+
liveRegion
|
|
277
|
+
)
|
|
278
|
+
: null
|
|
279
|
+
}
|
|
280
|
+
|
|
304
281
|
render() {
|
|
282
|
+
const liveRegion = this.getLiveRegion()
|
|
283
|
+
const screenReaderContent = liveRegion
|
|
284
|
+
? this.createScreenReaderPortal(liveRegion)
|
|
285
|
+
: null
|
|
305
286
|
// Don't render anything if screen reader only
|
|
306
287
|
if (this.props.screenReaderOnly) {
|
|
307
288
|
error(
|
|
@@ -309,22 +290,30 @@ class Alert extends Component<AlertProps, AlertState> {
|
|
|
309
290
|
`[Alert] The 'screenReaderOnly' prop must be used in conjunction with 'liveRegion'.`
|
|
310
291
|
)
|
|
311
292
|
|
|
312
|
-
return
|
|
293
|
+
return screenReaderContent
|
|
313
294
|
}
|
|
314
295
|
|
|
315
296
|
if (this.props.transition === 'none') {
|
|
316
|
-
return this.state.open ?
|
|
297
|
+
return this.state.open ? (
|
|
298
|
+
<React.Fragment>
|
|
299
|
+
{screenReaderContent}
|
|
300
|
+
{this.renderAlert()}
|
|
301
|
+
</React.Fragment>
|
|
302
|
+
) : null
|
|
317
303
|
}
|
|
318
304
|
return (
|
|
319
|
-
<
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
305
|
+
<React.Fragment>
|
|
306
|
+
{screenReaderContent}
|
|
307
|
+
<Transition
|
|
308
|
+
type={this.props.transition}
|
|
309
|
+
transitionOnMount
|
|
310
|
+
in={this.state.open}
|
|
311
|
+
unmountOnExit
|
|
312
|
+
onExited={this.onExitTransition}
|
|
313
|
+
>
|
|
314
|
+
{this.renderAlert()}
|
|
315
|
+
</Transition>
|
|
316
|
+
</React.Fragment>
|
|
328
317
|
)
|
|
329
318
|
}
|
|
330
319
|
}
|