orcs-design-system 3.1.29 → 3.1.31

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.
@@ -2,14 +2,14 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
4
  var _excluded = ["children", "width", "height", "maxWidth", "maxHeight", "minWidth", "minHeight", "overflow", "onClose", "theme", "visible", "overlayID", "modalID", "headerContent", "footerContent"];
5
- import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
6
6
  import ReactDOM from "react-dom";
7
7
  import useOnclickOutside from "react-cool-onclickoutside";
8
8
  import PropTypes from "prop-types";
9
9
  import styled, { keyframes, ThemeProvider } from "styled-components";
10
+ import FocusTrap from "focus-trap-react";
10
11
  import { css } from "@styled-system/css";
11
12
  import { themeGet } from "@styled-system/theme-get";
12
- import { commonKeys } from "../../hooks/keypress";
13
13
  import Icon from "../Icon";
14
14
  import Button from "../Button";
15
15
  import Flex from "../Flex";
@@ -74,18 +74,6 @@ var ScrollableContent = styled.div.withConfig({
74
74
  var isHidden = function isHidden(el) {
75
75
  return window.getComputedStyle(el).display === "none";
76
76
  };
77
- var makeRootNotFocusable = function makeRootNotFocusable() {
78
- var root = document.getElementById("root");
79
- root === null || root === void 0 || root.setAttribute("aria-hidden", true);
80
- root === null || root === void 0 || root.setAttribute("inert", true);
81
- };
82
-
83
- // Make root focusable again
84
- var makeRootFocusable = function makeRootFocusable() {
85
- var root = document.getElementById("root");
86
- root === null || root === void 0 || root.removeAttribute("aria-hidden");
87
- root === null || root === void 0 || root.removeAttribute("inert");
88
- };
89
77
  var Modal = function Modal(_ref) {
90
78
  var children = _ref.children,
91
79
  width = _ref.width,
@@ -103,6 +91,10 @@ var Modal = function Modal(_ref) {
103
91
  headerContent = _ref.headerContent,
104
92
  footerContent = _ref.footerContent,
105
93
  restProps = _objectWithoutProperties(_ref, _excluded);
94
+ var _useState = useState(null),
95
+ _useState2 = _slicedToArray(_useState, 2),
96
+ lastActiveElement = _useState2[0],
97
+ setLastActiveElement = _useState2[1];
106
98
  var options = {
107
99
  disabled: !visible
108
100
  };
@@ -116,62 +108,37 @@ var Modal = function Modal(_ref) {
116
108
  return headerContent;
117
109
  }
118
110
  }, [restProps.ariaLabel, headerContent]);
119
-
120
- // Initial focus point for keyboard navigation
121
- var modalContainerRef = useRef();
122
-
123
- // If bottom becomes focused then re-focus the close button
124
-
125
- // Ref to close button
126
- var button = useRef();
127
- var _useState = useState(null),
128
- _useState2 = _slicedToArray(_useState, 2),
129
- lastActiveElement = _useState2[0],
130
- setLastActiveElement = _useState2[1];
131
- var setFocus = useCallback(function () {
132
- var autoFocusable = modalContainerRef.current.querySelector("*[autofocus='true']");
133
- var firstInput = modalContainerRef.current.querySelectorAll("input")[0];
134
- if (autoFocusable) {
135
- autoFocusable.focus();
111
+ var focusLastActiveElement = useCallback(function () {
112
+ if (!lastActiveElement) return;
113
+ if (lastActiveElement !== null && lastActiveElement !== void 0 && lastActiveElement.dataset.actionMenuId && isHidden(lastActiveElement === null || lastActiveElement === void 0 ? void 0 : lastActiveElement.parentNode)) {
114
+ var actionMenu = document.getElementById(lastActiveElement.dataset.actionMenuId);
115
+ actionMenu.focus();
136
116
  } else {
137
- firstInput === null || firstInput === void 0 || firstInput.focus();
117
+ lastActiveElement.focus();
138
118
  }
139
- }, [modalContainerRef]);
119
+ }, [lastActiveElement]);
140
120
 
141
121
  // On becoming visible focus the top
142
122
  useEffect(function () {
143
- if (visible) {
123
+ if (visible && !lastActiveElement) {
144
124
  // Keep track of last clicked element to refocus to after dialog closes
145
125
  setLastActiveElement(document.activeElement);
126
+ } else {
127
+ setLastActiveElement(null);
146
128
 
147
- // Prevents tabbing of elements underneath modal overlay
148
- makeRootNotFocusable();
149
-
150
- // See function
151
- setFocus();
152
- } else if (!visible) {
153
- makeRootFocusable();
129
+ // Focus the last active element before modal open when modal is closed
130
+ focusLastActiveElement();
154
131
  }
155
- }, [visible, setFocus]);
132
+ }, [visible, focusLastActiveElement, lastActiveElement]);
156
133
  var component = /*#__PURE__*/React.createElement(Overlay, _extends({
157
134
  alignItems: "center",
158
135
  justifyContent: "center",
159
- onKeyUp: function onKeyUp(e) {
160
- e.stopPropagation();
161
- if ([commonKeys.ESCAPE, commonKeys.ESC].includes(e.key)) {
162
- onClose();
163
- makeRootFocusable();
164
- if (lastActiveElement !== null && lastActiveElement !== void 0 && lastActiveElement.dataset.actionMenuId && isHidden(lastActiveElement === null || lastActiveElement === void 0 ? void 0 : lastActiveElement.parentNode)) {
165
- var actionMenu = document.getElementById(lastActiveElement.dataset.actionMenuId);
166
- actionMenu.focus();
167
- } else {
168
- // Else we can focus the actual last focused element
169
- lastActiveElement.focus();
170
- }
171
- }
172
- },
173
136
  id: overlayID
174
- }, restProps), /*#__PURE__*/React.createElement("div", {
137
+ }, restProps), visible && /*#__PURE__*/React.createElement(FocusTrap, {
138
+ focusTrapOptions: {
139
+ onDeactivate: onClose
140
+ }
141
+ }, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
175
142
  ref: modalRef,
176
143
  role: "dialog",
177
144
  "aria-modal": "true",
@@ -187,13 +154,11 @@ var Modal = function Modal(_ref) {
187
154
  borderRadius: "2",
188
155
  bg: "white",
189
156
  p: "r",
190
- id: modalID,
191
- ref: modalContainerRef
157
+ id: modalID
192
158
  }, headerContent ? /*#__PURE__*/React.createElement(HeaderContent, null, /*#__PURE__*/React.createElement(Box, {
193
159
  mr: "xl",
194
160
  width: "100%"
195
161
  }, headerContent), /*#__PURE__*/React.createElement(CloseButton, {
196
- ref: button,
197
162
  onClick: onClose,
198
163
  className: "modal-close",
199
164
  small: true,
@@ -204,7 +169,6 @@ var Modal = function Modal(_ref) {
204
169
  color: "greyDark",
205
170
  size: "lg"
206
171
  }))) : /*#__PURE__*/React.createElement(CloseButton, {
207
- ref: button,
208
172
  onClick: onClose,
209
173
  className: "modal-close",
210
174
  small: true,
@@ -217,7 +181,7 @@ var Modal = function Modal(_ref) {
217
181
  })), /*#__PURE__*/React.createElement(ScrollableContent, {
218
182
  headerContent: headerContent,
219
183
  overflow: overflow
220
- }, children), footerContent && /*#__PURE__*/React.createElement(FooterContent, null, footerContent))));
184
+ }, children), footerContent && /*#__PURE__*/React.createElement(FooterContent, null, footerContent))))));
221
185
  var wrapper = visible && /*#__PURE__*/ReactDOM.createPortal(theme ? /*#__PURE__*/React.createElement(ThemeProvider, {
222
186
  theme: theme
223
187
  }, component) : component, document.body);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orcs-design-system",
3
- "version": "3.1.29",
3
+ "version": "3.1.31",
4
4
  "engines": {
5
5
  "node": "18.17.1"
6
6
  },
@@ -47,6 +47,7 @@
47
47
  "@styled-system/prop-types": "^5.1.5",
48
48
  "@styled-system/should-forward-prop": "^5.1.5",
49
49
  "@styled-system/theme-get": "^5.1.2",
50
+ "focus-trap-react": "^10.2.3",
50
51
  "moment": "^2.29.4",
51
52
  "polished": "^3.7.1",
52
53
  "prop-types": "^15.6.2",