@zohodesk/components 1.0.0-alpha-244 → 1.0.0-alpha-247

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.
Files changed (31) hide show
  1. package/README.md +10 -0
  2. package/assets/Appearance/pureDark/mode/pureDarkMode.module.css +2 -2
  3. package/es/CheckBox/CheckBox.module.css +12 -8
  4. package/es/LightNightMode/Colors.json +496 -397
  5. package/es/LightNightMode/docs/AlternativeColors.docs.js +21 -1
  6. package/es/ListItem/ListItem.module.css +12 -8
  7. package/es/MultiSelect/AdvancedGroupMultiSelect.js +1 -1
  8. package/es/Radio/Radio.module.css +8 -6
  9. package/es/RippleEffect/RippleEffect.module.css +37 -15
  10. package/es/Switch/Switch.module.css +3 -2
  11. package/es/index.js +0 -4
  12. package/lib/CheckBox/CheckBox.module.css +12 -8
  13. package/lib/LightNightMode/Colors.json +496 -397
  14. package/lib/LightNightMode/docs/AlternativeColors.docs.js +23 -1
  15. package/lib/ListItem/ListItem.module.css +12 -8
  16. package/lib/MultiSelect/AdvancedGroupMultiSelect.js +1 -1
  17. package/lib/Radio/Radio.module.css +8 -6
  18. package/lib/RippleEffect/RippleEffect.module.css +37 -15
  19. package/lib/Switch/Switch.module.css +3 -2
  20. package/lib/index.js +0 -36
  21. package/package.json +5 -5
  22. package/es/a11y/FocusScope/FocusScope.js +0 -370
  23. package/es/a11y/FocusScope/docs/FocusScope__default.docs.js +0 -139
  24. package/es/beta/FocusRing/FocusRing.js +0 -281
  25. package/es/beta/FocusRing/FocusRing.module.css +0 -152
  26. package/es/beta/FocusRing/docs/FocusRing__default.docs.js +0 -48
  27. package/lib/a11y/FocusScope/FocusScope.js +0 -443
  28. package/lib/a11y/FocusScope/docs/FocusScope__default.docs.js +0 -191
  29. package/lib/beta/FocusRing/FocusRing.js +0 -338
  30. package/lib/beta/FocusRing/FocusRing.module.css +0 -152
  31. package/lib/beta/FocusRing/docs/FocusRing__default.docs.js +0 -101
@@ -71,7 +71,10 @@ var AlternativeColors = /*#__PURE__*/function (_React$Component) {
71
71
  }, "Light Mode Colors"), /*#__PURE__*/_react["default"].createElement(_Box["default"], {
72
72
  flexible: true,
73
73
  className: _docStyleModule["default"].rgt
74
- }, "Alternate Night Mode Colors")), /*#__PURE__*/_react["default"].createElement(_Container["default"], {
74
+ }, "Alternate Night Mode Colors"), /*#__PURE__*/_react["default"].createElement(_Box["default"], {
75
+ flexible: true,
76
+ className: _docStyleModule["default"].rgt
77
+ }, "Alternate Pure Dark Mode Colors")), /*#__PURE__*/_react["default"].createElement(_Container["default"], {
75
78
  alignBox: "row",
76
79
  className: _docStyleModule["default"].content
77
80
  }, /*#__PURE__*/_react["default"].createElement(_Box["default"], {
@@ -114,6 +117,25 @@ var AlternativeColors = /*#__PURE__*/function (_React$Component) {
114
117
  },
115
118
  "data-title": "Copy ".concat(clrValue)
116
119
  }, clrValue));
