@redsift/design-system 11.5.0-muiv5 → 11.6.0-alpha.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/_internal/Alert2.js +197 -0
- package/_internal/Alert2.js.map +1 -0
- package/_internal/AppBar.js +248 -0
- package/_internal/AppBar.js.map +1 -0
- package/_internal/AppContainer.js +142 -0
- package/_internal/AppContainer.js.map +1 -0
- package/_internal/AppContent.js +92 -0
- package/_internal/AppContent.js.map +1 -0
- package/_internal/Badge2.js +142 -0
- package/_internal/Badge2.js.map +1 -0
- package/_internal/BreadcrumbItem.js +91 -0
- package/_internal/BreadcrumbItem.js.map +1 -0
- package/_internal/Breadcrumbs2.js +94 -0
- package/_internal/Breadcrumbs2.js.map +1 -0
- package/_internal/Button2.js +91 -0
- package/_internal/Button2.js.map +1 -0
- package/_internal/ButtonGroup.js +181 -0
- package/_internal/ButtonGroup.js.map +1 -0
- package/_internal/ButtonLink.js +84 -0
- package/_internal/ButtonLink.js.map +1 -0
- package/_internal/Card2.js +157 -0
- package/_internal/Card2.js.map +1 -0
- package/_internal/CardActions.js +44 -0
- package/_internal/CardActions.js.map +1 -0
- package/_internal/CardBody.js +42 -0
- package/_internal/CardBody.js.map +1 -0
- package/_internal/CardHeader.js +83 -0
- package/_internal/CardHeader.js.map +1 -0
- package/_internal/Checkbox2.js +244 -0
- package/_internal/Checkbox2.js.map +1 -0
- package/_internal/CheckboxGroup.js +188 -0
- package/_internal/CheckboxGroup.js.map +1 -0
- package/_internal/ConditionalWrapper.js +13 -0
- package/_internal/ConditionalWrapper.js.map +1 -0
- package/_internal/DetailedCard.js +6916 -0
- package/_internal/DetailedCard.js.map +1 -0
- package/_internal/DetailedCardCollapsibleSectionItems.js +64 -0
- package/_internal/DetailedCardCollapsibleSectionItems.js.map +1 -0
- package/_internal/DetailedCardHeader.js +67 -0
- package/_internal/DetailedCardHeader.js.map +1 -0
- package/_internal/DetailedCardSection.js +172 -0
- package/_internal/DetailedCardSection.js.map +1 -0
- package/_internal/DetailedCardSectionItem.js +94 -0
- package/_internal/DetailedCardSectionItem.js.map +1 -0
- package/_internal/Flexbox2.js +93 -0
- package/_internal/Flexbox2.js.map +1 -0
- package/_internal/Grid2.js +95 -0
- package/_internal/Grid2.js.map +1 -0
- package/_internal/GridItem.js +40 -0
- package/_internal/GridItem.js.map +1 -0
- package/_internal/Heading2.js +113 -0
- package/_internal/Heading2.js.map +1 -0
- package/_internal/Icon2.js +211 -0
- package/_internal/Icon2.js.map +1 -0
- package/_internal/IconButton.js +80 -0
- package/_internal/IconButton.js.map +1 -0
- package/_internal/IconButtonLink.js +75 -0
- package/_internal/IconButtonLink.js.map +1 -0
- package/_internal/Item2.js +399 -0
- package/_internal/Item2.js.map +1 -0
- package/_internal/Link2.js +67 -0
- package/_internal/Link2.js.map +1 -0
- package/_internal/LinkButton.js +66 -0
- package/_internal/LinkButton.js.map +1 -0
- package/_internal/Listbox2.js +274 -0
- package/_internal/Listbox2.js.map +1 -0
- package/_internal/Number2.js +111 -0
- package/_internal/Number2.js.map +1 -0
- package/_internal/NumberField.js +3974 -0
- package/_internal/NumberField.js.map +1 -0
- package/_internal/Pill2.js +405 -0
- package/_internal/Pill2.js.map +1 -0
- package/_internal/ProgressBar.js +69 -0
- package/_internal/ProgressBar.js.map +1 -0
- package/_internal/Radio2.js +237 -0
- package/_internal/Radio2.js.map +1 -0
- package/_internal/RadioGroup.js +176 -0
- package/_internal/RadioGroup.js.map +1 -0
- package/_internal/Shield2.js +225 -0
- package/_internal/Shield2.js.map +1 -0
- package/_internal/SideNavigationMenu.js +591 -0
- package/_internal/SideNavigationMenu.js.map +1 -0
- package/_internal/SideNavigationMenuItem.js +304 -0
- package/_internal/SideNavigationMenuItem.js.map +1 -0
- package/_internal/Skeleton2.js +42 -0
- package/_internal/Skeleton2.js.map +1 -0
- package/_internal/SkeletonCircle.js +58 -0
- package/_internal/SkeletonCircle.js.map +1 -0
- package/_internal/SkeletonText.js +77 -0
- package/_internal/SkeletonText.js.map +1 -0
- package/_internal/Spinner2.js +333 -0
- package/_internal/Spinner2.js.map +1 -0
- package/_internal/Switch2.js +320 -0
- package/_internal/Switch2.js.map +1 -0
- package/_internal/SwitchGroup.js +188 -0
- package/_internal/SwitchGroup.js.map +1 -0
- package/_internal/Text2.js +51 -0
- package/_internal/Text2.js.map +1 -0
- package/_internal/TextArea.js +444 -0
- package/_internal/TextArea.js.map +1 -0
- package/_internal/TextField.js +473 -0
- package/_internal/TextField.js.map +1 -0
- package/_internal/_rollupPluginBabelHelpers.js +133 -0
- package/_internal/_rollupPluginBabelHelpers.js.map +1 -0
- package/_internal/alert.js +2 -0
- package/_internal/alert.js.map +1 -0
- package/_internal/app-bar.js +2 -0
- package/_internal/app-bar.js.map +1 -0
- package/_internal/app-container.js +3 -0
- package/_internal/app-container.js.map +1 -0
- package/_internal/app-content.js +2 -0
- package/_internal/app-content.js.map +1 -0
- package/_internal/app-side-panel.js +3 -0
- package/_internal/app-side-panel.js.map +1 -0
- package/_internal/badge.js +2 -0
- package/_internal/badge.js.map +1 -0
- package/_internal/breadcrumb-item.js +2 -0
- package/_internal/breadcrumb-item.js.map +1 -0
- package/_internal/breadcrumbs.js +2 -0
- package/_internal/breadcrumbs.js.map +1 -0
- package/_internal/button-group.js +2 -0
- package/_internal/button-group.js.map +1 -0
- package/_internal/button-link.js +2 -0
- package/_internal/button-link.js.map +1 -0
- package/_internal/button.js +3 -0
- package/_internal/button.js.map +1 -0
- package/_internal/card-actions.js +2 -0
- package/_internal/card-actions.js.map +1 -0
- package/_internal/card-body.js +2 -0
- package/_internal/card-body.js.map +1 -0
- package/_internal/card-header.js +2 -0
- package/_internal/card-header.js.map +1 -0
- package/_internal/card.js +2 -0
- package/_internal/card.js.map +1 -0
- package/_internal/checkbox-group.js +2 -0
- package/_internal/checkbox-group.js.map +1 -0
- package/_internal/checkbox.js +2 -0
- package/_internal/checkbox.js.map +1 -0
- package/_internal/colors.js +98 -0
- package/_internal/colors.js.map +1 -0
- package/_internal/conditional-wrapper.js +2 -0
- package/_internal/conditional-wrapper.js.map +1 -0
- package/_internal/context.js +6 -0
- package/_internal/context.js.map +1 -0
- package/_internal/context2.js +300 -0
- package/_internal/context2.js.map +1 -0
- package/_internal/context3.js +6 -0
- package/_internal/context3.js.map +1 -0
- package/_internal/context4.js +6 -0
- package/_internal/context4.js.map +1 -0
- package/_internal/context5.js +6 -0
- package/_internal/context5.js.map +1 -0
- package/_internal/detailed-card-collapsible-section-items.js +2 -0
- package/_internal/detailed-card-collapsible-section-items.js.map +1 -0
- package/_internal/detailed-card-header.js +2 -0
- package/_internal/detailed-card-header.js.map +1 -0
- package/_internal/detailed-card-section-item.js +2 -0
- package/_internal/detailed-card-section-item.js.map +1 -0
- package/_internal/detailed-card-section.js +2 -0
- package/_internal/detailed-card-section.js.map +1 -0
- package/_internal/detailed-card.js +2 -0
- package/_internal/detailed-card.js.map +1 -0
- package/_internal/filterComponents.js +24 -0
- package/_internal/filterComponents.js.map +1 -0
- package/_internal/flexbox.js +2 -0
- package/_internal/flexbox.js.map +1 -0
- package/_internal/focus-within-group.js +3 -0
- package/_internal/focus-within-group.js.map +1 -0
- package/_internal/fonts.js +10 -0
- package/_internal/fonts.js.map +1 -0
- package/_internal/gradient-border.js +38 -0
- package/_internal/gradient-border.js.map +1 -0
- package/_internal/grid-item.js +2 -0
- package/_internal/grid-item.js.map +1 -0
- package/_internal/grid.js +2 -0
- package/_internal/grid.js.map +1 -0
- package/_internal/heading.js +3 -0
- package/_internal/heading.js.map +1 -0
- package/_internal/icon-button-link.js +2 -0
- package/_internal/icon-button-link.js.map +1 -0
- package/_internal/icon-button.js +3 -0
- package/_internal/icon-button.js.map +1 -0
- package/_internal/icon.js +2 -0
- package/_internal/icon.js.map +1 -0
- package/_internal/isComponent.js +15 -0
- package/_internal/isComponent.js.map +1 -0
- package/_internal/item.js +2 -0
- package/_internal/item.js.map +1 -0
- package/_internal/link-button.js +2 -0
- package/_internal/link-button.js.map +1 -0
- package/_internal/link.js +3 -0
- package/_internal/link.js.map +1 -0
- package/_internal/listbox.js +3 -0
- package/_internal/listbox.js.map +1 -0
- package/_internal/number-field.js +2 -0
- package/_internal/number-field.js.map +1 -0
- package/_internal/number.js +2 -0
- package/_internal/number.js.map +1 -0
- package/_internal/partitionComponents.js +26 -0
- package/_internal/partitionComponents.js.map +1 -0
- package/_internal/pill.js +2 -0
- package/_internal/pill.js.map +1 -0
- package/_internal/progress-bar.js +2 -0
- package/_internal/progress-bar.js.map +1 -0
- package/_internal/radio-group.js +2 -0
- package/_internal/radio-group.js.map +1 -0
- package/_internal/radio.js +2 -0
- package/_internal/radio.js.map +1 -0
- package/_internal/redsift-design-tokens.js +1391 -0
- package/_internal/redsift-design-tokens.js.map +1 -0
- package/_internal/shared.js +2 -0
- package/_internal/shared.js.map +1 -0
- package/_internal/shield.js +2 -0
- package/_internal/shield.js.map +1 -0
- package/_internal/side-navigation-menu-bar.js +3 -0
- package/_internal/side-navigation-menu-bar.js.map +1 -0
- package/_internal/side-navigation-menu-item.js +2 -0
- package/_internal/side-navigation-menu-item.js.map +1 -0
- package/_internal/side-navigation-menu.js +2 -0
- package/_internal/side-navigation-menu.js.map +1 -0
- package/_internal/skeleton-circle.js +2 -0
- package/_internal/skeleton-circle.js.map +1 -0
- package/_internal/skeleton-text.js +3 -0
- package/_internal/skeleton-text.js.map +1 -0
- package/_internal/skeleton.js +2 -0
- package/_internal/skeleton.js.map +1 -0
- package/_internal/spinner.js +2 -0
- package/_internal/spinner.js.map +1 -0
- package/_internal/styles.js +235 -0
- package/_internal/styles.js.map +1 -0
- package/_internal/styles2.js +47 -0
- package/_internal/styles2.js.map +1 -0
- package/_internal/styles3.js +145 -0
- package/_internal/styles3.js.map +1 -0
- package/_internal/styles4.js +250 -0
- package/_internal/styles4.js.map +1 -0
- package/_internal/styles5.js +143 -0
- package/_internal/styles5.js.map +1 -0
- package/_internal/styles6.js +84 -0
- package/_internal/styles6.js.map +1 -0
- package/_internal/switch-group.js +2 -0
- package/_internal/switch-group.js.map +1 -0
- package/_internal/switch.js +2 -0
- package/_internal/switch.js.map +1 -0
- package/_internal/text-area.js +2 -0
- package/_internal/text-area.js.map +1 -0
- package/_internal/text-field.js +2 -0
- package/_internal/text-field.js.map +1 -0
- package/_internal/text.js +3 -0
- package/_internal/text.js.map +1 -0
- package/_internal/theme.js +2 -0
- package/_internal/theme.js.map +1 -0
- package/_internal/types.js +15 -0
- package/_internal/types.js.map +1 -0
- package/_internal/types2.js +26 -0
- package/_internal/types2.js.map +1 -0
- package/_internal/types3.js +20 -0
- package/_internal/types3.js.map +1 -0
- package/_internal/useAppSidePanel.js +337 -0
- package/_internal/useAppSidePanel.js.map +1 -0
- package/_internal/useFocusOnList.js +541 -0
- package/_internal/useFocusOnList.js.map +1 -0
- package/_internal/useFocusOnListItem.js +203 -0
- package/_internal/useFocusOnListItem.js.map +1 -0
- package/_internal/useFocusRing.js +669 -0
- package/_internal/useFocusRing.js.map +1 -0
- package/_internal/useId.js +42 -0
- package/_internal/useId.js.map +1 -0
- package/_internal/useIsLoaded.js +14 -0
- package/_internal/useIsLoaded.js.map +1 -0
- package/_internal/useListboxItem.js +129 -0
- package/_internal/useListboxItem.js.map +1 -0
- package/_internal/useMessageFormatter.js +143 -0
- package/_internal/useMessageFormatter.js.map +1 -0
- package/_internal/useNumberFormatter.js +239 -0
- package/_internal/useNumberFormatter.js.map +1 -0
- package/_internal/useSideNavigationMenuBar.js +373 -0
- package/_internal/useSideNavigationMenuBar.js.map +1 -0
- package/_internal/useTheme.js +15 -0
- package/_internal/useTheme.js.map +1 -0
- package/_internal/warnIfNoAccessibleLabelFound.js +20 -0
- package/_internal/warnIfNoAccessibleLabelFound.js.map +1 -0
- package/index.js +315 -24243
- package/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
import React__default, { useRef, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { a as _defineProperty } from './_rollupPluginBabelHelpers.js';
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* Copyright 2020 Adobe. All rights reserved.
|
|
6
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
8
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
11
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
12
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
13
|
+
* governing permissions and limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// During SSR, React emits a warning when calling useLayoutEffect.
|
|
17
|
+
// Since neither useLayoutEffect nor useEffect run on the server,
|
|
18
|
+
// we can suppress this by replace it with a noop on the server.
|
|
19
|
+
const useLayoutEffect = typeof document !== 'undefined' ? React__default.useLayoutEffect : () => {};
|
|
20
|
+
|
|
21
|
+
const getOwnerDocument = el => {
|
|
22
|
+
var _el$ownerDocument;
|
|
23
|
+
return (_el$ownerDocument = el === null || el === void 0 ? void 0 : el.ownerDocument) !== null && _el$ownerDocument !== void 0 ? _el$ownerDocument : document;
|
|
24
|
+
};
|
|
25
|
+
const getOwnerWindow = el => {
|
|
26
|
+
if (el && 'window' in el && el.window === el) {
|
|
27
|
+
return el;
|
|
28
|
+
}
|
|
29
|
+
const doc = getOwnerDocument(el);
|
|
30
|
+
return doc.defaultView || window;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/* eslint-disable prefer-const */
|
|
34
|
+
// @ts-nocheck
|
|
35
|
+
/*
|
|
36
|
+
* Copyright 2020 Adobe. All rights reserved.
|
|
37
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
38
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
39
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
40
|
+
*
|
|
41
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
42
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
43
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
44
|
+
* governing permissions and limitations under the License.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
function testUserAgent(re) {
|
|
48
|
+
var _window$navigator$use;
|
|
49
|
+
if (typeof window === 'undefined' || window.navigator == null) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
return ((_window$navigator$use = window.navigator['userAgentData']) === null || _window$navigator$use === void 0 ? void 0 : _window$navigator$use.brands.some(brand => re.test(brand.brand))) || re.test(window.navigator.userAgent);
|
|
53
|
+
}
|
|
54
|
+
function testPlatform(re) {
|
|
55
|
+
var _window$navigator$use2;
|
|
56
|
+
return typeof window !== 'undefined' && window.navigator != null ? re.test(((_window$navigator$use2 = window.navigator['userAgentData']) === null || _window$navigator$use2 === void 0 ? void 0 : _window$navigator$use2.platform) || window.navigator.platform) : false;
|
|
57
|
+
}
|
|
58
|
+
function cached(fn) {
|
|
59
|
+
if (process.env.NODE_ENV === 'test') {
|
|
60
|
+
return fn;
|
|
61
|
+
}
|
|
62
|
+
let res = null;
|
|
63
|
+
return () => {
|
|
64
|
+
if (res == null) {
|
|
65
|
+
res = fn();
|
|
66
|
+
}
|
|
67
|
+
return res;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const isMac = cached(function () {
|
|
71
|
+
return testPlatform(/^Mac/i);
|
|
72
|
+
});
|
|
73
|
+
const isIPhone = cached(function () {
|
|
74
|
+
return testPlatform(/^iPhone/i);
|
|
75
|
+
});
|
|
76
|
+
const isIPad = cached(function () {
|
|
77
|
+
return testPlatform(/^iPad/i) ||
|
|
78
|
+
// iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
|
|
79
|
+
isMac() && navigator.maxTouchPoints > 1;
|
|
80
|
+
});
|
|
81
|
+
const isIOS = cached(function () {
|
|
82
|
+
return isIPhone() || isIPad();
|
|
83
|
+
});
|
|
84
|
+
cached(function () {
|
|
85
|
+
return isMac() || isIOS();
|
|
86
|
+
});
|
|
87
|
+
const isWebKit = cached(function () {
|
|
88
|
+
return testUserAgent(/AppleWebKit/i) && !isChrome();
|
|
89
|
+
});
|
|
90
|
+
const isChrome = cached(function () {
|
|
91
|
+
return testUserAgent(/Chrome/i);
|
|
92
|
+
});
|
|
93
|
+
const isAndroid = cached(function () {
|
|
94
|
+
return testUserAgent(/Android/i);
|
|
95
|
+
});
|
|
96
|
+
const isFirefox = cached(function () {
|
|
97
|
+
return testUserAgent(/Firefox/i);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Copyright 2023 Adobe. All rights reserved.
|
|
102
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
103
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
104
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
105
|
+
*
|
|
106
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
107
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
108
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
109
|
+
* governing permissions and limitations under the License.
|
|
110
|
+
*/
|
|
111
|
+
function useEffectEvent(fn) {
|
|
112
|
+
const ref = useRef(null);
|
|
113
|
+
useLayoutEffect(() => {
|
|
114
|
+
ref.current = fn;
|
|
115
|
+
}, [fn]);
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
return useCallback(function () {
|
|
118
|
+
const f = ref.current;
|
|
119
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
120
|
+
args[_key] = arguments[_key];
|
|
121
|
+
}
|
|
122
|
+
return f === null || f === void 0 ? void 0 : f(...args);
|
|
123
|
+
}, []);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* Copyright 2022 Adobe. All rights reserved.
|
|
128
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
129
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
130
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
131
|
+
*
|
|
132
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
133
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
134
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
135
|
+
* governing permissions and limitations under the License.
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
// Original licensing for the following method can be found in the
|
|
139
|
+
// NOTICE file in the root directory of this source tree.
|
|
140
|
+
// See https://github.com/facebook/react/blob/3c713d513195a53788b3f8bb4b70279d68b15bcc/packages/react-interactions/events/src/dom/shared/index.js#L74-L87
|
|
141
|
+
|
|
142
|
+
// Keyboards, Assistive Technologies, and element.click() all produce a "virtual"
|
|
143
|
+
// click event. This is a method of inferring such clicks. Every browser except
|
|
144
|
+
// IE 11 only sets a zero value of "detail" for click events that are "virtual".
|
|
145
|
+
// However, IE 11 uses a zero value for all click events. For IE 11 we rely on
|
|
146
|
+
// the quirk that it produces click events that are of type PointerEvent, and
|
|
147
|
+
// where only the "virtual" click lacks a pointerType field.
|
|
148
|
+
|
|
149
|
+
function isVirtualClick(event) {
|
|
150
|
+
// JAWS/NVDA with Firefox.
|
|
151
|
+
if (event.mozInputSource === 0 && event.isTrusted) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Android TalkBack's detail value varies depending on the event listener providing the event so we have specific logic here instead
|
|
156
|
+
// If pointerType is defined, event is from a click listener. For events from mousedown listener, detail === 0 is a sufficient check
|
|
157
|
+
// to detect TalkBack virtual clicks.
|
|
158
|
+
if (isAndroid() && event.pointerType) {
|
|
159
|
+
return event.type === 'click' && event.buttons === 1;
|
|
160
|
+
}
|
|
161
|
+
return event.detail === 0 && !event.pointerType;
|
|
162
|
+
}
|
|
163
|
+
function isVirtualPointerEvent(event) {
|
|
164
|
+
// If the pointer size is zero, then we assume it's from a screen reader.
|
|
165
|
+
// Android TalkBack double tap will sometimes return a event with width and height of 1
|
|
166
|
+
// and pointerType === 'mouse' so we need to check for a specific combination of event attributes.
|
|
167
|
+
// Cannot use "event.pressure === 0" as the sole check due to Safari pointer events always returning pressure === 0
|
|
168
|
+
// instead of .5, see https://bugs.webkit.org/show_bug.cgi?id=206216. event.pointerType === 'mouse' is to distingush
|
|
169
|
+
// Talkback double tap from Windows Firefox touch screen press
|
|
170
|
+
return !isAndroid() && event.width === 0 && event.height === 0 || event.width === 1 && event.height === 1 && event.pressure === 0 && event.detail === 0 && event.pointerType === 'mouse';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
class SyntheticFocusEvent {
|
|
174
|
+
constructor(type, nativeEvent) {
|
|
175
|
+
_defineProperty(this, "nativeEvent", void 0);
|
|
176
|
+
_defineProperty(this, "target", void 0);
|
|
177
|
+
_defineProperty(this, "currentTarget", void 0);
|
|
178
|
+
_defineProperty(this, "relatedTarget", void 0);
|
|
179
|
+
_defineProperty(this, "bubbles", void 0);
|
|
180
|
+
_defineProperty(this, "cancelable", void 0);
|
|
181
|
+
_defineProperty(this, "defaultPrevented", void 0);
|
|
182
|
+
_defineProperty(this, "eventPhase", void 0);
|
|
183
|
+
_defineProperty(this, "isTrusted", void 0);
|
|
184
|
+
_defineProperty(this, "timeStamp", void 0);
|
|
185
|
+
_defineProperty(this, "type", void 0);
|
|
186
|
+
this.nativeEvent = nativeEvent;
|
|
187
|
+
this.target = nativeEvent.target;
|
|
188
|
+
this.currentTarget = nativeEvent.currentTarget;
|
|
189
|
+
this.relatedTarget = nativeEvent.relatedTarget;
|
|
190
|
+
this.bubbles = nativeEvent.bubbles;
|
|
191
|
+
this.cancelable = nativeEvent.cancelable;
|
|
192
|
+
this.defaultPrevented = nativeEvent.defaultPrevented;
|
|
193
|
+
this.eventPhase = nativeEvent.eventPhase;
|
|
194
|
+
this.isTrusted = nativeEvent.isTrusted;
|
|
195
|
+
this.timeStamp = nativeEvent.timeStamp;
|
|
196
|
+
this.type = type;
|
|
197
|
+
}
|
|
198
|
+
isDefaultPrevented() {
|
|
199
|
+
return this.nativeEvent.defaultPrevented;
|
|
200
|
+
}
|
|
201
|
+
preventDefault() {
|
|
202
|
+
this.defaultPrevented = true;
|
|
203
|
+
this.nativeEvent.preventDefault();
|
|
204
|
+
}
|
|
205
|
+
stopPropagation() {
|
|
206
|
+
this.nativeEvent.stopPropagation();
|
|
207
|
+
this.isPropagationStopped = () => true;
|
|
208
|
+
}
|
|
209
|
+
isPropagationStopped() {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
persist() {}
|
|
213
|
+
}
|
|
214
|
+
function useSyntheticBlurEvent(onBlur) {
|
|
215
|
+
let stateRef = useRef({
|
|
216
|
+
isFocused: false,
|
|
217
|
+
observer: null
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Clean up MutationObserver on unmount. See below.
|
|
221
|
+
// eslint-disable-next-line arrow-body-style
|
|
222
|
+
useLayoutEffect(() => {
|
|
223
|
+
const state = stateRef.current;
|
|
224
|
+
return () => {
|
|
225
|
+
if (state.observer) {
|
|
226
|
+
state.observer.disconnect();
|
|
227
|
+
state.observer = null;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}, []);
|
|
231
|
+
let dispatchBlur = useEffectEvent(e => {
|
|
232
|
+
onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// This function is called during a React onFocus event.
|
|
236
|
+
return useCallback(e => {
|
|
237
|
+
// React does not fire onBlur when an element is disabled. https://github.com/facebook/react/issues/9142
|
|
238
|
+
// Most browsers fire a native focusout event in this case, except for Firefox. In that case, we use a
|
|
239
|
+
// MutationObserver to watch for the disabled attribute, and dispatch these events ourselves.
|
|
240
|
+
// For browsers that do, focusout fires before the MutationObserver, so onBlur should not fire twice.
|
|
241
|
+
if (e.target instanceof HTMLButtonElement || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement) {
|
|
242
|
+
stateRef.current.isFocused = true;
|
|
243
|
+
let target = e.target;
|
|
244
|
+
let onBlurHandler = e => {
|
|
245
|
+
stateRef.current.isFocused = false;
|
|
246
|
+
if (target.disabled) {
|
|
247
|
+
// For backward compatibility, dispatch a (fake) React synthetic event.
|
|
248
|
+
dispatchBlur(new SyntheticFocusEvent('blur', e));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// We no longer need the MutationObserver once the target is blurred.
|
|
252
|
+
if (stateRef.current.observer) {
|
|
253
|
+
stateRef.current.observer.disconnect();
|
|
254
|
+
stateRef.current.observer = null;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
target.addEventListener('focusout', onBlurHandler, {
|
|
258
|
+
once: true
|
|
259
|
+
});
|
|
260
|
+
stateRef.current.observer = new MutationObserver(() => {
|
|
261
|
+
if (stateRef.current.isFocused && target.disabled) {
|
|
262
|
+
var _stateRef$current$obs;
|
|
263
|
+
(_stateRef$current$obs = stateRef.current.observer) === null || _stateRef$current$obs === void 0 ? void 0 : _stateRef$current$obs.disconnect();
|
|
264
|
+
let relatedTargetEl = target === document.activeElement ? null : document.activeElement;
|
|
265
|
+
target.dispatchEvent(new FocusEvent('blur', {
|
|
266
|
+
relatedTarget: relatedTargetEl
|
|
267
|
+
}));
|
|
268
|
+
target.dispatchEvent(new FocusEvent('focusout', {
|
|
269
|
+
bubbles: true,
|
|
270
|
+
relatedTarget: relatedTargetEl
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
stateRef.current.observer.observe(target, {
|
|
275
|
+
attributes: true,
|
|
276
|
+
attributeFilter: ['disabled']
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}, [dispatchBlur]);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/* eslint-disable prefer-const */
|
|
283
|
+
/**
|
|
284
|
+
* Handles focus events for the immediate target.
|
|
285
|
+
* Focus events on child elements will be ignored.
|
|
286
|
+
*/
|
|
287
|
+
function useFocus(props) {
|
|
288
|
+
let {
|
|
289
|
+
isDisabled,
|
|
290
|
+
onFocus: onFocusProp,
|
|
291
|
+
onBlur: onBlurProp,
|
|
292
|
+
onFocusChange
|
|
293
|
+
} = props;
|
|
294
|
+
const onBlur = useCallback(e => {
|
|
295
|
+
if (e.target === e.currentTarget) {
|
|
296
|
+
if (onBlurProp) {
|
|
297
|
+
onBlurProp(e);
|
|
298
|
+
}
|
|
299
|
+
if (onFocusChange) {
|
|
300
|
+
onFocusChange(false);
|
|
301
|
+
}
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
}, [onBlurProp, onFocusChange]);
|
|
305
|
+
const onSyntheticFocus = useSyntheticBlurEvent(onBlur);
|
|
306
|
+
const onFocus = useCallback(e => {
|
|
307
|
+
// Double check that document.activeElement actually matches e.target in case a previously chained
|
|
308
|
+
// focus handler already moved focus somewhere else.
|
|
309
|
+
|
|
310
|
+
const ownerDocument = getOwnerDocument(e.target);
|
|
311
|
+
if (e.target === e.currentTarget && ownerDocument.activeElement === e.target) {
|
|
312
|
+
if (onFocusProp) {
|
|
313
|
+
onFocusProp(e);
|
|
314
|
+
}
|
|
315
|
+
if (onFocusChange) {
|
|
316
|
+
onFocusChange(true);
|
|
317
|
+
}
|
|
318
|
+
onSyntheticFocus(e);
|
|
319
|
+
}
|
|
320
|
+
}, [onFocusChange, onFocusProp, onSyntheticFocus]);
|
|
321
|
+
return {
|
|
322
|
+
focusProps: {
|
|
323
|
+
onFocus: !isDisabled && (onFocusProp || onFocusChange || onBlurProp) ? onFocus : undefined,
|
|
324
|
+
onBlur: !isDisabled && (onBlurProp || onFocusChange) ? onBlur : undefined
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/* eslint-disable prefer-const */
|
|
330
|
+
let currentModality = null;
|
|
331
|
+
let changeHandlers = new Set();
|
|
332
|
+
let hasSetupGlobalListeners = new Map(); // We use a map here to support setting event listeners across multiple document objects.
|
|
333
|
+
let hasEventBeforeFocus = false;
|
|
334
|
+
let hasBlurredWindowRecently = false;
|
|
335
|
+
|
|
336
|
+
// Only Tab or Esc keys will make focus visible on text input elements
|
|
337
|
+
const FOCUS_VISIBLE_INPUT_KEYS = {
|
|
338
|
+
Tab: true,
|
|
339
|
+
Escape: true
|
|
340
|
+
};
|
|
341
|
+
function triggerChangeHandlers(modality, e) {
|
|
342
|
+
for (let handler of changeHandlers) {
|
|
343
|
+
handler(modality, e);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Helper function to determine if a KeyboardEvent is unmodified and could make keyboard focus styles visible.
|
|
349
|
+
*/
|
|
350
|
+
function isValidKey(e) {
|
|
351
|
+
// Control and Shift keys trigger when navigating back to the tab with keyboard.
|
|
352
|
+
return !(e.metaKey || !isMac() && e.altKey || e.ctrlKey || e.key === 'Control' || e.key === 'Shift' || e.key === 'Meta');
|
|
353
|
+
}
|
|
354
|
+
function handleKeyboardEvent(e) {
|
|
355
|
+
hasEventBeforeFocus = true;
|
|
356
|
+
if (isValidKey(e)) {
|
|
357
|
+
currentModality = 'keyboard';
|
|
358
|
+
triggerChangeHandlers('keyboard', e);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function handlePointerEvent(e) {
|
|
362
|
+
currentModality = 'pointer';
|
|
363
|
+
if (e.type === 'mousedown' || e.type === 'pointerdown') {
|
|
364
|
+
hasEventBeforeFocus = true;
|
|
365
|
+
triggerChangeHandlers('pointer', e);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
function handleClickEvent(e) {
|
|
369
|
+
if (isVirtualClick(e)) {
|
|
370
|
+
hasEventBeforeFocus = true;
|
|
371
|
+
currentModality = 'virtual';
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function handleFocusEvent(e) {
|
|
375
|
+
// Firefox fires two extra focus events when the user first clicks into an iframe:
|
|
376
|
+
// first on the window, then on the document. We ignore these events so they don't
|
|
377
|
+
// cause keyboard focus rings to appear.
|
|
378
|
+
if (e.target === window || e.target === document) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// If a focus event occurs without a preceding keyboard or pointer event, switch to virtual modality.
|
|
383
|
+
// This occurs, for example, when navigating a form with the next/previous buttons on iOS.
|
|
384
|
+
if (!hasEventBeforeFocus && !hasBlurredWindowRecently) {
|
|
385
|
+
currentModality = 'virtual';
|
|
386
|
+
triggerChangeHandlers('virtual', e);
|
|
387
|
+
}
|
|
388
|
+
hasEventBeforeFocus = false;
|
|
389
|
+
hasBlurredWindowRecently = false;
|
|
390
|
+
}
|
|
391
|
+
function handleWindowBlur() {
|
|
392
|
+
// When the window is blurred, reset state. This is necessary when tabbing out of the window,
|
|
393
|
+
// for example, since a subsequent focus event won't be fired.
|
|
394
|
+
hasEventBeforeFocus = false;
|
|
395
|
+
hasBlurredWindowRecently = true;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Setup global event listeners to control when keyboard focus style should be visible.
|
|
400
|
+
*/
|
|
401
|
+
function setupGlobalFocusEvents(element) {
|
|
402
|
+
if (typeof window === 'undefined' || hasSetupGlobalListeners.get(getOwnerWindow(element))) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
const windowObject = getOwnerWindow(element);
|
|
406
|
+
const documentObject = getOwnerDocument(element);
|
|
407
|
+
|
|
408
|
+
// Programmatic focus() calls shouldn't affect the current input modality.
|
|
409
|
+
// However, we need to detect other cases when a focus event occurs without
|
|
410
|
+
// a preceding user event (e.g. screen reader focus). Overriding the focus
|
|
411
|
+
// method on HTMLElement.prototype is a bit hacky, but works.
|
|
412
|
+
let focus = windowObject.HTMLElement.prototype.focus;
|
|
413
|
+
windowObject.HTMLElement.prototype.focus = function () {
|
|
414
|
+
hasEventBeforeFocus = true;
|
|
415
|
+
focus.apply(this, arguments);
|
|
416
|
+
};
|
|
417
|
+
documentObject.addEventListener('keydown', handleKeyboardEvent, true);
|
|
418
|
+
documentObject.addEventListener('keyup', handleKeyboardEvent, true);
|
|
419
|
+
documentObject.addEventListener('click', handleClickEvent, true);
|
|
420
|
+
|
|
421
|
+
// Register focus events on the window so they are sure to happen
|
|
422
|
+
// before React's event listeners (registered on the document).
|
|
423
|
+
windowObject.addEventListener('focus', handleFocusEvent, true);
|
|
424
|
+
windowObject.addEventListener('blur', handleWindowBlur, false);
|
|
425
|
+
if (typeof PointerEvent !== 'undefined') {
|
|
426
|
+
documentObject.addEventListener('pointerdown', handlePointerEvent, true);
|
|
427
|
+
documentObject.addEventListener('pointermove', handlePointerEvent, true);
|
|
428
|
+
documentObject.addEventListener('pointerup', handlePointerEvent, true);
|
|
429
|
+
} else {
|
|
430
|
+
documentObject.addEventListener('mousedown', handlePointerEvent, true);
|
|
431
|
+
documentObject.addEventListener('mousemove', handlePointerEvent, true);
|
|
432
|
+
documentObject.addEventListener('mouseup', handlePointerEvent, true);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Add unmount handler
|
|
436
|
+
windowObject.addEventListener('beforeunload', () => {
|
|
437
|
+
tearDownWindowFocusTracking(element);
|
|
438
|
+
}, {
|
|
439
|
+
once: true
|
|
440
|
+
});
|
|
441
|
+
hasSetupGlobalListeners.set(windowObject, {
|
|
442
|
+
focus
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
const tearDownWindowFocusTracking = (element, loadListener) => {
|
|
446
|
+
const windowObject = getOwnerWindow(element);
|
|
447
|
+
const documentObject = getOwnerDocument(element);
|
|
448
|
+
if (loadListener) {
|
|
449
|
+
documentObject.removeEventListener('DOMContentLoaded', loadListener);
|
|
450
|
+
}
|
|
451
|
+
if (!hasSetupGlobalListeners.has(windowObject)) {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
windowObject.HTMLElement.prototype.focus = hasSetupGlobalListeners.get(windowObject).focus;
|
|
455
|
+
documentObject.removeEventListener('keydown', handleKeyboardEvent, true);
|
|
456
|
+
documentObject.removeEventListener('keyup', handleKeyboardEvent, true);
|
|
457
|
+
documentObject.removeEventListener('click', handleClickEvent, true);
|
|
458
|
+
windowObject.removeEventListener('focus', handleFocusEvent, true);
|
|
459
|
+
windowObject.removeEventListener('blur', handleWindowBlur, false);
|
|
460
|
+
if (typeof PointerEvent !== 'undefined') {
|
|
461
|
+
documentObject.removeEventListener('pointerdown', handlePointerEvent, true);
|
|
462
|
+
documentObject.removeEventListener('pointermove', handlePointerEvent, true);
|
|
463
|
+
documentObject.removeEventListener('pointerup', handlePointerEvent, true);
|
|
464
|
+
} else {
|
|
465
|
+
documentObject.removeEventListener('mousedown', handlePointerEvent, true);
|
|
466
|
+
documentObject.removeEventListener('mousemove', handlePointerEvent, true);
|
|
467
|
+
documentObject.removeEventListener('mouseup', handlePointerEvent, true);
|
|
468
|
+
}
|
|
469
|
+
hasSetupGlobalListeners.delete(windowObject);
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* EXPERIMENTAL
|
|
474
|
+
* Adds a window (i.e. iframe) to the list of windows that are being tracked for focus visible.
|
|
475
|
+
*
|
|
476
|
+
* Sometimes apps render portions of their tree into an iframe. In this case, we cannot accurately track if the focus
|
|
477
|
+
* is visible because we cannot see interactions inside the iframe. If you have this in your application's architecture,
|
|
478
|
+
* then this function will attach event listeners inside the iframe. You should call `addWindowFocusTracking` with an
|
|
479
|
+
* element from inside the window you wish to add. We'll retrieve the relevant elements based on that.
|
|
480
|
+
* Note, you do not need to call this for the default window, as we call it for you.
|
|
481
|
+
*
|
|
482
|
+
* When you are ready to stop listening, but you do not wish to unmount the iframe, you may call the cleanup function
|
|
483
|
+
* returned by `addWindowFocusTracking`. Otherwise, when you unmount the iframe, all listeners and state will be cleaned
|
|
484
|
+
* up automatically for you.
|
|
485
|
+
*
|
|
486
|
+
* @param element @default document.body - The element provided will be used to get the window to add.
|
|
487
|
+
* @returns A function to remove the event listeners and cleanup the state.
|
|
488
|
+
*/
|
|
489
|
+
function addWindowFocusTracking(element) {
|
|
490
|
+
const documentObject = getOwnerDocument(element);
|
|
491
|
+
let loadListener;
|
|
492
|
+
if (documentObject.readyState !== 'loading') {
|
|
493
|
+
setupGlobalFocusEvents(element);
|
|
494
|
+
} else {
|
|
495
|
+
loadListener = () => {
|
|
496
|
+
setupGlobalFocusEvents(element);
|
|
497
|
+
};
|
|
498
|
+
documentObject.addEventListener('DOMContentLoaded', loadListener);
|
|
499
|
+
}
|
|
500
|
+
return () => tearDownWindowFocusTracking(element, loadListener);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Server-side rendering does not have the document object defined
|
|
504
|
+
// eslint-disable-next-line no-restricted-globals
|
|
505
|
+
if (typeof document !== 'undefined') {
|
|
506
|
+
addWindowFocusTracking();
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* If true, keyboard focus is visible.
|
|
511
|
+
*/
|
|
512
|
+
function isFocusVisible() {
|
|
513
|
+
return currentModality !== 'pointer';
|
|
514
|
+
}
|
|
515
|
+
function getInteractionModality() {
|
|
516
|
+
return currentModality;
|
|
517
|
+
}
|
|
518
|
+
function setInteractionModality(modality) {
|
|
519
|
+
currentModality = modality;
|
|
520
|
+
triggerChangeHandlers(modality, null);
|
|
521
|
+
}
|
|
522
|
+
const nonTextInputTypes = new Set(['checkbox', 'radio', 'range', 'color', 'file', 'image', 'button', 'submit', 'reset']);
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* If this is attached to text input component, return if the event is a focus event (Tab/Escape keys pressed) so that
|
|
526
|
+
* focus visible style can be properly set.
|
|
527
|
+
*/
|
|
528
|
+
function isKeyboardFocusEvent(isTextInput, modality, e) {
|
|
529
|
+
var _e$target;
|
|
530
|
+
const IHTMLInputElement = typeof window !== 'undefined' ? getOwnerWindow(e === null || e === void 0 ? void 0 : e.target).HTMLInputElement : HTMLInputElement;
|
|
531
|
+
const IHTMLTextAreaElement = typeof window !== 'undefined' ? getOwnerWindow(e === null || e === void 0 ? void 0 : e.target).HTMLTextAreaElement : HTMLTextAreaElement;
|
|
532
|
+
const IHTMLElement = typeof window !== 'undefined' ? getOwnerWindow(e === null || e === void 0 ? void 0 : e.target).HTMLElement : HTMLElement;
|
|
533
|
+
const IKeyboardEvent = typeof window !== 'undefined' ? getOwnerWindow(e === null || e === void 0 ? void 0 : e.target).KeyboardEvent : KeyboardEvent;
|
|
534
|
+
isTextInput = isTextInput || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLInputElement && !nonTextInputTypes.has(e === null || e === void 0 ? void 0 : (_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.type) || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLTextAreaElement || (e === null || e === void 0 ? void 0 : e.target) instanceof IHTMLElement && (e === null || e === void 0 ? void 0 : e.target.isContentEditable);
|
|
535
|
+
return !(isTextInput && modality === 'keyboard' && e instanceof IKeyboardEvent && !FOCUS_VISIBLE_INPUT_KEYS[e.key]);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Listens for trigger change and reports if focus is visible (i.e., modality is not pointer).
|
|
540
|
+
*/
|
|
541
|
+
function useFocusVisibleListener(fn, deps, opts) {
|
|
542
|
+
setupGlobalFocusEvents();
|
|
543
|
+
useEffect(() => {
|
|
544
|
+
let handler = (modality, e) => {
|
|
545
|
+
if (!isKeyboardFocusEvent(!!(opts !== null && opts !== void 0 && opts.isTextInput), modality, e)) {
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
fn(isFocusVisible());
|
|
549
|
+
};
|
|
550
|
+
changeHandlers.add(handler);
|
|
551
|
+
return () => {
|
|
552
|
+
changeHandlers.delete(handler);
|
|
553
|
+
};
|
|
554
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
555
|
+
}, deps);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/* eslint-disable prefer-const */
|
|
559
|
+
/**
|
|
560
|
+
* Handles focus events for the target and its descendants.
|
|
561
|
+
*/
|
|
562
|
+
function useFocusWithin(props) {
|
|
563
|
+
let {
|
|
564
|
+
isDisabled,
|
|
565
|
+
onBlurWithin,
|
|
566
|
+
onFocusWithin,
|
|
567
|
+
onFocusWithinChange
|
|
568
|
+
} = props;
|
|
569
|
+
let state = useRef({
|
|
570
|
+
isFocusWithin: false
|
|
571
|
+
});
|
|
572
|
+
let onBlur = useCallback(e => {
|
|
573
|
+
// We don't want to trigger onBlurWithin and then immediately onFocusWithin again
|
|
574
|
+
// when moving focus inside the element. Only trigger if the currentTarget doesn't
|
|
575
|
+
// include the relatedTarget (where focus is moving).
|
|
576
|
+
if (state.current.isFocusWithin && !e.currentTarget.contains(e.relatedTarget)) {
|
|
577
|
+
state.current.isFocusWithin = false;
|
|
578
|
+
if (onBlurWithin) {
|
|
579
|
+
onBlurWithin(e);
|
|
580
|
+
}
|
|
581
|
+
if (onFocusWithinChange) {
|
|
582
|
+
onFocusWithinChange(false);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}, [onBlurWithin, onFocusWithinChange, state]);
|
|
586
|
+
let onSyntheticFocus = useSyntheticBlurEvent(onBlur);
|
|
587
|
+
let onFocus = useCallback(e => {
|
|
588
|
+
// Double check that document.activeElement actually matches e.target in case a previously chained
|
|
589
|
+
// focus handler already moved focus somewhere else.
|
|
590
|
+
if (!state.current.isFocusWithin && document.activeElement === e.target) {
|
|
591
|
+
if (onFocusWithin) {
|
|
592
|
+
onFocusWithin(e);
|
|
593
|
+
}
|
|
594
|
+
if (onFocusWithinChange) {
|
|
595
|
+
onFocusWithinChange(true);
|
|
596
|
+
}
|
|
597
|
+
state.current.isFocusWithin = true;
|
|
598
|
+
onSyntheticFocus(e);
|
|
599
|
+
}
|
|
600
|
+
}, [onFocusWithin, onFocusWithinChange, onSyntheticFocus]);
|
|
601
|
+
if (isDisabled) {
|
|
602
|
+
return {
|
|
603
|
+
focusWithinProps: {
|
|
604
|
+
// These should not have been null, that would conflict in mergeProps
|
|
605
|
+
onFocus: undefined,
|
|
606
|
+
onBlur: undefined
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
return {
|
|
611
|
+
focusWithinProps: {
|
|
612
|
+
onFocus,
|
|
613
|
+
onBlur
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/* eslint-disable prefer-const */
|
|
619
|
+
/**
|
|
620
|
+
* Determines whether a focus ring should be shown to indicate keyboard focus.
|
|
621
|
+
* Focus rings are visible only when the user is interacting with a keyboard,
|
|
622
|
+
* not with a mouse, touch, or other input methods.
|
|
623
|
+
*/
|
|
624
|
+
function useFocusRing() {
|
|
625
|
+
let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
626
|
+
let {
|
|
627
|
+
autoFocus = false,
|
|
628
|
+
isTextInput,
|
|
629
|
+
within
|
|
630
|
+
} = props;
|
|
631
|
+
let state = useRef({
|
|
632
|
+
isFocused: false,
|
|
633
|
+
isFocusVisible: autoFocus || isFocusVisible()
|
|
634
|
+
});
|
|
635
|
+
let [isFocused, setFocused] = useState(false);
|
|
636
|
+
let [isFocusVisibleState, setFocusVisible] = useState(() => state.current.isFocused && state.current.isFocusVisible);
|
|
637
|
+
let updateState = useCallback(() => setFocusVisible(state.current.isFocused && state.current.isFocusVisible), []);
|
|
638
|
+
let onFocusChange = useCallback(isFocused => {
|
|
639
|
+
state.current.isFocused = isFocused;
|
|
640
|
+
setFocused(isFocused);
|
|
641
|
+
updateState();
|
|
642
|
+
}, [updateState]);
|
|
643
|
+
useFocusVisibleListener(isFocusVisible => {
|
|
644
|
+
state.current.isFocusVisible = isFocusVisible;
|
|
645
|
+
updateState();
|
|
646
|
+
}, [], {
|
|
647
|
+
isTextInput
|
|
648
|
+
});
|
|
649
|
+
let {
|
|
650
|
+
focusProps
|
|
651
|
+
} = useFocus({
|
|
652
|
+
isDisabled: within,
|
|
653
|
+
onFocusChange
|
|
654
|
+
});
|
|
655
|
+
let {
|
|
656
|
+
focusWithinProps
|
|
657
|
+
} = useFocusWithin({
|
|
658
|
+
isDisabled: !within,
|
|
659
|
+
onFocusWithinChange: onFocusChange
|
|
660
|
+
});
|
|
661
|
+
return {
|
|
662
|
+
isFocused,
|
|
663
|
+
isFocusVisible: isFocusVisibleState,
|
|
664
|
+
focusProps: within ? focusWithinProps : focusProps
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
export { useFocusWithin as a, useLayoutEffect as b, isMac as c, isWebKit as d, isIPad as e, useEffectEvent as f, isIOS as g, getOwnerDocument as h, isFirefox as i, isVirtualPointerEvent as j, isVirtualClick as k, getOwnerWindow as l, getInteractionModality as m, useFocus as n, isIPhone as o, isAndroid as p, setInteractionModality as s, useFocusRing as u };
|
|
669
|
+
//# sourceMappingURL=useFocusRing.js.map
|