@patternfly/react-core 4.219.0 → 4.220.0
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 +27 -0
- package/dist/esm/components/AboutModal/AboutModalContainer.js +1 -1
- package/dist/esm/components/AboutModal/AboutModalContainer.js.map +1 -1
- package/dist/esm/components/ContextSelector/ContextSelector.d.ts.map +1 -1
- package/dist/esm/components/ContextSelector/ContextSelector.js +1 -1
- package/dist/esm/components/ContextSelector/ContextSelector.js.map +1 -1
- package/dist/esm/components/Modal/ModalBoxTitle.d.ts.map +1 -1
- package/dist/esm/components/Modal/ModalBoxTitle.js +3 -3
- package/dist/esm/components/Modal/ModalBoxTitle.js.map +1 -1
- package/dist/esm/components/Modal/ModalContent.js +1 -1
- package/dist/esm/components/Modal/ModalContent.js.map +1 -1
- package/dist/esm/components/Popover/Popover.d.ts.map +1 -1
- package/dist/esm/components/Popover/Popover.js +1 -0
- package/dist/esm/components/Popover/Popover.js.map +1 -1
- package/dist/esm/components/Slider/Slider.d.ts.map +1 -1
- package/dist/esm/components/Slider/Slider.js +1 -3
- package/dist/esm/components/Slider/Slider.js.map +1 -1
- package/dist/js/components/AboutModal/AboutModalContainer.js +1 -1
- package/dist/js/components/AboutModal/AboutModalContainer.js.map +1 -1
- package/dist/js/components/ContextSelector/ContextSelector.d.ts.map +1 -1
- package/dist/js/components/ContextSelector/ContextSelector.js +1 -1
- package/dist/js/components/ContextSelector/ContextSelector.js.map +1 -1
- package/dist/js/components/Modal/ModalBoxTitle.d.ts.map +1 -1
- package/dist/js/components/Modal/ModalBoxTitle.js +3 -3
- package/dist/js/components/Modal/ModalBoxTitle.js.map +1 -1
- package/dist/js/components/Modal/ModalContent.js +1 -1
- package/dist/js/components/Modal/ModalContent.js.map +1 -1
- package/dist/js/components/Popover/Popover.d.ts.map +1 -1
- package/dist/js/components/Popover/Popover.js +1 -0
- package/dist/js/components/Popover/Popover.js.map +1 -1
- package/dist/js/components/Slider/Slider.d.ts.map +1 -1
- package/dist/js/components/Slider/Slider.js +1 -3
- package/dist/js/components/Slider/Slider.js.map +1 -1
- package/dist/umd/react-core.js +722 -164
- package/dist/umd/react-core.min.css +10 -10
- package/dist/umd/react-core.min.js +7 -7
- package/package.json +6 -6
- package/src/components/AboutModal/AboutModalContainer.tsx +1 -1
- package/src/components/ContextSelector/ContextSelector.tsx +4 -1
- package/src/components/ExpandableSection/examples/ExpandableSection.md +47 -0
- package/src/components/Modal/ModalBoxTitle.tsx +3 -9
- package/src/components/Modal/ModalContent.tsx +1 -1
- package/src/components/Popover/Popover.tsx +1 -0
- package/src/components/Slider/Slider.tsx +1 -3
- package/src/components/Slider/examples/Slider.md +29 -2
- package/src/demos/ComposableMenu/examples/ComposableActionsMenu.tsx +12 -1
- package/src/demos/ComposableMenu/examples/ComposableContextSelector.tsx +12 -1
- package/src/demos/ComposableMenu/examples/ComposableDateSelect.tsx +13 -2
- package/src/demos/ComposableMenu/examples/ComposableDrilldownMenu.tsx +12 -1
- package/src/demos/ComposableMenu/examples/ComposableDropdwnVariants.tsx +10 -6
- package/src/demos/ComposableMenu/examples/ComposableFlyout.tsx +12 -1
- package/src/demos/ComposableMenu/examples/ComposableOptionsMenuVariants.tsx +6 -1
- package/src/demos/ComposableMenu/examples/ComposableSimpleDropdown.tsx +6 -1
- package/src/demos/ComposableMenu/examples/ComposableSimpleSelect.tsx +6 -1
- package/src/demos/ComposableMenu/examples/ComposableTreeViewMenu.tsx +12 -12
- package/src/demos/SearchInput/SearchInput.md +47 -44
package/dist/umd/react-core.js
CHANGED
|
@@ -123,12 +123,24 @@
|
|
|
123
123
|
};
|
|
124
124
|
|
|
125
125
|
/*!
|
|
126
|
-
* tabbable 5.
|
|
126
|
+
* tabbable 5.3.2
|
|
127
127
|
* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE
|
|
128
128
|
*/
|
|
129
|
-
var candidateSelectors = ['input', 'select', 'textarea', 'a[href]', 'button', '[tabindex]', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])', 'details>summary:first-of-type', 'details'];
|
|
129
|
+
var candidateSelectors = ['input', 'select', 'textarea', 'a[href]', 'button', '[tabindex]:not(slot)', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])', 'details>summary:first-of-type', 'details'];
|
|
130
130
|
var candidateSelector = /* #__PURE__ */candidateSelectors.join(',');
|
|
131
|
-
var
|
|
131
|
+
var NoElement = typeof Element === 'undefined';
|
|
132
|
+
var matches = NoElement ? function () {} : Element.prototype.matches || Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
|
|
133
|
+
var getRootNode = !NoElement && Element.prototype.getRootNode ? function (element) {
|
|
134
|
+
return element.getRootNode();
|
|
135
|
+
} : function (element) {
|
|
136
|
+
return element.ownerDocument;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* @param {Element} el container to check in
|
|
140
|
+
* @param {boolean} includeContainer add container to check
|
|
141
|
+
* @param {(node: Element) => boolean} filter filter candidates
|
|
142
|
+
* @returns {Element[]}
|
|
143
|
+
*/
|
|
132
144
|
|
|
133
145
|
var getCandidates = function getCandidates(el, includeContainer, filter) {
|
|
134
146
|
var candidates = Array.prototype.slice.apply(el.querySelectorAll(candidateSelector));
|
|
@@ -140,31 +152,112 @@
|
|
|
140
152
|
candidates = candidates.filter(filter);
|
|
141
153
|
return candidates;
|
|
142
154
|
};
|
|
155
|
+
/**
|
|
156
|
+
* @callback GetShadowRoot
|
|
157
|
+
* @param {Element} element to check for shadow root
|
|
158
|
+
* @returns {ShadowRoot|boolean} ShadowRoot if available or boolean indicating if a shadowRoot is attached but not available.
|
|
159
|
+
*/
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @typedef {Object} CandidatesScope
|
|
163
|
+
* @property {Element} scope contains inner candidates
|
|
164
|
+
* @property {Element[]} candidates
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @typedef {Object} IterativeOptions
|
|
169
|
+
* @property {GetShadowRoot|boolean} getShadowRoot true if shadow support is enabled; falsy if not;
|
|
170
|
+
* if a function, implies shadow support is enabled and either returns the shadow root of an element
|
|
171
|
+
* or a boolean stating if it has an undisclosed shadow root
|
|
172
|
+
* @property {(node: Element) => boolean} filter filter candidates
|
|
173
|
+
* @property {boolean} flatten if true then result will flatten any CandidatesScope into the returned list
|
|
174
|
+
*/
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* @param {Element[]} elements list of element containers to match candidates from
|
|
178
|
+
* @param {boolean} includeContainer add container list to check
|
|
179
|
+
* @param {IterativeOptions} options
|
|
180
|
+
* @returns {Array.<Element|CandidatesScope>}
|
|
181
|
+
*/
|
|
143
182
|
|
|
144
|
-
var isContentEditable = function isContentEditable(node) {
|
|
145
|
-
return node.contentEditable === 'true';
|
|
146
|
-
};
|
|
147
183
|
|
|
148
|
-
var
|
|
149
|
-
var
|
|
184
|
+
var getCandidatesIteratively = function getCandidatesIteratively(elements, includeContainer, options) {
|
|
185
|
+
var candidates = [];
|
|
186
|
+
var elementsToCheck = Array.from(elements);
|
|
150
187
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
} // Browsers do not return `tabIndex` correctly for contentEditable nodes;
|
|
154
|
-
// so if they don't have a tabindex attribute specifically set, assume it's 0.
|
|
188
|
+
while (elementsToCheck.length) {
|
|
189
|
+
var element = elementsToCheck.shift();
|
|
155
190
|
|
|
191
|
+
if (element.tagName === 'SLOT') {
|
|
192
|
+
// add shadow dom slot scope (slot itself cannot be focusable)
|
|
193
|
+
var assigned = element.assignedElements();
|
|
194
|
+
var content = assigned.length ? assigned : element.children;
|
|
195
|
+
var nestedCandidates = getCandidatesIteratively(content, true, options);
|
|
156
196
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
197
|
+
if (options.flatten) {
|
|
198
|
+
candidates.push.apply(candidates, nestedCandidates);
|
|
199
|
+
} else {
|
|
200
|
+
candidates.push({
|
|
201
|
+
scope: element,
|
|
202
|
+
candidates: nestedCandidates
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
} else {
|
|
206
|
+
// check candidate element
|
|
207
|
+
var validCandidate = matches.call(element, candidateSelector);
|
|
208
|
+
|
|
209
|
+
if (validCandidate && options.filter(element) && (includeContainer || !elements.includes(element))) {
|
|
210
|
+
candidates.push(element);
|
|
211
|
+
} // iterate over shadow content if possible
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
var shadowRoot = element.shadowRoot || // check for an undisclosed shadow
|
|
215
|
+
typeof options.getShadowRoot === 'function' && options.getShadowRoot(element);
|
|
216
|
+
|
|
217
|
+
if (shadowRoot) {
|
|
218
|
+
// add shadow dom scope IIF a shadow root node was given; otherwise, an undisclosed
|
|
219
|
+
// shadow exists, so look at light dom children as fallback BUT create a scope for any
|
|
220
|
+
// child candidates found because they're likely slotted elements (elements that are
|
|
221
|
+
// children of the web component element (which has the shadow), in the light dom, but
|
|
222
|
+
// slotted somewhere _inside_ the undisclosed shadow) -- the scope is created below,
|
|
223
|
+
// _after_ we return from this recursive call
|
|
224
|
+
var _nestedCandidates = getCandidatesIteratively(shadowRoot === true ? element.children : shadowRoot.children, true, options);
|
|
225
|
+
|
|
226
|
+
if (options.flatten) {
|
|
227
|
+
candidates.push.apply(candidates, _nestedCandidates);
|
|
228
|
+
} else {
|
|
229
|
+
candidates.push({
|
|
230
|
+
scope: element,
|
|
231
|
+
candidates: _nestedCandidates
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
// there's not shadow so just dig into the element's (light dom) children
|
|
236
|
+
// __without__ giving the element special scope treatment
|
|
237
|
+
elementsToCheck.unshift.apply(elementsToCheck, element.children);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
164
241
|
|
|
242
|
+
return candidates;
|
|
243
|
+
};
|
|
165
244
|
|
|
166
|
-
|
|
167
|
-
|
|
245
|
+
var getTabindex = function getTabindex(node, isScope) {
|
|
246
|
+
if (node.tabIndex < 0) {
|
|
247
|
+
// in Chrome, <details/>, <audio controls/> and <video controls/> elements get a default
|
|
248
|
+
// `tabIndex` of -1 when the 'tabindex' attribute isn't specified in the DOM,
|
|
249
|
+
// yet they are still part of the regular tab order; in FF, they get a default
|
|
250
|
+
// `tabIndex` of 0; since Chrome still puts those elements in the regular tab
|
|
251
|
+
// order, consider their tab index to be 0.
|
|
252
|
+
// Also browsers do not return `tabIndex` correctly for contentEditable nodes;
|
|
253
|
+
// so if they don't have a tabindex attribute specifically set, assume it's 0.
|
|
254
|
+
//
|
|
255
|
+
// isScope is positive for custom element with shadow root or slot that by default
|
|
256
|
+
// have tabIndex -1, but need to be sorted by document order in order for their
|
|
257
|
+
// content to be inserted in the correct position
|
|
258
|
+
if ((isScope || /^(AUDIO|VIDEO|DETAILS)$/.test(node.tagName) || node.isContentEditable) && isNaN(parseInt(node.getAttribute('tabindex'), 10))) {
|
|
259
|
+
return 0;
|
|
260
|
+
}
|
|
168
261
|
}
|
|
169
262
|
|
|
170
263
|
return node.tabIndex;
|
|
@@ -202,8 +295,26 @@
|
|
|
202
295
|
return true;
|
|
203
296
|
}
|
|
204
297
|
|
|
205
|
-
var radioScope = node.form || node
|
|
206
|
-
|
|
298
|
+
var radioScope = node.form || getRootNode(node);
|
|
299
|
+
|
|
300
|
+
var queryRadios = function queryRadios(name) {
|
|
301
|
+
return radioScope.querySelectorAll('input[type="radio"][name="' + name + '"]');
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
var radioSet;
|
|
305
|
+
|
|
306
|
+
if (typeof window !== 'undefined' && typeof window.CSS !== 'undefined' && typeof window.CSS.escape === 'function') {
|
|
307
|
+
radioSet = queryRadios(window.CSS.escape(node.name));
|
|
308
|
+
} else {
|
|
309
|
+
try {
|
|
310
|
+
radioSet = queryRadios(node.name);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
// eslint-disable-next-line no-console
|
|
313
|
+
console.error('Looks like you have a radio button with a name attribute containing invalid CSS selector characters and need the CSS.escape polyfill: %s', err.message);
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
207
318
|
var checked = getCheckedRadio(radioSet, node.form);
|
|
208
319
|
return !checked || checked === node;
|
|
209
320
|
};
|
|
@@ -216,7 +327,23 @@
|
|
|
216
327
|
return isRadio(node) && !isTabbableRadio(node);
|
|
217
328
|
};
|
|
218
329
|
|
|
219
|
-
var
|
|
330
|
+
var isZeroArea = function isZeroArea(node) {
|
|
331
|
+
var _node$getBoundingClie = node.getBoundingClientRect(),
|
|
332
|
+
width = _node$getBoundingClie.width,
|
|
333
|
+
height = _node$getBoundingClie.height;
|
|
334
|
+
|
|
335
|
+
return width === 0 && height === 0;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
var isHidden = function isHidden(node, _ref) {
|
|
339
|
+
var displayCheck = _ref.displayCheck,
|
|
340
|
+
getShadowRoot = _ref.getShadowRoot;
|
|
341
|
+
|
|
342
|
+
// NOTE: visibility will be `undefined` if node is detached from the document
|
|
343
|
+
// (see notes about this further down), which means we will consider it visible
|
|
344
|
+
// (this is legacy behavior from a very long way back)
|
|
345
|
+
// NOTE: we check this regardless of `displayCheck="none"` because this is a
|
|
346
|
+
// _visibility_ check, not a _display_ check
|
|
220
347
|
if (getComputedStyle(node).visibility === 'hidden') {
|
|
221
348
|
return true;
|
|
222
349
|
}
|
|
@@ -226,64 +353,234 @@
|
|
|
226
353
|
|
|
227
354
|
if (matches.call(nodeUnderDetails, 'details:not([open]) *')) {
|
|
228
355
|
return true;
|
|
229
|
-
}
|
|
356
|
+
} // The root node is the shadow root if the node is in a shadow DOM; some document otherwise
|
|
357
|
+
// (but NOT _the_ document; see second 'If' comment below for more).
|
|
358
|
+
// If rootNode is shadow root, it'll have a host, which is the element to which the shadow
|
|
359
|
+
// is attached, and the one we need to check if it's in the document or not (because the
|
|
360
|
+
// shadow, and all nodes it contains, is never considered in the document since shadows
|
|
361
|
+
// behave like self-contained DOMs; but if the shadow's HOST, which is part of the document,
|
|
362
|
+
// is hidden, or is not in the document itself but is detached, it will affect the shadow's
|
|
363
|
+
// visibility, including all the nodes it contains). The host could be any normal node,
|
|
364
|
+
// or a custom element (i.e. web component). Either way, that's the one that is considered
|
|
365
|
+
// part of the document, not the shadow root, nor any of its children (i.e. the node being
|
|
366
|
+
// tested).
|
|
367
|
+
// If rootNode is not a shadow root, it won't have a host, and so rootNode should be the
|
|
368
|
+
// document (per the docs) and while it's a Document-type object, that document does not
|
|
369
|
+
// appear to be the same as the node's `ownerDocument` for some reason, so it's safer
|
|
370
|
+
// to ignore the rootNode at this point, and use `node.ownerDocument`. Otherwise,
|
|
371
|
+
// using `rootNode.contains(node)` will _always_ be true we'll get false-positives when
|
|
372
|
+
// node is actually detached.
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
var nodeRootHost = getRootNode(node).host;
|
|
376
|
+
var nodeIsAttached = (nodeRootHost === null || nodeRootHost === void 0 ? void 0 : nodeRootHost.ownerDocument.contains(nodeRootHost)) || node.ownerDocument.contains(node);
|
|
377
|
+
|
|
378
|
+
if (!displayCheck || displayCheck === 'full') {
|
|
379
|
+
if (typeof getShadowRoot === 'function') {
|
|
380
|
+
// figure out if we should consider the node to be in an undisclosed shadow and use the
|
|
381
|
+
// 'non-zero-area' fallback
|
|
382
|
+
var originalNode = node;
|
|
383
|
+
|
|
384
|
+
while (node) {
|
|
385
|
+
var parentElement = node.parentElement;
|
|
386
|
+
var rootNode = getRootNode(node);
|
|
387
|
+
|
|
388
|
+
if (parentElement && !parentElement.shadowRoot && getShadowRoot(parentElement) === true // check if there's an undisclosed shadow
|
|
389
|
+
) {
|
|
390
|
+
// node has an undisclosed shadow which means we can only treat it as a black box, so we
|
|
391
|
+
// fall back to a non-zero-area test
|
|
392
|
+
return isZeroArea(node);
|
|
393
|
+
} else if (node.assignedSlot) {
|
|
394
|
+
// iterate up slot
|
|
395
|
+
node = node.assignedSlot;
|
|
396
|
+
} else if (!parentElement && rootNode !== node.ownerDocument) {
|
|
397
|
+
// cross shadow boundary
|
|
398
|
+
node = rootNode.host;
|
|
399
|
+
} else {
|
|
400
|
+
// iterate up normal dom
|
|
401
|
+
node = parentElement;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
230
404
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
405
|
+
node = originalNode;
|
|
406
|
+
} // else, `getShadowRoot` might be true, but all that does is enable shadow DOM support
|
|
407
|
+
// (i.e. it does not also presume that all nodes might have undisclosed shadows); or
|
|
408
|
+
// it might be a falsy value, which means shadow DOM support is disabled
|
|
409
|
+
// Since we didn't find it sitting in an undisclosed shadow (or shadows are disabled)
|
|
410
|
+
// now we can just test to see if it would normally be visible or not, provided it's
|
|
411
|
+
// attached to the main document.
|
|
412
|
+
// NOTE: We must consider case where node is inside a shadow DOM and given directly to
|
|
413
|
+
// `isTabbable()` or `isFocusable()` -- regardless of `getShadowRoot` option setting.
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
if (nodeIsAttached) {
|
|
417
|
+
// this works wherever the node is: if there's at least one client rect, it's
|
|
418
|
+
// somehow displayed; it also covers the CSS 'display: contents' case where the
|
|
419
|
+
// node itself is hidden in place of its contents; and there's no need to search
|
|
420
|
+
// up the hierarchy either
|
|
421
|
+
return !node.getClientRects().length;
|
|
422
|
+
} // Else, the node isn't attached to the document, which means the `getClientRects()`
|
|
423
|
+
// API will __always__ return zero rects (this can happen, for example, if React
|
|
424
|
+
// is used to render nodes onto a detached tree, as confirmed in this thread:
|
|
425
|
+
// https://github.com/facebook/react/issues/9117#issuecomment-284228870)
|
|
426
|
+
//
|
|
427
|
+
// It also means that even window.getComputedStyle(node).display will return `undefined`
|
|
428
|
+
// because styles are only computed for nodes that are in the document.
|
|
429
|
+
//
|
|
430
|
+
// NOTE: THIS HAS BEEN THE CASE FOR YEARS. It is not new, nor is it caused by tabbable
|
|
431
|
+
// somehow. Though it was never stated officially, anyone who has ever used tabbable
|
|
432
|
+
// APIs on nodes in detached containers has actually implicitly used tabbable in what
|
|
433
|
+
// was later (as of v5.2.0 on Apr 9, 2021) called `displayCheck="none"` mode -- essentially
|
|
434
|
+
// considering __everything__ to be visible because of the innability to determine styles.
|
|
435
|
+
|
|
436
|
+
} else if (displayCheck === 'non-zero-area') {
|
|
437
|
+
// NOTE: Even though this tests that the node's client rect is non-zero to determine
|
|
438
|
+
// whether it's displayed, and that a detached node will __always__ have a zero-area
|
|
439
|
+
// client rect, we don't special-case for whether the node is attached or not. In
|
|
440
|
+
// this mode, we do want to consider nodes that have a zero area to be hidden at all
|
|
441
|
+
// times, and that includes attached or not.
|
|
442
|
+
return isZeroArea(node);
|
|
443
|
+
} // visible, as far as we can tell, or per current `displayCheck` mode
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
return false;
|
|
447
|
+
}; // form fields (nested) inside a disabled fieldset are not focusable/tabbable
|
|
448
|
+
// unless they are in the _first_ <legend> element of the top-most disabled
|
|
449
|
+
// fieldset
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
var isDisabledFromFieldset = function isDisabledFromFieldset(node) {
|
|
453
|
+
if (/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(node.tagName)) {
|
|
454
|
+
var parentNode = node.parentElement; // check if `node` is contained in a disabled <fieldset>
|
|
455
|
+
|
|
456
|
+
while (parentNode) {
|
|
457
|
+
if (parentNode.tagName === 'FIELDSET' && parentNode.disabled) {
|
|
458
|
+
// look for the first <legend> among the children of the disabled <fieldset>
|
|
459
|
+
for (var i = 0; i < parentNode.children.length; i++) {
|
|
460
|
+
var child = parentNode.children.item(i); // when the first <legend> (in document order) is found
|
|
461
|
+
|
|
462
|
+
if (child.tagName === 'LEGEND') {
|
|
463
|
+
// if its parent <fieldset> is not nested in another disabled <fieldset>,
|
|
464
|
+
// return whether `node` is a descendant of its first <legend>
|
|
465
|
+
return matches.call(parentNode, 'fieldset[disabled] *') ? true : !child.contains(node);
|
|
466
|
+
}
|
|
467
|
+
} // the disabled <fieldset> containing `node` has no <legend>
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
parentNode = parentNode.parentElement;
|
|
234
474
|
}
|
|
475
|
+
} // else, node's tabbable/focusable state should not be affected by a fieldset's
|
|
476
|
+
// enabled/disabled state
|
|
235
477
|
|
|
236
|
-
node = node.parentElement;
|
|
237
|
-
}
|
|
238
478
|
|
|
239
479
|
return false;
|
|
240
480
|
};
|
|
241
481
|
|
|
242
|
-
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(node) {
|
|
243
|
-
if (node.disabled || isHiddenInput(node) || isHidden(node) ||
|
|
244
|
-
|
|
245
|
-
isDetailsWithSummary(node)) {
|
|
482
|
+
var isNodeMatchingSelectorFocusable = function isNodeMatchingSelectorFocusable(options, node) {
|
|
483
|
+
if (node.disabled || isHiddenInput(node) || isHidden(node, options) || // For a details element with a summary, the summary element gets the focus
|
|
484
|
+
isDetailsWithSummary(node) || isDisabledFromFieldset(node)) {
|
|
246
485
|
return false;
|
|
247
486
|
}
|
|
248
487
|
|
|
249
488
|
return true;
|
|
250
489
|
};
|
|
251
490
|
|
|
252
|
-
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(node) {
|
|
253
|
-
if (
|
|
491
|
+
var isNodeMatchingSelectorTabbable = function isNodeMatchingSelectorTabbable(options, node) {
|
|
492
|
+
if (isNonTabbableRadio(node) || getTabindex(node) < 0 || !isNodeMatchingSelectorFocusable(options, node)) {
|
|
254
493
|
return false;
|
|
255
494
|
}
|
|
256
495
|
|
|
257
496
|
return true;
|
|
258
497
|
};
|
|
498
|
+
/**
|
|
499
|
+
* @param {Array.<Element|CandidatesScope>} candidates
|
|
500
|
+
* @returns Element[]
|
|
501
|
+
*/
|
|
259
502
|
|
|
260
|
-
|
|
261
|
-
|
|
503
|
+
|
|
504
|
+
var sortByOrder = function sortByOrder(candidates) {
|
|
262
505
|
var regularTabbables = [];
|
|
263
506
|
var orderedTabbables = [];
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
var
|
|
507
|
+
candidates.forEach(function (item, i) {
|
|
508
|
+
var isScope = !!item.scope;
|
|
509
|
+
var element = isScope ? item.scope : item;
|
|
510
|
+
var candidateTabindex = getTabindex(element, isScope);
|
|
511
|
+
var elements = isScope ? sortByOrder(item.candidates) : element;
|
|
267
512
|
|
|
268
513
|
if (candidateTabindex === 0) {
|
|
269
|
-
regularTabbables.push(
|
|
514
|
+
isScope ? regularTabbables.push.apply(regularTabbables, elements) : regularTabbables.push(element);
|
|
270
515
|
} else {
|
|
271
516
|
orderedTabbables.push({
|
|
272
517
|
documentOrder: i,
|
|
273
518
|
tabIndex: candidateTabindex,
|
|
274
|
-
|
|
519
|
+
item: item,
|
|
520
|
+
isScope: isScope,
|
|
521
|
+
content: elements
|
|
275
522
|
});
|
|
276
523
|
}
|
|
277
524
|
});
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
525
|
+
return orderedTabbables.sort(sortOrderedTabbables).reduce(function (acc, sortable) {
|
|
526
|
+
sortable.isScope ? acc.push.apply(acc, sortable.content) : acc.push(sortable.content);
|
|
527
|
+
return acc;
|
|
528
|
+
}, []).concat(regularTabbables);
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
var tabbable = function tabbable(el, options) {
|
|
532
|
+
options = options || {};
|
|
533
|
+
var candidates;
|
|
534
|
+
|
|
535
|
+
if (options.getShadowRoot) {
|
|
536
|
+
candidates = getCandidatesIteratively([el], options.includeContainer, {
|
|
537
|
+
filter: isNodeMatchingSelectorTabbable.bind(null, options),
|
|
538
|
+
flatten: false,
|
|
539
|
+
getShadowRoot: options.getShadowRoot
|
|
540
|
+
});
|
|
541
|
+
} else {
|
|
542
|
+
candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorTabbable.bind(null, options));
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return sortByOrder(candidates);
|
|
546
|
+
};
|
|
547
|
+
|
|
548
|
+
var focusable = function focusable(el, options) {
|
|
549
|
+
options = options || {};
|
|
550
|
+
var candidates;
|
|
551
|
+
|
|
552
|
+
if (options.getShadowRoot) {
|
|
553
|
+
candidates = getCandidatesIteratively([el], options.includeContainer, {
|
|
554
|
+
filter: isNodeMatchingSelectorFocusable.bind(null, options),
|
|
555
|
+
flatten: true,
|
|
556
|
+
getShadowRoot: options.getShadowRoot
|
|
557
|
+
});
|
|
558
|
+
} else {
|
|
559
|
+
candidates = getCandidates(el, options.includeContainer, isNodeMatchingSelectorFocusable.bind(null, options));
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return candidates;
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
var isTabbable = function isTabbable(node, options) {
|
|
566
|
+
options = options || {};
|
|
567
|
+
|
|
568
|
+
if (!node) {
|
|
569
|
+
throw new Error('No node provided');
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if (matches.call(node, candidateSelector) === false) {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return isNodeMatchingSelectorTabbable(options, node);
|
|
282
577
|
};
|
|
283
578
|
|
|
284
579
|
var focusableCandidateSelector = /* #__PURE__ */candidateSelectors.concat('iframe').join(',');
|
|
285
580
|
|
|
286
|
-
var isFocusable = function isFocusable(node) {
|
|
581
|
+
var isFocusable = function isFocusable(node, options) {
|
|
582
|
+
options = options || {};
|
|
583
|
+
|
|
287
584
|
if (!node) {
|
|
288
585
|
throw new Error('No node provided');
|
|
289
586
|
}
|
|
@@ -292,38 +589,22 @@
|
|
|
292
589
|
return false;
|
|
293
590
|
}
|
|
294
591
|
|
|
295
|
-
return isNodeMatchingSelectorFocusable(node);
|
|
592
|
+
return isNodeMatchingSelectorFocusable(options, node);
|
|
296
593
|
};
|
|
297
594
|
|
|
298
595
|
/*!
|
|
299
|
-
* focus-trap 6.
|
|
596
|
+
* focus-trap 6.9.2
|
|
300
597
|
* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE
|
|
301
598
|
*/
|
|
302
599
|
|
|
303
|
-
function _defineProperty$1(obj, key, value) {
|
|
304
|
-
if (key in obj) {
|
|
305
|
-
Object.defineProperty(obj, key, {
|
|
306
|
-
value: value,
|
|
307
|
-
enumerable: true,
|
|
308
|
-
configurable: true,
|
|
309
|
-
writable: true
|
|
310
|
-
});
|
|
311
|
-
} else {
|
|
312
|
-
obj[key] = value;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return obj;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
600
|
function ownKeys(object, enumerableOnly) {
|
|
319
601
|
var keys = Object.keys(object);
|
|
320
602
|
|
|
321
603
|
if (Object.getOwnPropertySymbols) {
|
|
322
604
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
323
|
-
|
|
605
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
324
606
|
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
325
|
-
});
|
|
326
|
-
keys.push.apply(keys, symbols);
|
|
607
|
+
})), keys.push.apply(keys, symbols);
|
|
327
608
|
}
|
|
328
609
|
|
|
329
610
|
return keys;
|
|
@@ -331,25 +612,31 @@
|
|
|
331
612
|
|
|
332
613
|
function _objectSpread2(target) {
|
|
333
614
|
for (var i = 1; i < arguments.length; i++) {
|
|
334
|
-
var source = arguments[i]
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
} else if (Object.getOwnPropertyDescriptors) {
|
|
341
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
342
|
-
} else {
|
|
343
|
-
ownKeys(Object(source)).forEach(function (key) {
|
|
344
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
345
|
-
});
|
|
346
|
-
}
|
|
615
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
616
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
617
|
+
_defineProperty$1(target, key, source[key]);
|
|
618
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
619
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
620
|
+
});
|
|
347
621
|
}
|
|
348
622
|
|
|
349
623
|
return target;
|
|
350
624
|
}
|
|
351
625
|
|
|
352
|
-
|
|
626
|
+
function _defineProperty$1(obj, key, value) {
|
|
627
|
+
if (key in obj) {
|
|
628
|
+
Object.defineProperty(obj, key, {
|
|
629
|
+
value: value,
|
|
630
|
+
enumerable: true,
|
|
631
|
+
configurable: true,
|
|
632
|
+
writable: true
|
|
633
|
+
});
|
|
634
|
+
} else {
|
|
635
|
+
obj[key] = value;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
return obj;
|
|
639
|
+
}
|
|
353
640
|
|
|
354
641
|
var activeFocusTraps = function () {
|
|
355
642
|
var trapQueue = [];
|
|
@@ -401,10 +688,54 @@
|
|
|
401
688
|
|
|
402
689
|
var delay = function delay(fn) {
|
|
403
690
|
return setTimeout(fn, 0);
|
|
691
|
+
}; // Array.find/findIndex() are not supported on IE; this replicates enough
|
|
692
|
+
// of Array.findIndex() for our needs
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
var findIndex = function findIndex(arr, fn) {
|
|
696
|
+
var idx = -1;
|
|
697
|
+
arr.every(function (value, i) {
|
|
698
|
+
if (fn(value)) {
|
|
699
|
+
idx = i;
|
|
700
|
+
return false; // break
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return true; // next
|
|
704
|
+
});
|
|
705
|
+
return idx;
|
|
706
|
+
};
|
|
707
|
+
/**
|
|
708
|
+
* Get an option's value when it could be a plain value, or a handler that provides
|
|
709
|
+
* the value.
|
|
710
|
+
* @param {*} value Option's value to check.
|
|
711
|
+
* @param {...*} [params] Any parameters to pass to the handler, if `value` is a function.
|
|
712
|
+
* @returns {*} The `value`, or the handler's returned value.
|
|
713
|
+
*/
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
var valueOrHandler = function valueOrHandler(value) {
|
|
717
|
+
for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
718
|
+
params[_key - 1] = arguments[_key];
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
return typeof value === 'function' ? value.apply(void 0, params) : value;
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
var getActualTarget = function getActualTarget(event) {
|
|
725
|
+
// NOTE: If the trap is _inside_ a shadow DOM, event.target will always be the
|
|
726
|
+
// shadow host. However, event.target.composedPath() will be an array of
|
|
727
|
+
// nodes "clicked" from inner-most (the actual element inside the shadow) to
|
|
728
|
+
// outer-most (the host HTML document). If we have access to composedPath(),
|
|
729
|
+
// then use its first element; otherwise, fall back to event.target (and
|
|
730
|
+
// this only works for an _open_ shadow DOM; otherwise,
|
|
731
|
+
// composedPath()[0] === event.target always).
|
|
732
|
+
return event.target.shadowRoot && typeof event.composedPath === 'function' ? event.composedPath()[0] : event.target;
|
|
404
733
|
};
|
|
405
734
|
|
|
406
735
|
var createFocusTrap = function createFocusTrap(elements, userOptions) {
|
|
407
|
-
|
|
736
|
+
// SSR: a live trap shouldn't be created in this type of environment so this
|
|
737
|
+
// should be safe code to execute if the `document` option isn't specified
|
|
738
|
+
var doc = (userOptions === null || userOptions === void 0 ? void 0 : userOptions.document) || document;
|
|
408
739
|
|
|
409
740
|
var config = _objectSpread2({
|
|
410
741
|
returnFocusOnDeactivate: true,
|
|
@@ -413,51 +744,122 @@
|
|
|
413
744
|
}, userOptions);
|
|
414
745
|
|
|
415
746
|
var state = {
|
|
747
|
+
// containers given to createFocusTrap()
|
|
416
748
|
// @type {Array<HTMLElement>}
|
|
417
749
|
containers: [],
|
|
418
|
-
// list of objects identifying
|
|
419
|
-
// the trap
|
|
750
|
+
// list of objects identifying tabbable nodes in `containers` in the trap
|
|
420
751
|
// NOTE: it's possible that a group has no tabbable nodes if nodes get removed while the trap
|
|
421
752
|
// is active, but the trap should never get to a state where there isn't at least one group
|
|
422
753
|
// with at least one tabbable node in it (that would lead to an error condition that would
|
|
423
754
|
// result in an error being thrown)
|
|
424
|
-
// @type {Array<{
|
|
755
|
+
// @type {Array<{
|
|
756
|
+
// container: HTMLElement,
|
|
757
|
+
// tabbableNodes: Array<HTMLElement>, // empty if none
|
|
758
|
+
// focusableNodes: Array<HTMLElement>, // empty if none
|
|
759
|
+
// firstTabbableNode: HTMLElement|null,
|
|
760
|
+
// lastTabbableNode: HTMLElement|null,
|
|
761
|
+
// nextTabbableNode: (node: HTMLElement, forward: boolean) => HTMLElement|undefined
|
|
762
|
+
// }>}
|
|
763
|
+
containerGroups: [],
|
|
764
|
+
// same order/length as `containers` list
|
|
765
|
+
// references to objects in `containerGroups`, but only those that actually have
|
|
766
|
+
// tabbable nodes in them
|
|
767
|
+
// NOTE: same order as `containers` and `containerGroups`, but __not necessarily__
|
|
768
|
+
// the same length
|
|
425
769
|
tabbableGroups: [],
|
|
426
770
|
nodeFocusedBeforeActivation: null,
|
|
427
771
|
mostRecentlyFocusedNode: null,
|
|
428
772
|
active: false,
|
|
429
|
-
paused: false
|
|
773
|
+
paused: false,
|
|
774
|
+
// timer ID for when delayInitialFocus is true and initial focus in this trap
|
|
775
|
+
// has been delayed during activation
|
|
776
|
+
delayInitialFocusTimer: undefined
|
|
430
777
|
};
|
|
431
778
|
var trap; // eslint-disable-line prefer-const -- some private functions reference it, and its methods reference private functions, so we must declare here and define later
|
|
432
779
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
780
|
+
/**
|
|
781
|
+
* Gets a configuration option value.
|
|
782
|
+
* @param {Object|undefined} configOverrideOptions If true, and option is defined in this set,
|
|
783
|
+
* value will be taken from this object. Otherwise, value will be taken from base configuration.
|
|
784
|
+
* @param {string} optionName Name of the option whose value is sought.
|
|
785
|
+
* @param {string|undefined} [configOptionName] Name of option to use __instead of__ `optionName`
|
|
786
|
+
* IIF `configOverrideOptions` is not defined. Otherwise, `optionName` is used.
|
|
787
|
+
*/
|
|
788
|
+
|
|
789
|
+
var getOption = function getOption(configOverrideOptions, optionName, configOptionName) {
|
|
790
|
+
return configOverrideOptions && configOverrideOptions[optionName] !== undefined ? configOverrideOptions[optionName] : config[configOptionName || optionName];
|
|
791
|
+
};
|
|
792
|
+
/**
|
|
793
|
+
* Finds the index of the container that contains the element.
|
|
794
|
+
* @param {HTMLElement} element
|
|
795
|
+
* @returns {number} Index of the container in either `state.containers` or
|
|
796
|
+
* `state.containerGroups` (the order/length of these lists are the same); -1
|
|
797
|
+
* if the element isn't found.
|
|
798
|
+
*/
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
var findContainerIndex = function findContainerIndex(element) {
|
|
802
|
+
// NOTE: search `containerGroups` because it's possible a group contains no tabbable
|
|
803
|
+
// nodes, but still contains focusable nodes (e.g. if they all have `tabindex=-1`)
|
|
804
|
+
// and we still need to find the element in there
|
|
805
|
+
return state.containerGroups.findIndex(function (_ref) {
|
|
806
|
+
var container = _ref.container,
|
|
807
|
+
tabbableNodes = _ref.tabbableNodes;
|
|
808
|
+
return container.contains(element) || // fall back to explicit tabbable search which will take into consideration any
|
|
809
|
+
// web components if the `tabbableOptions.getShadowRoot` option was used for
|
|
810
|
+
// the trap, enabling shadow DOM support in tabbable (`Node.contains()` doesn't
|
|
811
|
+
// look inside web components even if open)
|
|
812
|
+
tabbableNodes.find(function (node) {
|
|
813
|
+
return node === element;
|
|
814
|
+
});
|
|
436
815
|
});
|
|
437
816
|
};
|
|
817
|
+
/**
|
|
818
|
+
* Gets the node for the given option, which is expected to be an option that
|
|
819
|
+
* can be either a DOM node, a string that is a selector to get a node, `false`
|
|
820
|
+
* (if a node is explicitly NOT given), or a function that returns any of these
|
|
821
|
+
* values.
|
|
822
|
+
* @param {string} optionName
|
|
823
|
+
* @returns {undefined | false | HTMLElement | SVGElement} Returns
|
|
824
|
+
* `undefined` if the option is not specified; `false` if the option
|
|
825
|
+
* resolved to `false` (node explicitly not given); otherwise, the resolved
|
|
826
|
+
* DOM node.
|
|
827
|
+
* @throws {Error} If the option is set, not `false`, and is not, or does not
|
|
828
|
+
* resolve to a node.
|
|
829
|
+
*/
|
|
830
|
+
|
|
438
831
|
|
|
439
832
|
var getNodeForOption = function getNodeForOption(optionName) {
|
|
440
833
|
var optionValue = config[optionName];
|
|
441
834
|
|
|
442
|
-
if (
|
|
443
|
-
|
|
835
|
+
if (typeof optionValue === 'function') {
|
|
836
|
+
for (var _len2 = arguments.length, params = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
|
837
|
+
params[_key2 - 1] = arguments[_key2];
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
optionValue = optionValue.apply(void 0, params);
|
|
444
841
|
}
|
|
445
842
|
|
|
446
|
-
|
|
843
|
+
if (optionValue === true) {
|
|
844
|
+
optionValue = undefined; // use default value
|
|
845
|
+
}
|
|
447
846
|
|
|
448
|
-
if (
|
|
449
|
-
|
|
847
|
+
if (!optionValue) {
|
|
848
|
+
if (optionValue === undefined || optionValue === false) {
|
|
849
|
+
return optionValue;
|
|
850
|
+
} // else, empty string (invalid), null (invalid), 0 (invalid)
|
|
450
851
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
}
|
|
852
|
+
|
|
853
|
+
throw new Error("`".concat(optionName, "` was specified but was not a node, or did not return a node"));
|
|
454
854
|
}
|
|
455
855
|
|
|
456
|
-
|
|
457
|
-
|
|
856
|
+
var node = optionValue; // could be HTMLElement, SVGElement, or non-empty string at this point
|
|
857
|
+
|
|
858
|
+
if (typeof optionValue === 'string') {
|
|
859
|
+
node = doc.querySelector(optionValue); // resolve to node, or null if fails
|
|
458
860
|
|
|
459
861
|
if (!node) {
|
|
460
|
-
throw new Error("`".concat(optionName, "`
|
|
862
|
+
throw new Error("`".concat(optionName, "` as selector refers to no known node"));
|
|
461
863
|
}
|
|
462
864
|
}
|
|
463
865
|
|
|
@@ -465,16 +867,22 @@
|
|
|
465
867
|
};
|
|
466
868
|
|
|
467
869
|
var getInitialFocusNode = function getInitialFocusNode() {
|
|
468
|
-
var node;
|
|
870
|
+
var node = getNodeForOption('initialFocus'); // false explicitly indicates we want no initialFocus at all
|
|
469
871
|
|
|
470
|
-
if (
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
872
|
+
if (node === false) {
|
|
873
|
+
return false;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (node === undefined) {
|
|
877
|
+
// option not specified: use fallback options
|
|
878
|
+
if (findContainerIndex(doc.activeElement) >= 0) {
|
|
879
|
+
node = doc.activeElement;
|
|
880
|
+
} else {
|
|
881
|
+
var firstTabbableGroup = state.tabbableGroups[0];
|
|
882
|
+
var firstTabbableNode = firstTabbableGroup && firstTabbableGroup.firstTabbableNode; // NOTE: `fallbackFocus` option function cannot return `false` (not supported)
|
|
883
|
+
|
|
884
|
+
node = firstTabbableNode || getNodeForOption('fallbackFocus');
|
|
885
|
+
}
|
|
478
886
|
}
|
|
479
887
|
|
|
480
888
|
if (!node) {
|
|
@@ -485,28 +893,73 @@
|
|
|
485
893
|
};
|
|
486
894
|
|
|
487
895
|
var updateTabbableNodes = function updateTabbableNodes() {
|
|
488
|
-
state.
|
|
489
|
-
var tabbableNodes = tabbable(container);
|
|
896
|
+
state.containerGroups = state.containers.map(function (container) {
|
|
897
|
+
var tabbableNodes = tabbable(container, config.tabbableOptions); // NOTE: if we have tabbable nodes, we must have focusable nodes; focusable nodes
|
|
898
|
+
// are a superset of tabbable nodes
|
|
899
|
+
|
|
900
|
+
var focusableNodes = focusable(container, config.tabbableOptions);
|
|
901
|
+
return {
|
|
902
|
+
container: container,
|
|
903
|
+
tabbableNodes: tabbableNodes,
|
|
904
|
+
focusableNodes: focusableNodes,
|
|
905
|
+
firstTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[0] : null,
|
|
906
|
+
lastTabbableNode: tabbableNodes.length > 0 ? tabbableNodes[tabbableNodes.length - 1] : null,
|
|
490
907
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
908
|
+
/**
|
|
909
|
+
* Finds the __tabbable__ node that follows the given node in the specified direction,
|
|
910
|
+
* in this container, if any.
|
|
911
|
+
* @param {HTMLElement} node
|
|
912
|
+
* @param {boolean} [forward] True if going in forward tab order; false if going
|
|
913
|
+
* in reverse.
|
|
914
|
+
* @returns {HTMLElement|undefined} The next tabbable node, if any.
|
|
915
|
+
*/
|
|
916
|
+
nextTabbableNode: function nextTabbableNode(node) {
|
|
917
|
+
var forward = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
918
|
+
// NOTE: If tabindex is positive (in order to manipulate the tab order separate
|
|
919
|
+
// from the DOM order), this __will not work__ because the list of focusableNodes,
|
|
920
|
+
// while it contains tabbable nodes, does not sort its nodes in any order other
|
|
921
|
+
// than DOM order, because it can't: Where would you place focusable (but not
|
|
922
|
+
// tabbable) nodes in that order? They have no order, because they aren't tabbale...
|
|
923
|
+
// Support for positive tabindex is already broken and hard to manage (possibly
|
|
924
|
+
// not supportable, TBD), so this isn't going to make things worse than they
|
|
925
|
+
// already are, and at least makes things better for the majority of cases where
|
|
926
|
+
// tabindex is either 0/unset or negative.
|
|
927
|
+
// FYI, positive tabindex issue: https://github.com/focus-trap/focus-trap/issues/375
|
|
928
|
+
var nodeIdx = focusableNodes.findIndex(function (n) {
|
|
929
|
+
return n === node;
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
if (nodeIdx < 0) {
|
|
933
|
+
return undefined;
|
|
934
|
+
}
|
|
497
935
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
936
|
+
if (forward) {
|
|
937
|
+
return focusableNodes.slice(nodeIdx + 1).find(function (n) {
|
|
938
|
+
return isTabbable(n, config.tabbableOptions);
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
return focusableNodes.slice(0, nodeIdx).reverse().find(function (n) {
|
|
943
|
+
return isTabbable(n, config.tabbableOptions);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
});
|
|
948
|
+
state.tabbableGroups = state.containerGroups.filter(function (group) {
|
|
949
|
+
return group.tabbableNodes.length > 0;
|
|
950
|
+
}); // throw if no groups have tabbable nodes and we don't have a fallback focus node either
|
|
503
951
|
|
|
504
|
-
if (state.tabbableGroups.length <= 0 && !getNodeForOption('fallbackFocus')
|
|
952
|
+
if (state.tabbableGroups.length <= 0 && !getNodeForOption('fallbackFocus') // returning false not supported for this option
|
|
953
|
+
) {
|
|
505
954
|
throw new Error('Your focus-trap must have at least one container with at least one tabbable node in it at all times');
|
|
506
955
|
}
|
|
507
956
|
};
|
|
508
957
|
|
|
509
958
|
var tryFocus = function tryFocus(node) {
|
|
959
|
+
if (node === false) {
|
|
960
|
+
return;
|
|
961
|
+
}
|
|
962
|
+
|
|
510
963
|
if (node === doc.activeElement) {
|
|
511
964
|
return;
|
|
512
965
|
}
|
|
@@ -527,19 +980,21 @@
|
|
|
527
980
|
};
|
|
528
981
|
|
|
529
982
|
var getReturnFocusNode = function getReturnFocusNode(previousActiveElement) {
|
|
530
|
-
var node = getNodeForOption('setReturnFocus');
|
|
531
|
-
return node ? node : previousActiveElement;
|
|
983
|
+
var node = getNodeForOption('setReturnFocus', previousActiveElement);
|
|
984
|
+
return node ? node : node === false ? false : previousActiveElement;
|
|
532
985
|
}; // This needs to be done on mousedown and touchstart instead of click
|
|
533
986
|
// so that it precedes the focus event.
|
|
534
987
|
|
|
535
988
|
|
|
536
989
|
var checkPointerDown = function checkPointerDown(e) {
|
|
537
|
-
|
|
990
|
+
var target = getActualTarget(e);
|
|
991
|
+
|
|
992
|
+
if (findContainerIndex(target) >= 0) {
|
|
538
993
|
// allow the click since it ocurred inside the trap
|
|
539
994
|
return;
|
|
540
995
|
}
|
|
541
996
|
|
|
542
|
-
if (config.clickOutsideDeactivates) {
|
|
997
|
+
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
543
998
|
// immediately deactivate the trap
|
|
544
999
|
trap.deactivate({
|
|
545
1000
|
// if, on deactivation, we should return focus to the node originally-focused
|
|
@@ -553,7 +1008,7 @@
|
|
|
553
1008
|
// that was clicked, whether it's focusable or not; by setting
|
|
554
1009
|
// `returnFocus: true`, we'll attempt to re-focus the node originally-focused
|
|
555
1010
|
// on activation (or the configured `setReturnFocus` node)
|
|
556
|
-
returnFocus: config.returnFocusOnDeactivate && !isFocusable(
|
|
1011
|
+
returnFocus: config.returnFocusOnDeactivate && !isFocusable(target, config.tabbableOptions)
|
|
557
1012
|
});
|
|
558
1013
|
return;
|
|
559
1014
|
} // This is needed for mobile devices.
|
|
@@ -561,7 +1016,7 @@
|
|
|
561
1016
|
// then on mobile they will be blocked anyways if `touchstart` is blocked.)
|
|
562
1017
|
|
|
563
1018
|
|
|
564
|
-
if (
|
|
1019
|
+
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
565
1020
|
// allow the click outside the trap to take place
|
|
566
1021
|
return;
|
|
567
1022
|
} // otherwise, prevent the click
|
|
@@ -572,11 +1027,12 @@
|
|
|
572
1027
|
|
|
573
1028
|
|
|
574
1029
|
var checkFocusIn = function checkFocusIn(e) {
|
|
575
|
-
var
|
|
1030
|
+
var target = getActualTarget(e);
|
|
1031
|
+
var targetContained = findContainerIndex(target) >= 0; // In Firefox when you Tab out of an iframe the Document is briefly focused.
|
|
576
1032
|
|
|
577
|
-
if (targetContained ||
|
|
1033
|
+
if (targetContained || target instanceof Document) {
|
|
578
1034
|
if (targetContained) {
|
|
579
|
-
state.mostRecentlyFocusedNode =
|
|
1035
|
+
state.mostRecentlyFocusedNode = target;
|
|
580
1036
|
}
|
|
581
1037
|
} else {
|
|
582
1038
|
// escaped! pull it back in to where it just left
|
|
@@ -590,28 +1046,75 @@
|
|
|
590
1046
|
|
|
591
1047
|
|
|
592
1048
|
var checkTab = function checkTab(e) {
|
|
1049
|
+
var target = getActualTarget(e);
|
|
593
1050
|
updateTabbableNodes();
|
|
594
1051
|
var destinationNode = null;
|
|
595
1052
|
|
|
596
1053
|
if (state.tabbableGroups.length > 0) {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
1054
|
+
// make sure the target is actually contained in a group
|
|
1055
|
+
// NOTE: the target may also be the container itself if it's focusable
|
|
1056
|
+
// with tabIndex='-1' and was given initial focus
|
|
1057
|
+
var containerIndex = findContainerIndex(target);
|
|
1058
|
+
var containerGroup = containerIndex >= 0 ? state.containerGroups[containerIndex] : undefined;
|
|
1059
|
+
|
|
1060
|
+
if (containerIndex < 0) {
|
|
1061
|
+
// target not found in any group: quite possible focus has escaped the trap,
|
|
1062
|
+
// so bring it back in to...
|
|
1063
|
+
if (e.shiftKey) {
|
|
1064
|
+
// ...the last node in the last group
|
|
1065
|
+
destinationNode = state.tabbableGroups[state.tabbableGroups.length - 1].lastTabbableNode;
|
|
1066
|
+
} else {
|
|
1067
|
+
// ...the first node in the first group
|
|
1068
|
+
destinationNode = state.tabbableGroups[0].firstTabbableNode;
|
|
1069
|
+
}
|
|
1070
|
+
} else if (e.shiftKey) {
|
|
1071
|
+
// REVERSE
|
|
1072
|
+
// is the target the first tabbable node in a group?
|
|
1073
|
+
var startOfGroupIndex = findIndex(state.tabbableGroups, function (_ref2) {
|
|
1074
|
+
var firstTabbableNode = _ref2.firstTabbableNode;
|
|
1075
|
+
return target === firstTabbableNode;
|
|
601
1076
|
});
|
|
602
1077
|
|
|
1078
|
+
if (startOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target, false))) {
|
|
1079
|
+
// an exception case where the target is either the container itself, or
|
|
1080
|
+
// a non-tabbable node that was given focus (i.e. tabindex is negative
|
|
1081
|
+
// and user clicked on it or node was programmatically given focus)
|
|
1082
|
+
// and is not followed by any other tabbable node, in which
|
|
1083
|
+
// case, we should handle shift+tab as if focus were on the container's
|
|
1084
|
+
// first tabbable node, and go to the last tabbable node of the LAST group
|
|
1085
|
+
startOfGroupIndex = containerIndex;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
603
1088
|
if (startOfGroupIndex >= 0) {
|
|
1089
|
+
// YES: then shift+tab should go to the last tabbable node in the
|
|
1090
|
+
// previous group (and wrap around to the last tabbable node of
|
|
1091
|
+
// the LAST group if it's the first tabbable node of the FIRST group)
|
|
604
1092
|
var destinationGroupIndex = startOfGroupIndex === 0 ? state.tabbableGroups.length - 1 : startOfGroupIndex - 1;
|
|
605
1093
|
var destinationGroup = state.tabbableGroups[destinationGroupIndex];
|
|
606
1094
|
destinationNode = destinationGroup.lastTabbableNode;
|
|
607
1095
|
}
|
|
608
1096
|
} else {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
1097
|
+
// FORWARD
|
|
1098
|
+
// is the target the last tabbable node in a group?
|
|
1099
|
+
var lastOfGroupIndex = findIndex(state.tabbableGroups, function (_ref3) {
|
|
1100
|
+
var lastTabbableNode = _ref3.lastTabbableNode;
|
|
1101
|
+
return target === lastTabbableNode;
|
|
612
1102
|
});
|
|
613
1103
|
|
|
1104
|
+
if (lastOfGroupIndex < 0 && (containerGroup.container === target || isFocusable(target, config.tabbableOptions) && !isTabbable(target, config.tabbableOptions) && !containerGroup.nextTabbableNode(target))) {
|
|
1105
|
+
// an exception case where the target is the container itself, or
|
|
1106
|
+
// a non-tabbable node that was given focus (i.e. tabindex is negative
|
|
1107
|
+
// and user clicked on it or node was programmatically given focus)
|
|
1108
|
+
// and is not followed by any other tabbable node, in which
|
|
1109
|
+
// case, we should handle tab as if focus were on the container's
|
|
1110
|
+
// last tabbable node, and go to the first tabbable node of the FIRST group
|
|
1111
|
+
lastOfGroupIndex = containerIndex;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
614
1114
|
if (lastOfGroupIndex >= 0) {
|
|
1115
|
+
// YES: then tab should go to the first tabbable node in the next
|
|
1116
|
+
// group (and wrap around to the first tabbable node of the FIRST
|
|
1117
|
+
// group if it's the last tabbable node of the LAST group)
|
|
615
1118
|
var _destinationGroupIndex = lastOfGroupIndex === state.tabbableGroups.length - 1 ? 0 : lastOfGroupIndex + 1;
|
|
616
1119
|
|
|
617
1120
|
var _destinationGroup = state.tabbableGroups[_destinationGroupIndex];
|
|
@@ -619,17 +1122,19 @@
|
|
|
619
1122
|
}
|
|
620
1123
|
}
|
|
621
1124
|
} else {
|
|
1125
|
+
// NOTE: the fallbackFocus option does not support returning false to opt-out
|
|
622
1126
|
destinationNode = getNodeForOption('fallbackFocus');
|
|
623
1127
|
}
|
|
624
1128
|
|
|
625
1129
|
if (destinationNode) {
|
|
626
1130
|
e.preventDefault();
|
|
627
1131
|
tryFocus(destinationNode);
|
|
628
|
-
}
|
|
1132
|
+
} // else, let the browser take care of [shift+]tab and move the focus
|
|
1133
|
+
|
|
629
1134
|
};
|
|
630
1135
|
|
|
631
1136
|
var checkKey = function checkKey(e) {
|
|
632
|
-
if (config.escapeDeactivates !== false
|
|
1137
|
+
if (isEscapeEvent(e) && valueOrHandler(config.escapeDeactivates, e) !== false) {
|
|
633
1138
|
e.preventDefault();
|
|
634
1139
|
trap.deactivate();
|
|
635
1140
|
return;
|
|
@@ -642,15 +1147,17 @@
|
|
|
642
1147
|
};
|
|
643
1148
|
|
|
644
1149
|
var checkClick = function checkClick(e) {
|
|
645
|
-
|
|
1150
|
+
var target = getActualTarget(e);
|
|
1151
|
+
|
|
1152
|
+
if (findContainerIndex(target) >= 0) {
|
|
646
1153
|
return;
|
|
647
1154
|
}
|
|
648
1155
|
|
|
649
|
-
if (
|
|
1156
|
+
if (valueOrHandler(config.clickOutsideDeactivates, e)) {
|
|
650
1157
|
return;
|
|
651
1158
|
}
|
|
652
1159
|
|
|
653
|
-
if (
|
|
1160
|
+
if (valueOrHandler(config.allowOutsideClick, e)) {
|
|
654
1161
|
return;
|
|
655
1162
|
}
|
|
656
1163
|
|
|
@@ -670,7 +1177,7 @@
|
|
|
670
1177
|
activeFocusTraps.activateTrap(trap); // Delay ensures that the focused element doesn't capture the event
|
|
671
1178
|
// that caused the focus trap activation.
|
|
672
1179
|
|
|
673
|
-
|
|
1180
|
+
state.delayInitialFocusTimer = config.delayInitialFocus ? delay(function () {
|
|
674
1181
|
tryFocus(getInitialFocusNode());
|
|
675
1182
|
}) : tryFocus(getInitialFocusNode());
|
|
676
1183
|
doc.addEventListener('focusin', checkFocusIn, true);
|
|
@@ -710,22 +1217,53 @@
|
|
|
710
1217
|
|
|
711
1218
|
|
|
712
1219
|
trap = {
|
|
1220
|
+
get active() {
|
|
1221
|
+
return state.active;
|
|
1222
|
+
},
|
|
1223
|
+
|
|
1224
|
+
get paused() {
|
|
1225
|
+
return state.paused;
|
|
1226
|
+
},
|
|
1227
|
+
|
|
713
1228
|
activate: function activate(activateOptions) {
|
|
714
1229
|
if (state.active) {
|
|
715
1230
|
return this;
|
|
716
1231
|
}
|
|
717
1232
|
|
|
718
|
-
|
|
1233
|
+
var onActivate = getOption(activateOptions, 'onActivate');
|
|
1234
|
+
var onPostActivate = getOption(activateOptions, 'onPostActivate');
|
|
1235
|
+
var checkCanFocusTrap = getOption(activateOptions, 'checkCanFocusTrap');
|
|
1236
|
+
|
|
1237
|
+
if (!checkCanFocusTrap) {
|
|
1238
|
+
updateTabbableNodes();
|
|
1239
|
+
}
|
|
1240
|
+
|
|
719
1241
|
state.active = true;
|
|
720
1242
|
state.paused = false;
|
|
721
1243
|
state.nodeFocusedBeforeActivation = doc.activeElement;
|
|
722
|
-
var onActivate = activateOptions && activateOptions.onActivate ? activateOptions.onActivate : config.onActivate;
|
|
723
1244
|
|
|
724
1245
|
if (onActivate) {
|
|
725
1246
|
onActivate();
|
|
726
1247
|
}
|
|
727
1248
|
|
|
728
|
-
|
|
1249
|
+
var finishActivation = function finishActivation() {
|
|
1250
|
+
if (checkCanFocusTrap) {
|
|
1251
|
+
updateTabbableNodes();
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
addListeners();
|
|
1255
|
+
|
|
1256
|
+
if (onPostActivate) {
|
|
1257
|
+
onPostActivate();
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1261
|
+
if (checkCanFocusTrap) {
|
|
1262
|
+
checkCanFocusTrap(state.containers.concat()).then(finishActivation, finishActivation);
|
|
1263
|
+
return this;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
finishActivation();
|
|
729
1267
|
return this;
|
|
730
1268
|
},
|
|
731
1269
|
deactivate: function deactivate(deactivateOptions) {
|
|
@@ -733,25 +1271,46 @@
|
|
|
733
1271
|
return this;
|
|
734
1272
|
}
|
|
735
1273
|
|
|
736
|
-
|
|
1274
|
+
var options = _objectSpread2({
|
|
1275
|
+
onDeactivate: config.onDeactivate,
|
|
1276
|
+
onPostDeactivate: config.onPostDeactivate,
|
|
1277
|
+
checkCanReturnFocus: config.checkCanReturnFocus
|
|
1278
|
+
}, deactivateOptions);
|
|
1279
|
+
|
|
1280
|
+
clearTimeout(state.delayInitialFocusTimer); // noop if undefined
|
|
1281
|
+
|
|
1282
|
+
state.delayInitialFocusTimer = undefined;
|
|
737
1283
|
removeListeners();
|
|
738
1284
|
state.active = false;
|
|
739
1285
|
state.paused = false;
|
|
740
1286
|
activeFocusTraps.deactivateTrap(trap);
|
|
741
|
-
var onDeactivate =
|
|
1287
|
+
var onDeactivate = getOption(options, 'onDeactivate');
|
|
1288
|
+
var onPostDeactivate = getOption(options, 'onPostDeactivate');
|
|
1289
|
+
var checkCanReturnFocus = getOption(options, 'checkCanReturnFocus');
|
|
1290
|
+
var returnFocus = getOption(options, 'returnFocus', 'returnFocusOnDeactivate');
|
|
742
1291
|
|
|
743
1292
|
if (onDeactivate) {
|
|
744
1293
|
onDeactivate();
|
|
745
1294
|
}
|
|
746
1295
|
|
|
747
|
-
var
|
|
748
|
-
|
|
749
|
-
if (returnFocus) {
|
|
1296
|
+
var finishDeactivation = function finishDeactivation() {
|
|
750
1297
|
delay(function () {
|
|
751
|
-
|
|
1298
|
+
if (returnFocus) {
|
|
1299
|
+
tryFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation));
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if (onPostDeactivate) {
|
|
1303
|
+
onPostDeactivate();
|
|
1304
|
+
}
|
|
752
1305
|
});
|
|
1306
|
+
};
|
|
1307
|
+
|
|
1308
|
+
if (returnFocus && checkCanReturnFocus) {
|
|
1309
|
+
checkCanReturnFocus(getReturnFocusNode(state.nodeFocusedBeforeActivation)).then(finishDeactivation, finishDeactivation);
|
|
1310
|
+
return this;
|
|
753
1311
|
}
|
|
754
1312
|
|
|
1313
|
+
finishDeactivation();
|
|
755
1314
|
return this;
|
|
756
1315
|
},
|
|
757
1316
|
pause: function pause() {
|
|
@@ -3852,7 +4411,7 @@
|
|
|
3852
4411
|
return null;
|
|
3853
4412
|
}
|
|
3854
4413
|
return (React__namespace.createElement(Backdrop, null,
|
|
3855
|
-
React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true }, className: css(styles$1h.bullseye) },
|
|
4414
|
+
React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true, tabbableOptions: { displayCheck: 'none' } }, className: css(styles$1h.bullseye) },
|
|
3856
4415
|
React__namespace.createElement(AboutModalBox, { className: className, "aria-labelledby": aboutModalBoxHeaderId, "aria-describedby": aboutModalBoxContentId },
|
|
3857
4416
|
React__namespace.createElement(AboutModalBoxBrand, { src: brandImageSrc, alt: brandImageAlt }),
|
|
3858
4417
|
React__namespace.createElement(AboutModalBoxCloseButton, { "aria-label": closeButtonAriaLabel, onClose: onClose }),
|
|
@@ -8522,6 +9081,7 @@
|
|
|
8522
9081
|
const content = (React__namespace.createElement(FocusTrap, Object.assign({ active: focusTrapActive, focusTrapOptions: {
|
|
8523
9082
|
returnFocusOnDeactivate: true,
|
|
8524
9083
|
clickOutsideDeactivates: true,
|
|
9084
|
+
tabbableOptions: { displayCheck: 'none' },
|
|
8525
9085
|
fallbackFocus: () => {
|
|
8526
9086
|
// If the popover's trigger is focused but scrolled out of view,
|
|
8527
9087
|
// FocusTrap will throw an error when the Enter button is used on the trigger.
|
|
@@ -9068,7 +9628,7 @@
|
|
|
9068
9628
|
const screenReaderLabelId = `pf-context-selector-label-id-${newId}`;
|
|
9069
9629
|
const searchButtonId = `pf-context-selector-search-button-id-${newId}`;
|
|
9070
9630
|
const _a = this.props, { children, className, isOpen, isFullHeight, onToggle, onSelect, screenReaderLabel, toggleText, searchButtonAriaLabel, searchInputValue, onSearchInputChange, searchInputPlaceholder, onSearchButtonClick, menuAppendTo, ouiaId, ouiaSafe, isPlain, isText, footer, disableFocusTrap, isFlipEnabled } = _a, props = __rest$1(_a, ["children", "className", "isOpen", "isFullHeight", "onToggle", "onSelect", "screenReaderLabel", "toggleText", "searchButtonAriaLabel", "searchInputValue", "onSearchInputChange", "searchInputPlaceholder", "onSearchButtonClick", "menuAppendTo", "ouiaId", "ouiaSafe", "isPlain", "isText", "footer", "disableFocusTrap", "isFlipEnabled"]);
|
|
9071
|
-
const menuContainer = (React__namespace.createElement("div", Object.assign({ className: css(styles$Q.contextSelectorMenu) }, (isFlipEnabled && { style: { position: 'revert' } })), isOpen && (React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true } },
|
|
9631
|
+
const menuContainer = (React__namespace.createElement("div", Object.assign({ className: css(styles$Q.contextSelectorMenu) }, (isFlipEnabled && { style: { position: 'revert' } })), isOpen && (React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true, tabbableOptions: { displayCheck: 'none' } } },
|
|
9072
9632
|
React__namespace.createElement("div", { className: css(styles$Q.contextSelectorMenuSearch) },
|
|
9073
9633
|
React__namespace.createElement(InputGroup, null,
|
|
9074
9634
|
React__namespace.createElement(TextInput, { value: searchInputValue, type: "search", placeholder: searchInputPlaceholder, onChange: onSearchInputChange, onKeyPress: this.onEnterPressed, "aria-labelledby": searchButtonId }),
|
|
@@ -15376,7 +15936,7 @@
|
|
|
15376
15936
|
const isVariantIcon = (icon) => ['success', 'danger', 'warning', 'info', 'default'].includes(icon);
|
|
15377
15937
|
const ModalBoxTitle = (_a) => {
|
|
15378
15938
|
var { className = '', id, title, titleIconVariant, titleLabel = '' } = _a, props = __rest$1(_a, ["className", "id", "title", "titleIconVariant", "titleLabel"]);
|
|
15379
|
-
const [
|
|
15939
|
+
const [hasTooltip, setHasTooltip] = React__namespace.useState(false);
|
|
15380
15940
|
const h1 = React__namespace.useRef();
|
|
15381
15941
|
const label = titleLabel || (isVariantIcon(titleIconVariant) ? `${capitalize(titleIconVariant)} alert:` : titleLabel);
|
|
15382
15942
|
const variantIcons = {
|
|
@@ -15388,13 +15948,13 @@
|
|
|
15388
15948
|
};
|
|
15389
15949
|
const CustomIcon = !isVariantIcon(titleIconVariant) && titleIconVariant;
|
|
15390
15950
|
useIsomorphicLayoutEffect(() => {
|
|
15391
|
-
|
|
15951
|
+
setHasTooltip(h1.current && h1.current.offsetWidth < h1.current.scrollWidth);
|
|
15392
15952
|
}, []);
|
|
15393
15953
|
const content = (React__namespace.createElement("h1", Object.assign({ id: id, ref: h1, className: css(modalStyles.modalBoxTitle, titleIconVariant && modalStyles.modifiers.icon, className) }, props),
|
|
15394
15954
|
titleIconVariant && (React__namespace.createElement("span", { className: css(modalStyles.modalBoxTitleIcon) }, isVariantIcon(titleIconVariant) ? variantIcons[titleIconVariant] : React__namespace.createElement(CustomIcon, null))),
|
|
15395
15955
|
label && React__namespace.createElement("span", { className: css(a11yStyles.screenReader) }, label),
|
|
15396
15956
|
React__namespace.createElement("span", { className: css(modalStyles.modalBoxTitleText) }, title)));
|
|
15397
|
-
return
|
|
15957
|
+
return hasTooltip ? React__namespace.createElement(Tooltip, { content: title }, content) : content;
|
|
15398
15958
|
};
|
|
15399
15959
|
ModalBoxTitle.displayName = 'ModalBoxTitle';
|
|
15400
15960
|
|
|
@@ -15433,7 +15993,7 @@
|
|
|
15433
15993
|
modalBody,
|
|
15434
15994
|
modalBoxFooter));
|
|
15435
15995
|
return (React__namespace.createElement(Backdrop, null,
|
|
15436
|
-
React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true }, className: css(styles$1h.bullseye) }, modalBox)));
|
|
15996
|
+
React__namespace.createElement(FocusTrap, { active: !disableFocusTrap, focusTrapOptions: { clickOutsideDeactivates: true, tabbableOptions: { displayCheck: 'none' } }, className: css(styles$1h.bullseye) }, modalBox)));
|
|
15437
15997
|
};
|
|
15438
15998
|
ModalContent.displayName = 'ModalContent';
|
|
15439
15999
|
|
|
@@ -18069,9 +18629,7 @@
|
|
|
18069
18629
|
if (!areCustomStepsContinuous && customSteps) {
|
|
18070
18630
|
let percentage = newPercentage;
|
|
18071
18631
|
if (customSteps[customSteps.length - 1].value !== 100) {
|
|
18072
|
-
|
|
18073
|
-
const percentagePerStep = 100 / numSteps;
|
|
18074
|
-
percentage = newPercentage / percentagePerStep;
|
|
18632
|
+
percentage = (newPercentage * (max - min)) / 100 + min;
|
|
18075
18633
|
}
|
|
18076
18634
|
const stepIndex = customSteps.findIndex(stepObj => stepObj.value >= percentage);
|
|
18077
18635
|
if (customSteps[stepIndex].value === percentage) {
|