120
+ })), /*#__PURE__*/_react["default"].createElement(_Box["default"], {
121
+ flexible: true,
122
+ className: _docStyleModule["default"].rgt
123
+ }, index.equalPureDarkColors.toString().split(", ").map(function (clrValue, j) {
124
+ return /*#__PURE__*/_react["default"].createElement("div", {
125
+ className: _docStyleModule["default"].nestedDiv,
126
+ key: j
127
+ }, /*#__PURE__*/_react["default"].createElement("span", {
128
+ style: {
129
+ backgroundColor: "".concat(clrValue)
130
+ },
131
+ className: "".concat(_docStyleModule["default"].rect, " ").concat(_docStyleModule["default"].gold)
132
+ }), /*#__PURE__*/_react["default"].createElement("span", {
133
+ className: _docStyleModule["default"].colorvalue,
134
+ onClick: function onClick() {
135
+ return navigator.clipboard.writeText(clrValue);
136
+ },
137
+ "data-title": "Copy ".concat(clrValue)
138
+ }, clrValue));
117
139
  })));
118
140
  })))));
119
141
  }
@@ -106,26 +106,30 @@
106
106
  }
107
107
 
108
108
  .defaultHover,
109
- .defaultEffect:hover,
110
- .defaultEffect:focus {
109
+ .defaultEffect:hover
110
+ /* .defaultEffect:focus */
111
+ {
111
112
  --listitem_bg_color: var(--zdt_listitem_highlight_bg);
112
113
  }
113
114
  .primaryHover,
114
- .primaryEffect:hover,
115
- .primaryEffect:focus {
115
+ .primaryEffect:hover
116
+ /* .primaryEffect:focus */
117
+ {
116
118
  --listitem_bg_color: var(--zdt_listitem_primary_bg);
117
119
  --listitem_highlight_bg_color: var(--zdt_listitem_primary_bg);
118
120
  }
119
121
  .secondaryHover,
120
- .secondaryEffect:hover,
121
- .secondaryEffect:focus {
122
+ .secondaryEffect:hover
123
+ /* .secondaryEffect:focus */
124
+ {
122
125
  --listitem_bg_color: var(--zdt_listitem_secondary_bg);
123
126
  --listitem_highlight_bg_color: var(--zdt_listitem_secondary_bg);
124
127
  --listitem_text_color: var(--zdt_listitem_secondary_text);
125
128
  }
126
129
  .darkHover,
127
- .darkEffect:hover,
128
- .darkEffect:focus {
130
+ .darkEffect:hover
131
+ /* .darkEffect:focus */
132
+ {
129
133
  --listitem_bg_color: var(--zdt_listitem_dark_effect_bg);
130
134
  --listitem_highlight_bg_color: var(--zdt_listitem_dark_effect_bg);
131
135
  }
@@ -11,7 +11,7 @@ var _react = _interopRequireDefault(require("react"));
11
11
 
12
12
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
13
 
14
- var _Loader = _interopRequireDefault(require("@zohodesk/svg/lib/svg/Loader"));
14
+ var _Loader = _interopRequireDefault(require("@zohodesk/svg/lib/Loader/Loader"));
15
15
 
16
16
  var _Popup = _interopRequireDefault(require("../Popup/Popup"));
17
17
 
@@ -67,14 +67,16 @@
67
67
  animation: circleAnimate var(--zd_transition3) ease forwards;
68
68
  }
69
69
  .rdBoxprimary,
70
- .hoverEfffect:hover .hoverprimary,
71
- .hoverEfffect:focus .hoverprimary {
70
+ .hoverEfffect:hover .hoverprimary
71
+ /* .hoverEfffect:focus .hoverprimary */
72
+ {
72
73
  --radio_stroke_color: var(--zdt_radio_primary_stroke);
73
74
  }
74
75
 
75
76
  .rdBoxdanger,
76
- .hoverEfffect:hover .hoverdanger,
77
- .hoverEfffect:focus .hoverdanger {
77
+ .hoverEfffect:hover .hoverdanger
78
+ /* .hoverEfffect:focus .hoverdanger */
79
+ {
78
80
  --radio_stroke_color: var(--zdt_radio_danger_stroke);
79
81
  }
80
82
 
@@ -86,13 +88,13 @@
86
88
  }
87
89
 
88
90
  .active:hover .primaryLabel,
89
- .active:focus .primaryLabel,
91
+ /* .active:focus .primaryLabel, */
90
92
  .primarycheckedActive {
91
93
  --label_text_color: var(--zdt_radio_label_primary_text);
92
94
  }
93
95
 
94
96
  .active:hover .dangerLabel,
95
- .active:focus .dangerLabel,
97
+ /* .active:focus .dangerLabel, */
96
98
  .dangercheckedActive {
97
99
  --label_text_color: var(--zdt_radio_label_danger_text);
98
100
  }
@@ -8,43 +8,61 @@
8
8
  .default.defaultHover {
9
9
  border-color: var(--zdt_rippleeffect_hover_border);
10
10
  }
11
- .hoverEffect:hover.primary.defaultHover, .hoverEffect:focus.primary.defaultHover, .hoverEffect:hover.primary.borderHover, .hoverEffect:focus.primary.borderHover {
11
+ .hoverEffect:hover.primary.defaultHover, .hoverEffect:hover.primary.borderHover
12
+ /* .hoverEffect:focus.primary.borderHover */
13
+ {
12
14
  border-color: var(--zdt_rippleeffect_primary_border);
13
15
  }
14
- .primary.defaultHover, .hoverEffect:hover.primary.active.border, .hoverEffect:focus.primary.active.border {
16
+ .primary.defaultHover, .hoverEffect:hover.primary.active.border
17
+ /* .hoverEffect:focus.primary.active.border */
18
+ {
15
19
  border-color: var(--zdt_rippleeffect_primary_active_border);
16
20
  }
17
- .primaryLight.defaultHover, .hoverEffect:hover.primaryLight.borderHover, .hoverEffect:focus.primaryLight.borderHover {
21
+ .primaryLight.defaultHover, .hoverEffect:hover.primaryLight.borderHover
22
+ /* .hoverEffect:focus.primaryLight.borderHover */
23
+ {
18
24
  border-color: var(--zdt_rippleeffect_primary_light_border);
19
25
  }
20
- .green.defaultHover, .hoverEffect:hover.green.borderHover, .hoverEffect:focus.green.borderHover {
26
+ .green.defaultHover, .hoverEffect:hover.green.borderHover
27
+ /* .hoverEffect:focus.green.borderHover */
28
+ {
21
29
  border-color: var(--zdt_rippleeffect_green_border);
22
30
  }
23
- .hoverEffect:hover.default.defaultHover, .hoverEffect:focus.default.defaultHover {
31
+ .hoverEffect:hover.default.defaultHover
32
+ /* .hoverEffect:focus.default.defaultHover */
33
+ {
24
34
  border-color: var(--zdt_rippleeffect_slate_border);
25
35
  }
26
- .hoverEffect:hover.default.borderHover, .hoverEffect:focus.default.borderHover {
36
+ .hoverEffect:hover.default.borderHover
37
+ /* .hoverEffect:focus.default.borderHover */
38
+ {
27
39
  border-color: var(--zdt_rippleeffect_navy_border);
28
40
  }
29
- .hoverEffect:hover.default.bgHover, .hoverEffect:focus.default.bgHover {
41
+ .hoverEffect:hover.default.bgHover
42
+ /* .hoverEffect:focus.default.bgHover */
43
+ {
30
44
  background-color: var(--zdt_rippleeffect_hover_bg);
31
45
  }
32
- .hoverEffect:hover.primaryLight.bgHover, .hoverEffect:focus.primaryLight.bgHover {
46
+ .hoverEffect:hover.primaryLight.bgHover
47
+ /* .hoverEffect:focus.primaryLight.bgHover */
48
+ {
33
49
  background-color: var(--zdt_rippleeffect_primary_light_bg);
34
50
  }
35
51
  .primaryFilled {
36
52
  background-color: var(--zdt_rippleeffect_primary_bg);
37
53
  }
38
- .hoverEffect:hover.primaryFilled, .hoverEffect:focus.primaryFilled, .primaryFilled.active {
54
+ .hoverEffect:hover.primaryFilled, .primaryFilled.active {
39
55
  background-color: var(--zdt_rippleeffect_primaryfilled_bg);
40
56
  }
41
- .hoverEffect:hover.green.bgHover, .hoverEffect:focus.green.bgHover {
57
+ .hoverEffect:hover.green.bgHover
58
+ /* .hoverEffect:focus.green.bgHover */
59
+ {
42
60
  background-color: var(--zdt_rippleeffect_green_bg);
43
61
  }
44
- .default.active, .hoverEffect:hover.default.active, .hoverEffect:focus.default.active, .primaryLight.active, .primaryDark.active {
62
+ .default.active, .hoverEffect:hover.default.active, .primaryLight.active, .primaryDark.active {
45
63
  background-color: var(--zdt_rippleeffect_primary_light_bg);
46
64
  }
47
- .default.active.border, .hoverEffect:hover.default.active.border, .hoverEffect:focus.default.active.border, .primaryLight.active.border, .primaryDark.active.border {
65
+ .default.active.border, .hoverEffect:hover.default.active.border, .primaryLight.active.border, .primaryDark.active.border {
48
66
  border-color: var(--zdt_rippleeffect_primary_light_border);
49
67
  }
50
68
  .green.active {
@@ -56,13 +74,17 @@
56
74
  .primary.active {
57
75
  background-color: var(--zdt_rippleeffect_primary_bg);
58
76
  }
59
- .danger.defaultHover, .hoverEffect:hover.danger.borderHover, .hoverEffect:focus.danger.borderHover {
77
+ .danger.defaultHover, .hoverEffect:hover.danger.borderHover
78
+ /* .hoverEffect:focus.danger.borderHover */
79
+ {
60
80
  border-color: var(--zdt_rippleeffect_danger_border);
61
81
  }
62
- .hoverEffect:hover.danger.bgHover, .hoverEffect:focus.danger.bgHover, .danger.active {
82
+ .hoverEffect:hover.danger.bgHover, .danger.active {
63
83
  background-color: var(--zdt_rippleeffect_danger_bg);
64
84
  }
65
- .hoverEffect:hover.primaryDark.bgHover, .hoverEffect:focus.primaryDark.bgHover {
85
+ .hoverEffect:hover.primaryDark.bgHover
86
+ /* .hoverEffect:focus.primaryDark.bgHover */
87
+ {
66
88
  background-color: var(--zdt_rippleeffect_primary_dark_bg);
67
89
  }
68
90
  .notAllowed {
@@ -26,8 +26,9 @@
26
26
  border-radius: 20px;
27
27
  cursor: pointer;
28
28
  }
29
- .effect:hover .label,
30
- .effect:focus .label {
29
+ .effect:hover .label
30
+ /* .effect:focus .label */
31
+ {
31
32
  --switch_off_bg_color: var(--zdt_switch_effect_off_bg);
32
33
  }
33
34
  .label:after {
package/lib/index.js CHANGED
@@ -150,10 +150,6 @@ var _exportNames = {
150
150
  Provider__Zindex_For_FunctionComponent: true,
151
151
  SemanticButton: true,
152
152
  SemanticButton__default: true,
153
- FocusScope: true,
154
- FocusScope__default: true,
155
- FocusRing: true,
156
- FocusRing__default: true,
157
153
  LightNightMode__AlternativeColors: true,
158
154
  ResponsiveDropBox: true
159
155
  };
@@ -469,30 +465,6 @@ Object.defineProperty(exports, "DropDownHeading__Heading", {
469
465
  return _DropDownHeading__default["default"];
470
466
  }
471
467
  });
472
- Object.defineProperty(exports, "FocusRing", {
473
- enumerable: true,
474
- get: function get() {
475
- return _FocusRing["default"];
476
- }
477
- });
478
- Object.defineProperty(exports, "FocusRing__default", {
479
- enumerable: true,
480
- get: function get() {
481
- return _FocusRing__default["default"];
482
- }
483
- });
484
- Object.defineProperty(exports, "FocusScope", {
485
- enumerable: true,
486
- get: function get() {
487
- return _FocusScope["default"];
488
- }
489
- });
490
- Object.defineProperty(exports, "FocusScope__default", {
491
- enumerable: true,
492
- get: function get() {
493
- return _FocusScope__default["default"];
494
- }
495
- });
496
468
  Object.defineProperty(exports, "GroupSelect", {
497
469
  enumerable: true,
498
470
  get: function get() {
@@ -1406,14 +1378,6 @@ var _Button2 = _interopRequireDefault(require("./semantic/Button/Button"));
1406
1378
 
1407
1379
  var _Button__defaultDocs = _interopRequireDefault(require("./semantic/Button/docs/Button__default.docs.js"));
1408
1380
 
1409
- var _FocusScope = _interopRequireDefault(require("./a11y/FocusScope/FocusScope"));
1410
-
1411
- var _FocusScope__default = _interopRequireDefault(require("./a11y/FocusScope/docs/FocusScope__default.docs"));
1412
-
1413
- var _FocusRing = _interopRequireDefault(require("./beta/FocusRing/FocusRing"));
1414
-
1415
- var _FocusRing__default = _interopRequireDefault(require("./beta/FocusRing/docs/FocusRing__default.docs"));
1416
-
1417
1381
  var _AlternativeColors = _interopRequireDefault(require("./LightNightMode/docs/AlternativeColors.docs"));
1418
1382
 
1419
1383
  var _ResponsiveDropBox = _interopRequireDefault(require("./ResponsiveDropBox/ResponsiveDropBox"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/components",
3
- "version": "1.0.0-alpha-244",
3
+ "version": "1.0.0-alpha-247",
4
4
  "main": "lib/index.js",
5
5
  "module": "es/index.js",
6
6
  "jsnext:main": "es/index.js",
@@ -37,11 +37,11 @@
37
37
  "devDependencies": {
38
38
  "@zohodesk/docstool": "1.0.0-alpha-2",
39
39
  "@zohodesk/variables": "1.0.0-beta.29",
40
- "@zohodesk/icons": "1.0.0-beta.105",
40
+ "@zohodesk/icons": "1.0.0-beta.109",
41
41
  "@zohodesk/virtualizer": "1.0.3",
42
42
  "velocity-react": "1.4.3",
43
43
  "react-sortable-hoc": "^0.8.3",
44
- "@zohodesk/svg": "1.0.0-beta.47"
44
+ "@zohodesk/svg": "1.0.0-beta.48"
45
45
  },
46
46
  "dependencies": {
47
47
  "hoist-non-react-statics": "3.0.1",
@@ -50,9 +50,9 @@
50
50
  "selectn": "1.1.2"
51
51
  },
52
52
  "peerDependencies": {
53
- "@zohodesk/icons": "1.0.0-beta.105",
53
+ "@zohodesk/icons": "1.0.0-beta.109",
54
54
  "@zohodesk/variables": "1.0.0-beta.29",
55
- "@zohodesk/svg": "1.0.0-beta.47",
55
+ "@zohodesk/svg": "1.0.0-beta.49",
56
56
  "@zohodesk/virtualizer": "1.0.3",
57
57
  "velocity-react": "1.4.3",
58
58
  "react-sortable-hoc": "^0.8.3"
@@ -1,370 +0,0 @@
1
- import React, { useContext, useEffect, useRef } from 'react';
2
- let scopes = new Set();
3
- let activeScope = null;
4
- const FocusContext = /*#__PURE__*/React.createContext(null); // interface FocusManager {
5
- // /** Moves focus to the next focusable or tabbable element in the focus scope. */
6
- // focusNext(opts?: FocusManagerOptions): HTMLElement,
7
- // /** Moves focus to the previous focusable or tabbable element in the focus scope. */
8
- // focusPrevious(opts?: FocusManagerOptions): HTMLElement
9
- // }
10
-
11
- export const useLayoutEffect = window !== 'undefined' ? React.useLayoutEffect : () => {};
12
- export default function FocusScope(props) {
13
- let {
14
- children,
15
- contain = true,
16
- restoreFocus = true,
17
- autoFocus = true
18
- } = props;
19
- let startRef = useRef();
20
- let endRef = useRef();
21
- let scopeRef = useRef([]);
22
- useLayoutEffect(() => {
23
- // Find all rendered nodes between the sentinels and add them to the scope.
24
- let node = startRef.current.nextSibling;
25
- let nodes = [];
26
-
27
- while (node && node !== endRef.current) {
28
- nodes.push(node);
29
- node = node.nextSibling;
30
- }
31
-
32
- scopeRef.current = nodes;
33
- scopes.add(scopeRef);
34
- return () => {
35
- scopes.delete(scopeRef);
36
- };
37
- }, [children]);
38
- useFocusContainment(scopeRef, contain);
39
- useRestoreFocus(scopeRef, restoreFocus, contain);
40
- useAutoFocus(scopeRef, autoFocus);
41
- let focusManager = createFocusManager(scopeRef);
42
- return /*#__PURE__*/React.createElement(FocusContext.Provider, {
43
- value: focusManager
44
- }, /*#__PURE__*/React.createElement("span", {
45
- hidden: true,
46
- ref: startRef
47
- }), children, /*#__PURE__*/React.createElement("span", {
48
- hidden: true,
49
- ref: endRef
50
- }));
51
- }
52
- export function useFocusManager() {
53
- return useContext(FocusContext);
54
- }
55
-
56
- function createFocusManager(scopeRef) {
57
- return {
58
- focusNext(opts) {
59
- let node = opts.from || document.activeElement;
60
- let focusable = getFocusableElementsInScope(scopeRef.current, opts);
61
- let nextNode = focusable.find(n => !!(node.compareDocumentPosition(n) & (Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY)));
62
-
63
- if (!nextNode && opts.wrap) {
64
- nextNode = focusable[0];
65
- }
66
-
67
- if (nextNode) {
68
- nextNode.focus();
69
- }
70
-
71
- return nextNode;
72
- },
73
-
74
- focusPrevious(opts) {
75
- let node = opts.from || document.activeElement;
76
- let focusable = getFocusableElementsInScope(scopeRef.current, opts).reverse();
77
- let previousNode = focusable.find(n => !!(node.compareDocumentPosition(n) & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINED_BY)));
78
-
79
- if (!previousNode && opts.wrap) {
80
- previousNode = focusable[0];
81
- }
82
-
83
- if (previousNode) {
84
- previousNode.focus();
85
- }
86
-
87
- return previousNode;
88
- }
89
-
90
- };
91
- }
92
-
93
- const focusableElements = ['input:not([disabled]):not([type=hidden])', 'select:not([disabled])', 'textarea:not([disabled])', 'button:not([disabled])', 'a[href]', 'audio[controls]', 'video[controls]', '[contenteditable]:not([contenteditable="false"])', 'details>summary:first-of-type', 'details', 'area[href]', 'summary', 'iframe', 'object', 'embed'];
94
- const FOCUSABLE_ELEMENT_SELECTOR = focusableElements.join(',') + ',[tabindex]';
95
- focusableElements.push('[tabindex]:not([tabindex="-1"])');
96
- const TABBABLE_ELEMENT_SELECTOR = focusableElements.join(':not([tabindex="-1"]),');
97
-
98
- function useAutoFocus(scopeRef, autoFocus) {
99
- useEffect(() => {
100
- if (autoFocus) {
101
- activeScope = scopeRef;
102
-
103
- if (!isElementInScope(document.activeElement, activeScope.current)) {
104
- focusFirstInScope(scopeRef.current);
105
- }
106
- }
107
- }, [scopeRef, autoFocus]);
108
- }
109
-
110
- function getFocusableElementsInScope(scope, opts) {
111
- let res = [],
112
- response = [];
113
- let selector = opts.tabbable ? TABBABLE_ELEMENT_SELECTOR : FOCUSABLE_ELEMENT_SELECTOR;
114
-
115
- for (let node of scope) {
116
- if (node.matches(selector)) {
117
- res.push(node);
118
- }
119
-
120
- response.push(...Array.from(node.querySelectorAll(selector)));
121
- res = response.filter(element => {
122
- return !(window.getComputedStyle(element).display === 'none');
123
- });
124
- }
125
-
126
- ;
127
- return res;
128
- }
129
-
130
- function useFocusContainment(scopeRef, contain) {
131
- let focusedNode = useRef();
132
- let raf = useRef(null);
133
- useEffect(() => {
134
- let scope = scopeRef.current;
135
-
136
- if (!contain) {
137
- return;
138
- } // Handle the Tab key to contain focus within the scope
139
-
140
-
141
- let onKeyDown = e => {
142
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) {
143
- return;
144
- }
145
-
146
- let elements = getFocusableElementsInScope(scope, {
147
- tabbable: true
148
- });
149
- let focusedElement = document.activeElement;
150
-
151
- if (!isElementInScope(focusedElement, scope)) {
152
- return;
153
- }
154
-
155
- let position = elements.indexOf(focusedElement);
156
- let lastPosition = elements.length - 1;
157
- let nextElement = null;
158
-
159
- if (e.shiftKey) {
160
- if (position <= 0) {
161
- nextElement = elements[lastPosition];
162
- } else {
163
- nextElement = elements[position - 1];
164
- }
165
- } else {
166
- if (position === lastPosition) {
167
- nextElement = elements[0];
168
- } else {
169
- nextElement = elements[position + 1];
170
- }
171
- }
172
-
173
- e.preventDefault();
174
-
175
- if (nextElement) {
176
- focusElement(nextElement, true);
177
- }
178
- };
179
-
180
- let onFocus = e => {
181
- // If a focus event occurs outside the active scope (e.g. user tabs from browser location bar),
182
- // restore focus to the previously focused node or the first tabbable element in the active scope.
183
- let isInAnyScope = isElementInAnyScope(e.target, scopes);
184
-
185
- if (!isInAnyScope) {
186
- if (focusedNode.current) {
187
- focusedNode.current.focus();
188
- } else if (activeScope) {
189
- focusFirstInScope(activeScope.current);
190
- }
191
- } else {
192
- activeScope = scopeRef;
193
- focusedNode.current = e.target;
194
- }
195
- };
196
-
197
- let onBlur = e => {
198
- // Firefox doesn't shift focus back to the Dialog properly without this
199
- raf.current = requestAnimationFrame(() => {
200
- // Use document.activeElement instead of e.relatedTarget so we can tell if user clicked into iframe
201
- let isInAnyScope = isElementInAnyScope(document.activeElement, scopes);
202
-
203
- if (!isInAnyScope) {
204
- activeScope = scopeRef;
205
- focusedNode.current = e.target;
206
- focusedNode.current.focus();
207
- }
208
- });
209
- };
210
-
211
- document.addEventListener('keydown', onKeyDown, false);
212
- document.addEventListener('focusin', onFocus, false);
213
- scope.forEach(element => element.addEventListener('focusin', onFocus, false));
214
- scope.forEach(element => element.addEventListener('focusout', onBlur, false));
215
- return () => {
216
- document.removeEventListener('keydown', onKeyDown, false);
217
- document.removeEventListener('focusin', onFocus, false);
218
- scope.forEach(element => element.removeEventListener('focusin', onFocus, false));
219
- scope.forEach(element => element.removeEventListener('focusout', onBlur, false));
220
- };
221
- }, [scopeRef, contain]); // eslint-disable-next-line arrow-body-style
222
-
223
- useEffect(() => {
224
- return () => cancelAnimationFrame(raf.current);
225
- }, [raf]);
226
- }
227
-
228
- function isElementInAnyScope(element) {
229
- let scopes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
230
-
231
- for (let scope of scopes.values()) {
232
- if (isElementInScope(element, scope.current)) {
233
- return true;
234
- }
235
- }
236
-
237
- return false;
238
- }
239
-
240
- function isElementInScope(element) {
241
- let scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
242
- return scope.some(node => node.contains(element));
243
- }
244
-
245
- function focusElement() {
246
- let element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
247
-
248
- if (element != null) {
249
- element.focus();
250
- }
251
- }
252
-
253
- function findElement(elements) {
254
- let ele = [];
255
-
256
- for (let element = 0; element < elements.length; element++) {
257
- let elem = elements[element];
258
-
259
- if (elem.getAttribute('data-auto-focus')) {
260
- ele.push(elem);
261
- }
262
- }
263
-
264
- return ele.length ? ele[0] : null;
265
- }
266
-
267
- function focusFirstInScope() {
268
- let scope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
269
- let elements = getFocusableElementsInScope(scope, {
270
- tabbable: true
271
- });
272
- let element = findElement(elements);
273
- focusElement(element ? element : elements[0]);
274
- }
275
-
276
- function useRestoreFocus(scopeRef, restoreFocus, contain) {
277
- // useLayoutEffect instead of useEffect so the active element is saved synchronously instead of asynchronously.
278
- useLayoutEffect(() => {
279
- let scope = scopeRef.current;
280
- let nodeToRestore = document.activeElement; // Handle the Tab key so that tabbing out of the scope goes to the next element
281
- // after the node that had focus when the scope mounted. This is important when
282
- // using portals for overlays, so that focus goes to the expected element when
283
- // tabbing out of the overlay.
284
-
285
- let onKeyDown = e => {
286
- if (e.key !== 'Tab' || e.altKey || e.ctrlKey || e.metaKey) {
287
- return;
288
- }
289
-
290
- let focusedElement = document.activeElement;
291
-
292
- if (!isElementInScope(focusedElement, scope)) {
293
- return;
294
- } // Create a DOM tree walker that matches all tabbable elements
295
-
296
-
297
- let walker = getFocusableTreeWalker(document.body, {
298
- tabbable: true
299
- }); // Find the next tabbable element after the currently focused element
300
-
301
- walker.currentNode = focusedElement;
302
- let nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode(); // If there is no next element, or it is outside the current scope, move focus to the
303
- // next element after the node to restore to instead.
304
-
305
- if ((!nextElement || !isElementInScope(nextElement, scope)) && nodeToRestore) {
306
- walker.currentNode = nodeToRestore; // Skip over elements within the scope, in case the scope immediately follows the node to restore.
307
-
308
- do {
309
- nextElement = e.shiftKey ? walker.previousNode() : walker.nextNode();
310
- } while (isElementInScope(nextElement, scope));
311
-
312
- e.preventDefault();
313
- e.stopPropagation();
314
-
315
- if (nextElement) {
316
- nextElement.focus();
317
- } else {
318
- // If there is no next element, blur the focused element to move focus to the body.
319
- focusedElement.blur();
320
- }
321
- }
322
- };
323
-
324
- if (!contain) {
325
- document.addEventListener('keydown', onKeyDown, true);
326
- }
327
-
328
- return () => {
329
- if (!contain) {
330
- document.removeEventListener('keydown', onKeyDown, true);
331
- }
332
-
333
- if (restoreFocus && nodeToRestore && isElementInScope(document.activeElement, scope)) {
334
- requestAnimationFrame(() => {
335
- if (document.body.contains(nodeToRestore)) {
336
- focusElement(nodeToRestore);
337
- }
338
- });
339
- }
340
- };
341
- }, [scopeRef, restoreFocus, contain]);
342
- }
343
-
344
- export function getFocusableTreeWalker(root, opts) {
345
- let selector = opts && opts.tabbable ? TABBABLE_ELEMENT_SELECTOR : FOCUSABLE_ELEMENT_SELECTOR;
346
- let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
347
- acceptNode(node) {
348
- // Skip nodes inside the starting node.
349
- if (opts && opts.from && opts.from.contains(node)) {
350
- return NodeFilter.FILTER_REJECT;
351
- }
352
-
353
- if (node.matches(selector)) {
354
- return NodeFilter.FILTER_ACCEPT;
355
- }
356
-
357
- return NodeFilter.FILTER_SKIP;
358
- }
359
-
360
- }, false);
361
-
362
- if (opts && opts.from) {
363
- walker.currentNode = opts.from;
364
- }
365
-
366
- return walker;
367
- }
368
- FocusScope.docs = {
369
- componentGroup: 'Atom'
370
- };