@dnb/eufemia 9.17.1 → 9.17.2

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.
@@ -22,8 +22,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
22
22
  import "core-js/modules/es.array.filter.js";
23
23
  import "core-js/modules/es.object.to-string.js";
24
24
  import "core-js/modules/web.dom-collections.for-each.js";
25
- import "core-js/modules/es.regexp.exec.js";
26
25
  import "core-js/modules/es.parse-float.js";
26
+ import "core-js/modules/es.regexp.exec.js";
27
27
 
28
28
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
29
29
 
@@ -57,6 +57,31 @@ var ModalContent = function (_React$PureComponent) {
57
57
  triggeredByEvent: null
58
58
  });
59
59
 
60
+ _defineProperty(_assertThisInitialized(_this), "lockBody", function () {
61
+ var modalRoots = getListOfModalRoots();
62
+ var firstLevel = modalRoots[0];
63
+
64
+ if (firstLevel === _assertThisInitialized(_this)) {
65
+ _this._ii = new InteractionInvalidation();
66
+
67
+ _this._ii.setBypassSelector(['.dnb-modal__content *', "#dnb-modal-".concat(_this.props.root_id || 'root', " *")].filter(Boolean));
68
+
69
+ _this._ii.activate();
70
+ } else {
71
+ modalRoots.forEach(function (modal) {
72
+ if (modal !== _assertThisInitialized(_this) && typeof modal._iiLocal === 'undefined' && typeof modal._contentRef !== 'undefined') {
73
+ modal._iiLocal = new InteractionInvalidation();
74
+
75
+ modal._iiLocal.activate(modal._contentRef.current);
76
+ }
77
+ });
78
+ }
79
+
80
+ if (typeof document !== 'undefined') {
81
+ document.addEventListener('keydown', _this.onKeyDownHandler);
82
+ }
83
+ });
84
+
60
85
  _defineProperty(_assertThisInitialized(_this), "_androidFocusHelper", function () {
61
86
  clearTimeout(_this._androidFocusTimeout);
62
87
  _this._androidFocusTimeout = setTimeout(function () {
@@ -67,7 +92,7 @@ var ModalContent = function (_React$PureComponent) {
67
92
  document.activeElement.scrollIntoView();
68
93
  }
69
94
  } catch (e) {}
70
- }, 100);
95
+ }, parseFloat(_this.props.animation_duration) / 2);
71
96
  });
72
97
 
