@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 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-snapshot-2](https://github.com/instructure/instructure-ui/compare/v8.28.0...v8.28.1-snapshot-2) (2022-09-02)
6
+ ## [8.28.1](https://github.com/instructure/instructure-ui/compare/v8.28.0...v8.28.1) (2022-09-12)
7
7
 
8
- **Note:** Version bump only for package @instructure/ui-alerts
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 { canvas } from '@instructure/ui-themes';
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
- this.createScreenreaderAlert();
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
- // Don't render anything if screen reader only
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 null;
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 = {
@@ -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
- this.createScreenreaderAlert();
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
- // Don't render anything if screen reader only
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 null;
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-snapshot-2",
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-snapshot-2",
27
- "@instructure/ui-color-utils": "8.28.1-snapshot-2",
28
- "@instructure/ui-test-utils": "8.28.1-snapshot-2"
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-snapshot-2",
33
- "@instructure/emotion": "8.28.1-snapshot-2",
34
- "@instructure/shared-types": "8.28.1-snapshot-2",
35
- "@instructure/ui-a11y-content": "8.28.1-snapshot-2",
36
- "@instructure/ui-buttons": "8.28.1-snapshot-2",
37
- "@instructure/ui-icons": "8.28.1-snapshot-2",
38
- "@instructure/ui-motion": "8.28.1-snapshot-2",
39
- "@instructure/ui-react-utils": "8.28.1-snapshot-2",
40
- "@instructure/ui-themes": "8.28.1-snapshot-2",
41
- "@instructure/ui-utils": "8.28.1-snapshot-2",
42
- "@instructure/ui-view": "8.28.1-snapshot-2",
43
- "@instructure/uid": "8.28.1-snapshot-2",
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
  },
@@ -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 { canvas } from '@instructure/ui-themes'
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?: string
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
- this.createScreenreaderAlert()
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 null
293
+ return screenReaderContent
313
294
  }
314
295
 
315
296
  if (this.props.transition === 'none') {
316
- return this.state.open ? this.renderAlert() : null
297
+ return this.state.open ? (
298
+ <React.Fragment>
299
+ {screenReaderContent}
300
+ {this.renderAlert()}
301
+ </React.Fragment>
302
+ ) : null
317
303
  }
318
304
  return (
319
- <Transition
320
- type={this.props.transition}
321
- transitionOnMount
322
- in={this.state.open}
323
- unmountOnExit
324
- onExited={this.onExitTransition}
325
- >
326
- {this.renderAlert()}
327
- </Transition>
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
  }