73
98
  _defineProperty(_assertThisInitialized(_this), "preventClick", function (e) {
@@ -122,8 +147,6 @@ var ModalContent = function (_React$PureComponent) {
122
147
  _createClass(ModalContent, [{
123
148
  key: "componentDidMount",
124
149
  value: function componentDidMount() {
125
- var _this2 = this;
126
-
127
150
  this.addToIndex();
128
151
  this.removeScrollPossibility();
129
152
  this.setFocus();
@@ -136,9 +159,7 @@ var ModalContent = function (_React$PureComponent) {
136
159
  if (isTrue(this.props.no_animation) || process.env.NODE_ENV === 'test') {
137
160
  this.lockBody();
138
161
  } else {
139
- this._lockTimeout = setTimeout(function () {
140
- _this2.lockBody();
141
- }, 500);
162
+ this._lockTimeout = setTimeout(this.lockBody, parseFloat(this.props.animation_duration) * 1.2);
142
163
  }
143
164
  }
144
165
  }, {
@@ -148,34 +169,6 @@ var ModalContent = function (_React$PureComponent) {
148
169
  clearTimeout(this._lockTimeout);
149
170
  this.removeLocks();
150
171
  }
151
- }, {
152
- key: "lockBody",
153
- value: function lockBody() {
154
- var _this3 = this;
155
-
156
- var modalRoots = getListOfModalRoots();
157
- var firstLevel = modalRoots[0];
158
-
159
- if (firstLevel === this) {
160
- this._ii = new InteractionInvalidation();
161
-
162
- this._ii.setBypassSelector(['.dnb-modal__content *', "#dnb-modal-".concat(this.props.root_id || 'root', " *")].filter(Boolean));
163
-
164
- this._ii.activate();
165
- } else {
166
- modalRoots.forEach(function (modal) {
167
- if (modal !== _this3 && typeof modal._iiLocal === 'undefined' && typeof modal._contentRef !== 'undefined') {
168
- modal._iiLocal = new InteractionInvalidation();
169
-
170
- modal._iiLocal.activate(modal._contentRef.current);
171
- }
172
- });
173
- }
174
-
175
- if (typeof document !== 'undefined') {
176
- document.addEventListener('keydown', this.onKeyDownHandler);
177
- }
178
- }
179
172
  }, {
180
173
  key: "removeLocks",
181
174
  value: function removeLocks() {
@@ -248,7 +241,7 @@ var ModalContent = function (_React$PureComponent) {
248
241
  }, {
249
242
  key: "removeFromIndex",
250
243
  value: function removeFromIndex() {
251
- var _this4 = this;
244
+ var _this2 = this;
252
245
 
253
246
  if (typeof window !== 'undefined') {
254
247
  try {
@@ -257,7 +250,7 @@ var ModalContent = function (_React$PureComponent) {
257
250
  }
258
251
 
259
252
  window.__modalStack = window.__modalStack.filter(function (cur) {
260
- return cur !== _this4;
253
+ return cur !== _this2;
261
254
  });
262
255
  } catch (e) {
263
256
  warn(e);
@@ -312,7 +305,7 @@ var ModalContent = function (_React$PureComponent) {
312
305
  key: "closeModal",
313
306
  value: function closeModal(event, _ref) {
314
307
  var _event$persist,
315
- _this5 = this;
308
+ _this3 = this;
316
309
 
317
310
  var triggeredBy = _ref.triggeredBy,
318
311
  params = _objectWithoutProperties(_ref, _excluded);
@@ -322,7 +315,7 @@ var ModalContent = function (_React$PureComponent) {
322
315
  triggeredBy: triggeredBy,
323
316
  triggeredByEvent: event
324
317
  }, function () {
325
- _this5.props.closeModal(event, _objectSpread({
318
+ _this3.props.closeModal(event, _objectSpread({
326
319
  triggeredBy: triggeredBy
327
320
  }, params));
328
321
  });
@@ -203,14 +203,19 @@ export const useEventMapping = ({
203
203
  onBeforeInput: event => callEvent({
204
204
  event
205
205
  }, 'on_before_input'),
206
+ onFocus: params => callEvent(params, 'on_focus'),
207
+ onBlur: params => callEvent(params, 'on_blur'),
206
208
  onMouseUp: event => callEvent({
207
209
  event
208
210
  }, 'on_mouse_up'),
209
- on_focus: params => callEvent(params, 'on_focus'),
210
- on_key_down: params => callEvent(params, 'on_key_down'),
211
- on_submit: params => callEvent(params, 'on_submit'),
212
- on_blur: params => callEvent(params, 'on_blur'),
213
- on_change: params => callEvent(params, 'on_change')
211
+ onKeyDown: params => callEvent(params, 'on_key_down'),
212
+ onSubmit: params => callEvent(params, 'on_submit'),
213
+ onChange: params => callEvent(params, 'on_change'),
214
+ on_focus: undefined,
215
+ on_blur: undefined,
216
+ on_key_down: undefined,
217
+ on_submit: undefined,
218
+ on_change: undefined
214
219
  };
215
220
  };
216
221
 
@@ -221,11 +226,7 @@ const useCallEvent = ({
221
226
  props
222
227
  } = React.useContext(InputMaskedContext);
223
228
  const maskParams = useMaskParams();
224
-
225
- if (!maskParams) {
226
- return () => {};
227
- }
228
-
229
+ const isNumberMask = useNumberMask();
229
230
  const decimalSeparators = /[,.'·]/;
230
231
  let isUnidentified = false;
231
232
 
@@ -247,7 +248,7 @@ const useCallEvent = ({
247
248
  isUnidentified = false;
248
249
  }
249
250
 
250
- if (name === 'on_key_down' && !isUnidentified && !(maskParams !== null && maskParams !== void 0 && maskParams.allowLeadingZeroes) && (keyCode === '0' || value.replace(/[^\d]/g, '') === '' && decimalSeparators.test(keyCode))) {
251
+ if (name === 'on_key_down' && !isUnidentified && (isNumberMask && !(maskParams !== null && maskParams !== void 0 && maskParams.allowLeadingZeroes) || !isNumberMask && (maskParams === null || maskParams === void 0 ? void 0 : maskParams.allowLeadingZeroes) === false) && (keyCode === '0' || keyCode === 'numpad 0' || value.replace(/[^\d]/g, '') === '' && decimalSeparators.test(keyCode))) {
251
252
  const testValue = (value.slice(0, selStart) + '0' + value.slice(selStart + 1, value.length)).replace(/[^\d]/g, '');
252
253
 
253
254
  if (/^0/.test(testValue)) {
@@ -256,7 +257,7 @@ const useCallEvent = ({
256
257
  }
257
258
  }
258
259
 
259
- if (name === 'on_key_down' && !isUnidentified && maskParams !== null && maskParams !== void 0 && maskParams.decimalSymbol) {
260
+ if (name === 'on_key_down' && isNumberMask && !isUnidentified && maskParams !== null && maskParams !== void 0 && maskParams.decimalSymbol) {
260
261
  const hasDecimalSymbol = value.includes(maskParams.decimalSymbol);
261
262
  const allowedDecimals = maskParams.decimalLimit > 0 || maskParams.allowDecimal !== false;
262
263
 
@@ -242,6 +242,10 @@ export interface ModalProps extends React.HTMLProps<HTMLElement> {
242
242
  * Set a function to call the callback function, once the modal/drawer should close: `close_modal={(close) => close()}`
243
243
  */
244
244
  close_modal?: (...args: any[]) => any;
245
+
246
+ /**
247
+ * Provide a custom trigger component. Like `trigger={<Anchor href="/" />}`. It will set the focus on it when the modal/drawer gets closed.
248
+ */
245
249
  trigger?: ModalTrigger;
246
250
 
247
251
  /**
@@ -120,7 +120,6 @@ export default class Modal extends React.PureComponent {
120
120
  this.setState({
121
121
  hide: true
122
122
  });
123
- clearTimeout(this._closeTimeout);
124
123
  this._closeTimeout = setTimeout(doItNow, parseFloat(this.props.animation_duration));
125
124
  } else {
126
125
  doItNow();
@@ -131,13 +130,14 @@ export default class Modal extends React.PureComponent {
131
130
  const delay = parseFloat(this.props.open_delay);
132
131
 
133
132
  if (delay > 0 && !isTrue(this.props.no_animation)) {
134
- clearTimeout(this._openTimeout);
135
133
  this._openTimeout = setTimeout(toggleNow, delay);
136
134
  } else {
137
135
  toggleNow();
138
136
  }
139
137
  };
140
138
 
139
+ clearTimeout(this._closeTimeout);
140
+ clearTimeout(this._openTimeout);
141
141
  const {
142
142
  open_modal
143
143
  } = this.props;
@@ -184,13 +184,7 @@ export default class Modal extends React.PureComponent {
184
184
  } catch (e) {}
185
185
  }
186
186
 
187
- const last = getListOfModalRoots(-1);
188
-
189
- if (last) {
190
- this.setActiveState(last._id);
191
- } else if (getListOfModalRoots().length <= 1) {
192
- this.setActiveState(false);
193
- }
187
+ this.removeActiveState();
194
188
  }
195
189
  });
196
190
 
@@ -245,16 +239,15 @@ export default class Modal extends React.PureComponent {
245
239
  }
246
240
 
247
241
  componentWillUnmount() {
242
+ clearTimeout(this._openTimeout);
243
+ clearTimeout(this._closeTimeout);
244
+ this.removeActiveState(false);
245
+
248
246
  this._onUnmount.forEach(fn => {
249
247
  if (typeof fn === 'function') {
250
248
  fn();
251
249
  }
252
250
  });
253
-
254
- clearTimeout(this._openTimeout);
255
- clearTimeout(this._closeTimeout);
256
- clearTimeout(this._sideEffectsTimeout);
257
- clearTimeout(this._tryToOpenTimeout);
258
251
  }
259
252
 
260
253
  componentDidUpdate(prevProps) {
@@ -265,8 +258,7 @@ export default class Modal extends React.PureComponent {
265
258
 
266
259
  openBasedOnStateUpdate() {
267
260
  const {
268
- hide,
269
- modalActive
261
+ hide
270
262
  } = this.state;
271
263
  const {
272
264
  open_state
@@ -276,25 +268,39 @@ export default class Modal extends React.PureComponent {
276
268
  this.activeElement = document.activeElement;
277
269
  }
278
270
 
279
- if (!hide && !modalActive && (open_state === 'opened' || open_state === true)) {
271
+ if (!hide && (open_state === 'opened' || open_state === true)) {
280
272
  this.toggleOpenClose(null, true);
281
- } else if (hide && modalActive && (open_state === 'closed' || open_state === false)) {
273
+ } else if (hide && (open_state === 'closed' || open_state === false)) {
282
274
  this.toggleOpenClose(null, false);
283
275
  }
284
276
  }
285
277
 
278
+ removeActiveState() {
279
+ const last = getListOfModalRoots(-1);
280
+
281
+ if (last !== null && last !== void 0 && last._id && last._id !== this._id) {
282
+ return this.setActiveState(last._id);
283
+ }
284
+
285
+ try {
286
+ document.documentElement.removeAttribute('data-dnb-modal-active');
287
+ document.body.setAttribute('data-dnb-modal-active', 'false');
288
+ } catch (e) {
289
+ warn('Modal: Error on remove "data-dnb-modal-active"', e);
290
+ }
291
+ }
292
+
286
293
  setActiveState(modalId) {
294
+ if (!modalId) {
295
+ warn('Modal: A valid modalId is required');
296
+ }
297
+
287
298
  if (typeof document !== 'undefined') {
288
299
  try {
289
- if (modalId) {
290
- document.documentElement.setAttribute('data-dnb-modal-active', modalId);
291
- } else {
292
- document.documentElement.removeAttribute('data-dnb-modal-active');
293
- }
294
-
295
- document.body.setAttribute('data-dnb-modal-active', modalId ? 'true' : 'false');
300
+ document.documentElement.setAttribute('data-dnb-modal-active', modalId);
301
+ document.body.setAttribute('data-dnb-modal-active', 'true');
296
302
  } catch (e) {
297
- warn('Modal: Error on set "data-dnb-modal-active" by using element.setAttribute()', e);
303
+ warn('Modal: Error on set "data-dnb-modal-active"', e);
298
304
  }
299
305
  }
300
306
  }
@@ -27,6 +27,31 @@ export default class ModalContent extends React.PureComponent {
27
27
  triggeredByEvent: null
28
28
  });
29
29
 
30
+ _defineProperty(this, "lockBody", () => {
31
+ const modalRoots = getListOfModalRoots();
32
+ const firstLevel = modalRoots[0];
33
+
34
+ if (firstLevel === this) {
35
+ this._ii = new InteractionInvalidation();
36
+
37
+ this._ii.setBypassSelector(['.dnb-modal__content *', `#dnb-modal-${this.props.root_id || 'root'} *`].filter(Boolean));
38
+
39
+ this._ii.activate();
40
+ } else {
41
+ modalRoots.forEach(modal => {
42
+ if (modal !== this && typeof modal._iiLocal === 'undefined' && typeof modal._contentRef !== 'undefined') {
43
+ modal._iiLocal = new InteractionInvalidation();
44
+
45
+ modal._iiLocal.activate(modal._contentRef.current);
46
+ }
47
+ });
48
+ }
49
+
50
+ if (typeof document !== 'undefined') {
51
+ document.addEventListener('keydown', this.onKeyDownHandler);
52
+ }
53
+ });
54
+
30
55
  _defineProperty(this, "_androidFocusHelper", () => {
31
56
  clearTimeout(this._androidFocusTimeout);
32
57
  this._androidFocusTimeout = setTimeout(() => {
@@ -37,7 +62,7 @@ export default class ModalContent extends React.PureComponent {
37
62
  document.activeElement.scrollIntoView();
38
63
  }
39
64
  } catch (e) {}
40
- }, 100);
65
+ }, parseFloat(this.props.animation_duration) / 2);
41
66
  });
42
67
 
43
68
  _defineProperty(this, "preventClick", e => {
@@ -100,9 +125,7 @@ export default class ModalContent extends React.PureComponent {
100
125
  if (isTrue(this.props.no_animation) || process.env.NODE_ENV === 'test') {
101
126
  this.lockBody();
102
127
  } else {
103
- this._lockTimeout = setTimeout(() => {
104
- this.lockBody();
105
- }, 500);
128
+ this._lockTimeout = setTimeout(this.lockBody, parseFloat(this.props.animation_duration) * 1.2);
106
129
  }
107
130
  }
108
131
 
@@ -112,31 +135,6 @@ export default class ModalContent extends React.PureComponent {
112
135
  this.removeLocks();
113
136
  }
114
137
 
115
- lockBody() {
116
- const modalRoots = getListOfModalRoots();
117
- const firstLevel = modalRoots[0];
118
-
119
- if (firstLevel === this) {
120
- this._ii = new InteractionInvalidation();
121
-
122
- this._ii.setBypassSelector(['.dnb-modal__content *', `#dnb-modal-${this.props.root_id || 'root'} *`].filter(Boolean));
123
-
124
- this._ii.activate();
125
- } else {
126
- modalRoots.forEach(modal => {
127
- if (modal !== this && typeof modal._iiLocal === 'undefined' && typeof modal._contentRef !== 'undefined') {
128
- modal._iiLocal = new InteractionInvalidation();
129
-
130
- modal._iiLocal.activate(modal._contentRef.current);
131
- }
132
- });
133
- }
134
-
135
- if (typeof document !== 'undefined') {
136
- document.addEventListener('keydown', this.onKeyDownHandler);
137
- }
138
- }
139
-
140
138
  removeLocks() {
141
139
  const modalRoots = getListOfModalRoots();
142
140
  const firstLevel = modalRoots[0];
@@ -220,26 +220,31 @@ export var useEventMapping = function useEventMapping(_ref) {
220
220
  event: event
221
221
  }, 'on_before_input');
222
222
  },
223
+ onFocus: function onFocus(params) {
224
+ return callEvent(params, 'on_focus');
225
+ },
226
+ onBlur: function onBlur(params) {
227
+ return callEvent(params, 'on_blur');
228
+ },
223
229
  onMouseUp: function onMouseUp(event) {
224
230
  return callEvent({
225
231
  event: event
226
232
  }, 'on_mouse_up');
227
233
  },
228
- on_focus: function on_focus(params) {
229
- return callEvent(params, 'on_focus');
230
- },
231
- on_key_down: function on_key_down(params) {
234
+ onKeyDown: function onKeyDown(params) {
232
235
  return callEvent(params, 'on_key_down');
233
236
  },
234
- on_submit: function on_submit(params) {
237
+ onSubmit: function onSubmit(params) {
235
238
  return callEvent(params, 'on_submit');
236
239
  },
237
- on_blur: function on_blur(params) {
238
- return callEvent(params, 'on_blur');
239
- },
240
- on_change: function on_change(params) {
240
+ onChange: function onChange(params) {
241
241
  return callEvent(params, 'on_change');
242
- }
242
+ },
243
+ on_focus: undefined,
244
+ on_blur: undefined,
245
+ on_key_down: undefined,
246
+ on_submit: undefined,
247
+ on_change: undefined
243
248
  };
244
249
  };
245
250
 
@@ -250,11 +255,7 @@ var useCallEvent = function useCallEvent(_ref2) {
250
255
  props = _React$useContext8.props;
251
256
 
252
257
  var maskParams = useMaskParams();
253
-
254
- if (!maskParams) {
255
- return function () {};
256
- }
257
-
258
+ var isNumberMask = useNumberMask();
258
259
  var decimalSeparators = /[,.'·]/;
259
260
  var isUnidentified = false;
260
261
 
@@ -275,7 +276,7 @@ var useCallEvent = function useCallEvent(_ref2) {
275
276
  isUnidentified = false;
276
277
  }
277
278
 
278
- if (name === 'on_key_down' && !isUnidentified && !(maskParams !== null && maskParams !== void 0 && maskParams.allowLeadingZeroes) && (keyCode === '0' || value.replace(/[^\d]/g, '') === '' && decimalSeparators.test(keyCode))) {
279
+ if (name === 'on_key_down' && !isUnidentified && (isNumberMask && !(maskParams !== null && maskParams !== void 0 && maskParams.allowLeadingZeroes) || !isNumberMask && (maskParams === null || maskParams === void 0 ? void 0 : maskParams.allowLeadingZeroes) === false) && (keyCode === '0' || keyCode === 'numpad 0' || value.replace(/[^\d]/g, '') === '' && decimalSeparators.test(keyCode))) {
279
280
  var testValue = (value.slice(0, selStart) + '0' + value.slice(selStart + 1, value.length)).replace(/[^\d]/g, '');
280
281
 
281
282
  if (/^0/.test(testValue)) {
@@ -284,7 +285,7 @@ var useCallEvent = function useCallEvent(_ref2) {
284
285
  }
285
286
  }
286
287
 
287
- if (name === 'on_key_down' && !isUnidentified && maskParams !== null && maskParams !== void 0 && maskParams.decimalSymbol) {
288
+ if (name === 'on_key_down' && isNumberMask && !isUnidentified && maskParams !== null && maskParams !== void 0 && maskParams.decimalSymbol) {
288
289
  var hasDecimalSymbol = value.includes(maskParams.decimalSymbol);
289
290
  var allowedDecimals = maskParams.decimalLimit > 0 || maskParams.allowDecimal !== false;
290
291
 
@@ -242,6 +242,10 @@ export interface ModalProps extends React.HTMLProps<HTMLElement> {
242
242
  * Set a function to call the callback function, once the modal/drawer should close: `close_modal={(close) => close()}`
243
243
  */
244
244
  close_modal?: (...args: any[]) => any;
245
+
246
+ /**
247
+ * Provide a custom trigger component. Like `trigger={<Anchor href="/" />}`. It will set the focus on it when the modal/drawer gets closed.
248
+ */
245
249
  trigger?: ModalTrigger;
246
250
 
247
251
  /**
@@ -94,7 +94,6 @@ var Modal = function (_React$PureComponent) {
94
94
  hide: true
95
95
  });
96
96
 
97
- clearTimeout(_this._closeTimeout);
98
97
  _this._closeTimeout = setTimeout(doItNow, parseFloat(_this.props.animation_duration));
99
98
  } else {
100
99
  doItNow();
@@ -105,13 +104,14 @@ var Modal = function (_React$PureComponent) {
105
104
  var delay = parseFloat(_this.props.open_delay);
106
105
 
107
106
  if (delay > 0 && !isTrue(_this.props.no_animation)) {
108
- clearTimeout(_this._openTimeout);
109
107
  _this._openTimeout = setTimeout(toggleNow, delay);
110
108
  } else {
111
109
  toggleNow();
112
110
  }
113
111
  };
114
112
 
113
+ clearTimeout(_this._closeTimeout);
114
+ clearTimeout(_this._openTimeout);
115
115
  var open_modal = _this.props.open_modal;
116
116
 
117
117
  if (typeof open_modal === 'function') {
@@ -157,13 +157,7 @@ var Modal = function (_React$PureComponent) {
157
157
  } catch (e) {}
158
158
  }
159
159
 
160
- var last = getListOfModalRoots(-1);
161
-
162
- if (last) {
163
- _this.setActiveState(last._id);
164
- } else if (getListOfModalRoots().length <= 1) {
165
- _this.setActiveState(false);
166
- }
160
+ _this.removeActiveState();
167
161
  }
168
162
  });
169
163
 
@@ -221,16 +215,15 @@ var Modal = function (_React$PureComponent) {
221
215
  }, {
222
216
  key: "componentWillUnmount",
223
217
  value: function componentWillUnmount() {
218
+ clearTimeout(this._openTimeout);
219
+ clearTimeout(this._closeTimeout);
220
+ this.removeActiveState(false);
221
+
224
222
  this._onUnmount.forEach(function (fn) {
225
223
  if (typeof fn === 'function') {
226
224
  fn();
227
225
  }
228
226
  });
229
-
230
- clearTimeout(this._openTimeout);
231
- clearTimeout(this._closeTimeout);
232
- clearTimeout(this._sideEffectsTimeout);
233
- clearTimeout(this._tryToOpenTimeout);
234
227
  }
235
228
  }, {
236
229
  key: "componentDidUpdate",
@@ -242,35 +235,48 @@ var Modal = function (_React$PureComponent) {
242
235
  }, {
243
236
  key: "openBasedOnStateUpdate",
244
237
  value: function openBasedOnStateUpdate() {
245
- var _this$state = this.state,
246
- hide = _this$state.hide,
247
- modalActive = _this$state.modalActive;
238
+ var hide = this.state.hide;
248
239
  var open_state = this.props.open_state;
249
240
 
250
241
  if (!this.activeElement && typeof document !== 'undefined') {
251
242
  this.activeElement = document.activeElement;
252
243
  }
253
244
 
254
- if (!hide && !modalActive && (open_state === 'opened' || open_state === true)) {
245
+ if (!hide && (open_state === 'opened' || open_state === true)) {
255
246
  this.toggleOpenClose(null, true);
256
- } else if (hide && modalActive && (open_state === 'closed' || open_state === false)) {
247
+ } else if (hide && (open_state === 'closed' || open_state === false)) {
257
248
  this.toggleOpenClose(null, false);
258
249
  }
259
250
  }
251
+ }, {
252
+ key: "removeActiveState",
253
+ value: function removeActiveState() {
254
+ var last = getListOfModalRoots(-1);
255
+
256
+ if (last !== null && last !== void 0 && last._id && last._id !== this._id) {
257
+ return this.setActiveState(last._id);
258
+ }
259
+
260
+ try {
261
+ document.documentElement.removeAttribute('data-dnb-modal-active');
262
+ document.body.setAttribute('data-dnb-modal-active', 'false');
263
+ } catch (e) {
264
+ warn('Modal: Error on remove "data-dnb-modal-active"', e);
265
+ }
266
+ }
260
267
  }, {
261
268
  key: "setActiveState",
262
269
  value: function setActiveState(modalId) {
270
+ if (!modalId) {
271
+ warn('Modal: A valid modalId is required');
272
+ }
273
+
263
274
  if (typeof document !== 'undefined') {
264
275
  try {
265
- if (modalId) {
266
- document.documentElement.setAttribute('data-dnb-modal-active', modalId);
267
- } else {
268
- document.documentElement.removeAttribute('data-dnb-modal-active');
269
- }
270
-
271
- document.body.setAttribute('data-dnb-modal-active', modalId ? 'true' : 'false');
276
+ document.documentElement.setAttribute('data-dnb-modal-active', modalId);
277
+ document.body.setAttribute('data-dnb-modal-active', 'true');
272
278
  } catch (e) {
273
- warn('Modal: Error on set "data-dnb-modal-active" by using element.setAttribute()', e);
279
+ warn('Modal: Error on set "data-dnb-modal-active"', e);
274
280
  }
275
281
  }
276
282
  }
@@ -305,9 +311,9 @@ var Modal = function (_React$PureComponent) {
305
311
  trigger_class = props.trigger_class,
306
312
  rest = _objectWithoutProperties(props, _excluded);
307
313
 
308
- var _this$state2 = this.state,
309
- hide = _this$state2.hide,
310
- modalActive = _this$state2.modalActive;
314
+ var _this$state = this.state,
315
+ hide = _this$state.hide,
316
+ modalActive = _this$state.modalActive;
311
317
  var modal_content = Modal.getContent(typeof this.props.children === 'function' ? Object.freeze(_objectSpread(_objectSpread({}, this.props), {}, {
312
318
  close: this.close
313
319
  })) : this.props);