orcs-design-system 3.1.27 → 3.1.28

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.
@@ -1,18 +1,20 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
+ import _extends from "@babel/runtime/helpers/extends";
5
5
  var _excluded = ["as"],
6
- _excluded2 = ["theme", "onToggle", "toggleState", "direction", "menuTopPosition", "menuLeftPosition", "menuRightPosition", "menuWidth", "customTriggerComponent", "children", "triggerRef", "ariaLabel"],
7
- _excluded3 = ["children", "customTriggerComponent", "direction", "isOpen", "theme", "closeOnClick", "ariaLabel", "triggerRef"];
6
+ _excluded2 = ["theme", "onToggle", "toggleState", "direction", "menuTopPosition", "menuLeftPosition", "menuRightPosition", "menuWidth", "customTriggerComponent", "children", "ariaLabel", "onTriggerFocus", "closeMenu", "closeOnClick"],
7
+ _excluded3 = ["children", "customTriggerComponent", "direction", "isOpen", "theme", "closeOnClick", "ariaLabel"];
8
8
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
9
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
- import React, { useState, useEffect, useImperativeHandle, useCallback } from "react";
10
+ import React, { useState, useEffect, useImperativeHandle, useCallback, createContext, useContext, useMemo, useRef } from "react";
11
11
  import styled, { css, keyframes, ThemeProvider } from "styled-components";
12
12
  import PropTypes from "prop-types";
13
13
  import { space, layout } from "styled-system";
14
14
  import { themeGet } from "@styled-system/theme-get";
15
15
  import { useKeepInView } from "../../hooks/keepInView";
16
+ import { commonKeys } from "../../hooks/keypress";
17
+ var ActionMenuContext = /*#__PURE__*/createContext({});
16
18
  var crossTransform1 = keyframes(["0%{transform:translate(0,-6px);border-radius:2px;}50%{transform:translate(0,0);border-radius:2px;}75%{transform:rotate(-45deg) translate(0,0);border-radius:2px;}100%{transform:rotate(-45deg) translate(0,0) scaleX(4);border-radius:0;}"]);
17
19
  var crossTransform2 = keyframes(["0%{transform:translate(0,6px);border-radius:2px;}50%{transform:translate(0,0);border-radius:2px;}75%{transform:rotate(45deg) translate(0,0);border-radius:2px;}100%{transform:rotate(45deg) translate(0,0) scaleX(4);border-radius:0;}"]);
18
20
  var Wrapper = styled.div.withConfig({
@@ -65,7 +67,18 @@ var Menu = styled.div.withConfig({
65
67
  }, function (props) {
66
68
  return props.isOpen ? css(["transform:scale(1);opacity:1;pointer-events:auto;"]) : css([""]);
67
69
  });
68
- export var ActionsMenuHeading = styled.div.withConfig({
70
+ export var ActionsMenuHeading = styled(function (props) {
71
+ return /*#__PURE__*/React.createElement("div", _extends({}, props, {
72
+ onKeyUp: function onKeyUp(e) {
73
+ if (e.key === commonKeys.ENTER && props !== null && props !== void 0 && props.canClick) {
74
+ props === null || props === void 0 || props.onClick();
75
+ }
76
+ }
77
+ }));
78
+ }).attrs({
79
+ tabIndex: "0",
80
+ role: "button"
81
+ }).withConfig({
69
82
  displayName: "ActionsMenu__ActionsMenuHeading",
70
83
  componentId: "sc-yvbni2-4"
71
84
  })(["color:", ";padding:8px;width:100%;font-size:", ";font-weight:", ";border-bottom:solid 1px ", ";white-space:nowrap;cursor:", ";"], function (props) {
@@ -80,16 +93,29 @@ export var ActionsMenuHeading = styled.div.withConfig({
80
93
  return props.canClick ? "pointer" : "default";
81
94
  });
82
95
  export var ActionsMenuItem = styled(function (props) {
96
+ var _useContext = useContext(ActionMenuContext),
97
+ id = _useContext.id,
98
+ onItemClick = _useContext.onItemClick;
83
99
  var as = props.as,
84
100
  others = _objectWithoutProperties(props, _excluded);
85
101
  var Component = as ? as : others.href ? "a" : "button";
86
102
  var newProps = others;
103
+ var _newProps = newProps,
104
+ originalOnClick = _newProps.onClick;
105
+ var onClick = useMemo(function () {
106
+ return function (e) {
107
+ onItemClick(e);
108
+ originalOnClick === null || originalOnClick === void 0 || originalOnClick(e);
109
+ };
110
+ }, [originalOnClick, onItemClick]);
87
111
  if (Component === "button") {
88
- newProps = _objectSpread(_objectSpread({}, others), {}, {
112
+ newProps = _objectSpread(_objectSpread({}, others), {}, _defineProperty({
89
113
  type: "button"
90
- });
114
+ }, "data-action-menu-id", id));
91
115
  }
92
- return /*#__PURE__*/React.createElement(Component, newProps);
116
+ return /*#__PURE__*/React.createElement(Component, _extends({}, newProps, {
117
+ onClick: onClick
118
+ }));
93
119
  }).attrs({
94
120
  role: "listitem"
95
121
  }).withConfig({
@@ -135,21 +161,32 @@ export var ActionsMenuBody = function ActionsMenuBody(_ref) {
135
161
  menuWidth = _ref.menuWidth,
136
162
  customTriggerComponent = _ref.customTriggerComponent,
137
163
  children = _ref.children,
138
- triggerRef = _ref.triggerRef,
139
164
  _ref$ariaLabel = _ref.ariaLabel,
140
165
  ariaLabel = _ref$ariaLabel === void 0 ? "Options Menu" : _ref$ariaLabel,
166
+ onTriggerFocus = _ref.onTriggerFocus,
167
+ closeMenu = _ref.closeMenu,
168
+ _ref$closeOnClick = _ref.closeOnClick,
169
+ closeOnClick = _ref$closeOnClick === void 0 ? false : _ref$closeOnClick,
141
170
  props = _objectWithoutProperties(_ref, _excluded2);
142
- var _useState = useState({
171
+ var _useState = useState(false),
172
+ _useState2 = _slicedToArray(_useState, 2),
173
+ isTabbed = _useState2[0],
174
+ setTabbed = _useState2[1];
175
+ var _useState3 = useState("action-menu-".concat(Math.random())),
176
+ _useState4 = _slicedToArray(_useState3, 1),
177
+ id = _useState4[0];
178
+ var wrapperRef = useRef();
179
+ var _useState5 = useState({
143
180
  menuLeftPosition: menuLeftPosition,
144
181
  menuRightPosition: menuRightPosition,
145
182
  menuTopPosition: menuTopPosition
146
183
  }),
147
- _useState2 = _slicedToArray(_useState, 1),
148
- menuPosition = _useState2[0];
149
- var _useState3 = useState(direction),
150
- _useState4 = _slicedToArray(_useState3, 2),
151
- inViewDirection = _useState4[0],
152
- setInViewDirection = _useState4[1];
184
+ _useState6 = _slicedToArray(_useState5, 1),
185
+ menuPosition = _useState6[0];
186
+ var _useState7 = useState(direction),
187
+ _useState8 = _slicedToArray(_useState7, 2),
188
+ inViewDirection = _useState8[0],
189
+ setInViewDirection = _useState8[1];
153
190
  var setMenuPosition = useCallback(function (newDirection) {
154
191
  if (typeof menuLeftPosition !== "undefined" || typeof menuRightPosition !== "undefined") {
155
192
  if (menuPosition.menuLeftPosition) {
@@ -169,28 +206,63 @@ export var ActionsMenuBody = function ActionsMenuBody(_ref) {
169
206
  _useKeepInView2 = _slicedToArray(_useKeepInView, 2),
170
207
  ref = _useKeepInView2[0],
171
208
  setIsShown = _useKeepInView2[1];
172
- var onToggleInView = function onToggleInView(e) {
173
- setIsShown(!toggleState);
174
- onToggle(e);
175
- };
209
+ useEffect(function () {
210
+ setIsShown(toggleState);
211
+ }, [toggleState, setIsShown]);
176
212
  var triggerBtn = null;
213
+ var value = useMemo(function () {
214
+ return {
215
+ id: id,
216
+ onItemClick: function onItemClick(e) {
217
+ if (closeOnClick && !isTabbed) {
218
+ closeMenu(e);
219
+ }
220
+ }
221
+ };
222
+ }, [closeOnClick, isTabbed, closeMenu, id]);
177
223
  if (customTriggerComponent) {
178
224
  triggerBtn = /*#__PURE__*/React.cloneElement(customTriggerComponent, {
179
- onClick: onToggleInView,
225
+ onClick: onToggle,
180
226
  "aria-label": ariaLabel,
181
- "aria-expanded": "".concat(toggleState)
227
+ "aria-expanded": "".concat(toggleState),
228
+ onFocus: onTriggerFocus,
229
+ id: id
182
230
  });
183
231
  } else {
184
232
  triggerBtn = /*#__PURE__*/React.createElement(Control, {
185
233
  "aria-label": ariaLabel,
186
234
  "aria-expanded": "".concat(toggleState),
187
- ref: triggerRef,
188
- onClick: onToggleInView
235
+ onClick: onToggle,
236
+ onFocus: onTriggerFocus,
237
+ id: id
189
238
  }, /*#__PURE__*/React.createElement(Icon, {
190
239
  isOpen: toggleState
191
240
  }));
192
241
  }
193
- var component = /*#__PURE__*/React.createElement(Wrapper, props, triggerBtn, /*#__PURE__*/React.createElement(Menu, {
242
+ var component = /*#__PURE__*/React.createElement(Wrapper, _extends({}, props, {
243
+ ref: wrapperRef,
244
+ onKeyUp: function onKeyUp(e) {
245
+ if ([commonKeys.ESCAPE, commonKeys.ESC].includes(e.key)) {
246
+ closeMenu(e);
247
+ document.getElementById(id).focus();
248
+ }
249
+ if (commonKeys.TAB === e.key && !isTabbed) {
250
+ setTabbed === null || setTabbed === void 0 || setTabbed(true);
251
+ }
252
+ },
253
+ onBlur: function onBlur(e) {
254
+ setTimeout(function () {
255
+ var _document$getElementB;
256
+ var focusedElement = document.activeElement;
257
+ var isChild = wrapperRef.current.contains(focusedElement);
258
+ var isModalChild = (_document$getElementB = document.getElementById("modal-overlay")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.contains(focusedElement);
259
+ var isModalAndTabbed = isTabbed && isModalChild;
260
+ if (isChild || isModalAndTabbed) return;
261
+ setTabbed === null || setTabbed === void 0 || setTabbed(false);
262
+ closeMenu(e);
263
+ }, 0);
264
+ }
265
+ }), triggerBtn, /*#__PURE__*/React.createElement(Menu, {
194
266
  isOpen: toggleState,
195
267
  direction: inViewDirection,
196
268
  menuTopPosition: menuPosition.menuTopPosition,
@@ -199,14 +271,19 @@ export var ActionsMenuBody = function ActionsMenuBody(_ref) {
199
271
  menuWidth: menuWidth,
200
272
  ref: ref,
201
273
  role: "list"
202
- }, children));
274
+ }, /*#__PURE__*/React.createElement(ActionMenuContext.Provider, {
275
+ value: value
276
+ }, children)));
203
277
  return theme ? /*#__PURE__*/React.createElement(ThemeProvider, {
204
278
  theme: theme
205
279
  }, component) : component;
206
280
  };
207
281
  ActionsMenuBody.propTypes = {
282
+ onTriggerFocus: PropTypes.func,
208
283
  onToggle: PropTypes.func.isRequired,
284
+ closeMenu: PropTypes.func.isRequired,
209
285
  toggleState: PropTypes.bool.isRequired,
286
+ closeOnClick: PropTypes.bool,
210
287
  direction: PropTypes.string,
211
288
  menuTopPosition: PropTypes.string,
212
289
  menuLeftPosition: PropTypes.string,
@@ -215,10 +292,7 @@ ActionsMenuBody.propTypes = {
215
292
  customTriggerComponent: PropTypes.node,
216
293
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]),
217
294
  theme: PropTypes.object,
218
- ariaLabel: PropTypes.string,
219
- triggerRef: PropTypes.shape({
220
- current: PropTypes.any
221
- })
295
+ ariaLabel: PropTypes.string
222
296
  };
223
297
  var ActionsMenu = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
224
298
  var children = _ref2.children,
@@ -231,12 +305,11 @@ var ActionsMenu = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
231
305
  closeOnClick = _ref2$closeOnClick === void 0 ? true : _ref2$closeOnClick,
232
306
  _ref2$ariaLabel = _ref2.ariaLabel,
233
307
  ariaLabel = _ref2$ariaLabel === void 0 ? "Options Menu" : _ref2$ariaLabel,
234
- triggerRef = _ref2.triggerRef,
235
308
  props = _objectWithoutProperties(_ref2, _excluded3);
236
- var _useState5 = useState(isOpen),
237
- _useState6 = _slicedToArray(_useState5, 2),
238
- toggleState = _useState6[0],
239
- setToggle = _useState6[1];
309
+ var _useState9 = useState(isOpen),
310
+ _useState10 = _slicedToArray(_useState9, 2),
311
+ toggleState = _useState10[0],
312
+ setToggle = _useState10[1];
240
313
  useImperativeHandle(ref, function () {
241
314
  return {
242
315
  closeMenu: function closeMenu() {
@@ -244,38 +317,23 @@ var ActionsMenu = /*#__PURE__*/React.forwardRef(function (_ref2, ref) {
244
317
  }
245
318
  };
246
319
  });
247
- useEffect(function () {
248
- if (!closeOnClick || !toggleState) {
249
- return;
250
- }
251
- var handleClicked = function handleClicked() {
252
- // As the event listener is attached in capture phase, need to do this make sure the sate change are after react event cycle.
253
- setTimeout(function () {
254
- return setToggle(false);
255
- }, 0);
256
- };
257
-
258
- // handle click to hide menu
259
- // If any of the actions are using stopPropagation(), the event will stop in the react mounting root.
260
- // So use capture phase to detect anything clicked.
261
- document.addEventListener("click", handleClicked, true);
262
- return function () {
263
- // If menu closed, unregister event listener to prevent memory leaks
264
- document.removeEventListener("click", handleClicked, true);
265
- };
266
- }, [closeOnClick, toggleState]);
267
320
  var onToggle = function onToggle(e) {
268
321
  e.stopPropagation();
269
322
  setToggle(!toggleState);
270
323
  };
324
+ var closeMenu = function closeMenu(e) {
325
+ e.stopPropagation();
326
+ setToggle(false);
327
+ };
271
328
  return /*#__PURE__*/React.createElement(ActionsMenuBody, _extends({
272
329
  onToggle: onToggle,
330
+ closeMenu: closeMenu,
273
331
  toggleState: toggleState,
274
332
  customTriggerComponent: customTriggerComponent,
275
333
  direction: direction,
276
334
  theme: theme,
277
335
  ariaLabel: ariaLabel,
278
- triggerRef: triggerRef
336
+ closeOnClick: closeOnClick
279
337
  }, props), children);
280
338
  });
281
339
  ActionsMenu.propTypes = {
@@ -287,10 +345,7 @@ ActionsMenu.propTypes = {
287
345
  /** Specifies the colour theme */
288
346
  theme: PropTypes.object,
289
347
  /** Specifies the aria-label for the button */
290
- ariaLabel: PropTypes.object,
291
- triggerRef: PropTypes.shape({
292
- current: PropTypes.any
293
- })
348
+ ariaLabel: PropTypes.object
294
349
  };
295
350
  ActionsMenu.__docgenInfo = {
296
351
  "description": "",
@@ -365,19 +420,6 @@ ActionsMenu.__docgenInfo = {
365
420
  "name": "object"
366
421
  },
367
422
  "required": false
368
- },
369
- "triggerRef": {
370
- "description": "",
371
- "type": {
372
- "name": "shape",
373
- "value": {
374
- "current": {
375
- "name": "any",
376
- "required": false
377
- }
378
- }
379
- },
380
- "required": false
381
423
  }
382
424
  }
383
425
  };
@@ -398,6 +440,24 @@ ActionsMenuBody.__docgenInfo = {
398
440
  },
399
441
  "required": false
400
442
  },
443
+ "closeOnClick": {
444
+ "defaultValue": {
445
+ "value": "false",
446
+ "computed": false
447
+ },
448
+ "description": "",
449
+ "type": {
450
+ "name": "bool"
451
+ },
452
+ "required": false
453
+ },
454
+ "onTriggerFocus": {
455
+ "description": "",
456
+ "type": {
457
+ "name": "func"
458
+ },
459
+ "required": false
460
+ },
401
461
  "onToggle": {
402
462
  "description": "",
403
463
  "type": {
@@ -405,6 +465,13 @@ ActionsMenuBody.__docgenInfo = {
405
465
  },
406
466
  "required": true
407
467
  },
468
+ "closeMenu": {
469
+ "description": "",
470
+ "type": {
471
+ "name": "func"
472
+ },
473
+ "required": true
474
+ },
408
475
  "toggleState": {
409
476
  "description": "",
410
477
  "type": {
@@ -475,19 +542,6 @@ ActionsMenuBody.__docgenInfo = {
475
542
  "name": "object"
476
543
  },
477
544
  "required": false
478
- },
479
- "triggerRef": {
480
- "description": "",
481
- "type": {
482
- "name": "shape",
483
- "value": {
484
- "current": {
485
- "name": "any",
486
- "required": false
487
- }
488
- }
489
- },
490
- "required": false
491
545
  }
492
546
  }
493
547
  };
@@ -1,5 +1,5 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import React, { useRef, useState } from "react";
2
+ import React, { useState } from "react";
3
3
  import Button from "../Button";
4
4
  import Modal from ".";
5
5
  import { H3, P } from "../Typography";
@@ -17,7 +17,6 @@ var Basic = function Basic() {
17
17
  _useState2 = _slicedToArray(_useState, 2),
18
18
  visible = _useState2[0],
19
19
  setVisible = _useState2[1];
20
- var button = useRef();
21
20
  var handleOnButtonClick = function handleOnButtonClick() {
22
21
  setVisible(true);
23
22
  };
@@ -30,14 +29,12 @@ var Basic = function Basic() {
30
29
  };
31
30
  };
32
31
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
33
- ref: button,
34
32
  onClick: handleOnButtonClick
35
33
  }, "Open basic modal"), /*#__PURE__*/React.createElement(Modal, {
36
34
  ariaLabel: "Modal Name",
37
35
  visible: visible,
38
36
  handleOnConfirm: handleOnConfirm,
39
- onClose: onToggleModal(false),
40
- triggerRef: button
37
+ onClose: onToggleModal(false)
41
38
  }, /*#__PURE__*/React.createElement(Spacer, {
42
39
  mb: "r"
43
40
  }, /*#__PURE__*/React.createElement(H3, null, "Modal Title"), /*#__PURE__*/React.createElement(P, null, "Content of the modal. Modal accepts any child components or content."))));
@@ -48,7 +45,7 @@ export var basicModal = function basicModal() {
48
45
  basicModal.parameters = {
49
46
  docs: {
50
47
  source: {
51
- code: "\nconst Basic = () => {\n const [visible, setVisible] = useState(false);\n const button = useRef();\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n return (\n <>\n <Button ref={button} onClick={handleOnButtonClick}>\n Open basic modal\n </Button>\n <Modal\n ariaLabel=\"Modal Title\"\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n triggerRef={button}\n >\n <Spacer mb=\"r\">\n <H3>Modal Title</H3>\n <P>\n Content of the modal. Modal accepts any child components or content.\n </P>\n </Spacer>\n </Modal>\n </>\n );\n};"
48
+ code: "\nconst Basic = () => {\n const [visible, setVisible] = useState(false);\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n return (\n <>\n <Button onClick={handleOnButtonClick}>\n Open basic modal\n </Button>\n <Modal\n ariaLabel=\"Modal Title\"\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n >\n <Spacer mb=\"r\">\n <H3>Modal Title</H3>\n <P>\n Content of the modal. Modal accepts any child components or content.\n </P>\n </Spacer>\n </Modal>\n </>\n );\n};"
52
49
  }
53
50
  }
54
51
  };
@@ -57,7 +54,6 @@ var Advanced = function Advanced() {
57
54
  _useState4 = _slicedToArray(_useState3, 2),
58
55
  visible = _useState4[0],
59
56
  setVisible = _useState4[1];
60
- var button = useRef();
61
57
  var handleOnButtonClick = function handleOnButtonClick() {
62
58
  setVisible(true);
63
59
  };
@@ -74,7 +70,6 @@ var Advanced = function Advanced() {
74
70
  onClick: handleOnConfirm
75
71
  }, "Go to full article");
76
72
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
77
- ref: button,
78
73
  onClick: handleOnButtonClick
79
74
  }, "Open advanced modal"), /*#__PURE__*/React.createElement(Modal, {
80
75
  maxWidth: "500px",
@@ -85,8 +80,7 @@ var Advanced = function Advanced() {
85
80
  handleOnConfirm: handleOnConfirm,
86
81
  onClose: onToggleModal(false),
87
82
  headerContent: modalHeader,
88
- footerContent: modalFooter,
89
- triggerRef: button
83
+ footerContent: modalFooter
90
84
  }, /*#__PURE__*/React.createElement(Spacer, {
91
85
  my: "r"
92
86
  }, /*#__PURE__*/React.createElement(P, null, "Content of the modal. Modal accepts any child components or content. This content will be scrollable if it exeeds the height of the modal."), /*#__PURE__*/React.createElement(P, null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."), /*#__PURE__*/React.createElement(P, null, "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"))));
@@ -97,7 +91,7 @@ export var advancedModal = function advancedModal() {
97
91
  advancedModal.parameters = {
98
92
  docs: {
99
93
  source: {
100
- code: "\nconst Advanced = () => {\n const [visible, setVisible] = useState(false);\n const button = useRef();\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalHeader = <H3>Modal Title</H3>;\n\n const modalFooter = (\n <Button onClick={handleOnConfirm}>Go to full article</Button>\n );\n\n return (\n <>\n <Button ref={button} onClick={handleOnButtonClick}>\n Open advanced modal\n </Button>\n <Modal\n maxWidth=\"500px\"\n maxHeight=\"400px\"\n height=\"90vh\"\n width=\"90vw\"\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n headerContent={modalHeader}\n footerContent={modalFooter}\n triggerRef={button}\n >\n <Spacer my=\"r\">\n <P>\n Content of the modal. Modal accepts any child components or content.\n This content will be scrollable if it exeeds the height of the\n modal.\n </P>\n <P>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\n ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n aliquip ex ea commodo consequat. Duis aute irure dolor in\n reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\n pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n culpa qui officia deserunt mollit anim id est laborum.\n </P>\n <P>\n Sed ut perspiciatis unde omnis iste natus error sit voluptatem\n accusantium doloremque laudantium, totam rem aperiam, eaque ipsa\n quae ab illo inventore veritatis et quasi architecto beatae vitae\n dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit\n aspernatur aut odit aut fugit, sed quia consequuntur magni dolores\n eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,\n sed quia non numquam eius modi tempora incidunt ut labore et dolore\n magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis\n nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut\n aliquid ex ea commodi consequatur? Quis autem vel eum iure\n reprehenderit qui in ea voluptate velit esse quam nihil molestiae\n consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n </P>\n </Spacer>\n </Modal>\n </>\n );\n};"
94
+ code: "\nconst Advanced = () => {\n const [visible, setVisible] = useState(false);\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalHeader = <H3>Modal Title</H3>;\n\n const modalFooter = (\n <Button onClick={handleOnConfirm}>Go to full article</Button>\n );\n\n return (\n <>\n <Button onClick={handleOnButtonClick}>\n Open advanced modal\n </Button>\n <Modal\n maxWidth=\"500px\"\n maxHeight=\"400px\"\n height=\"90vh\"\n width=\"90vw\"\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n headerContent={modalHeader}\n footerContent={modalFooter}\n >\n <Spacer my=\"r\">\n <P>\n Content of the modal. Modal accepts any child components or content.\n This content will be scrollable if it exeeds the height of the\n modal.\n </P>\n <P>\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim\n ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut\n aliquip ex ea commodo consequat. Duis aute irure dolor in\n reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla\n pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n culpa qui officia deserunt mollit anim id est laborum.\n </P>\n <P>\n Sed ut perspiciatis unde omnis iste natus error sit voluptatem\n accusantium doloremque laudantium, totam rem aperiam, eaque ipsa\n quae ab illo inventore veritatis et quasi architecto beatae vitae\n dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit\n aspernatur aut odit aut fugit, sed quia consequuntur magni dolores\n eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est,\n qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit,\n sed quia non numquam eius modi tempora incidunt ut labore et dolore\n magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis\n nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut\n aliquid ex ea commodi consequatur? Quis autem vel eum iure\n reprehenderit qui in ea voluptate velit esse quam nihil molestiae\n consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla\n pariatur?\n </P>\n </Spacer>\n </Modal>\n </>\n );\n};"
101
95
  }
102
96
  }
103
97
  };
@@ -106,7 +100,6 @@ var BasicDialogue = function BasicDialogue() {
106
100
  _useState6 = _slicedToArray(_useState5, 2),
107
101
  visible = _useState6[0],
108
102
  setVisible = _useState6[1];
109
- var button = useRef();
110
103
  var handleOnButtonClick = function handleOnButtonClick() {
111
104
  setVisible(true);
112
105
  };
@@ -128,7 +121,6 @@ var BasicDialogue = function BasicDialogue() {
128
121
  onClick: onToggleModal(false)
129
122
  }, "Cancel")));
130
123
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
131
- ref: button,
132
124
  onClick: handleOnButtonClick,
133
125
  variant: "danger",
134
126
  iconLeft: true
@@ -138,8 +130,7 @@ var BasicDialogue = function BasicDialogue() {
138
130
  visible: visible,
139
131
  handleOnConfirm: handleOnConfirm,
140
132
  onClose: onToggleModal(false),
141
- footerContent: modalFooter,
142
- triggerRef: button
133
+ footerContent: modalFooter
143
134
  }, /*#__PURE__*/React.createElement(Spacer, {
144
135
  mb: "r"
145
136
  }, /*#__PURE__*/React.createElement(P, {
@@ -153,7 +144,7 @@ export var basicDialogueModal = function basicDialogueModal() {
153
144
  basicDialogueModal.parameters = {
154
145
  docs: {
155
146
  source: {
156
- code: "\nconst BasicDialogue = () => {\n const [visible, setVisible] = useState(false);\n const button = useRef();\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalFooter = (\n <Flex>\n <Spacer mr=\"s\">\n <Button onClick={handleOnConfirm} px=\"l\">\n OK\n </Button>\n <Button variant=\"ghost\" onClick={onToggleModal(false)}>\n Cancel\n </Button>\n </Spacer>\n </Flex>\n );\n\n return (\n <>\n <Button\n ref={button}\n onClick={handleOnButtonClick}\n variant=\"danger\"\n iconLeft\n >\n <Icon icon={[\"fas\", \"trash\"]} />\n Delete data\n </Button>\n <Modal\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n footerContent={modalFooter}\n triggerRef={button}\n >\n <Spacer mb=\"r\">\n <P weight=\"bold\" marginBottom=\"sm\">\n This will remove all data from the application.\n </P>\n <P>Do you wish to continue?</P>\n </Spacer>\n </Modal>\n </>\n );\n};"
147
+ code: "\nconst BasicDialogue = () => {\n const [visible, setVisible] = useState(false);\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalFooter = (\n <Flex>\n <Spacer mr=\"s\">\n <Button onClick={handleOnConfirm} px=\"l\">\n OK\n </Button>\n <Button variant=\"ghost\" onClick={onToggleModal(false)}>\n Cancel\n </Button>\n </Spacer>\n </Flex>\n );\n\n return (\n <>\n <Button\n onClick={handleOnButtonClick}\n variant=\"danger\"\n iconLeft\n >\n <Icon icon={[\"fas\", \"trash\"]} />\n Delete data\n </Button>\n <Modal\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n footerContent={modalFooter}\n >\n <Spacer mb=\"r\">\n <P weight=\"bold\" marginBottom=\"sm\">\n This will remove all data from the application.\n </P>\n <P>Do you wish to continue?</P>\n </Spacer>\n </Modal>\n </>\n );\n};"
157
148
  }
158
149
  }
159
150
  };
@@ -162,7 +153,6 @@ var EditDialogue = function EditDialogue() {
162
153
  _useState8 = _slicedToArray(_useState7, 2),
163
154
  visible = _useState8[0],
164
155
  setVisible = _useState8[1];
165
- var button = useRef();
166
156
  var handleOnButtonClick = function handleOnButtonClick() {
167
157
  setVisible(true);
168
158
  };
@@ -191,7 +181,6 @@ var EditDialogue = function EditDialogue() {
191
181
  icon: ["fas", "times"]
192
182
  }), "Cancel")));
193
183
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
194
- ref: button,
195
184
  onClick: handleOnButtonClick,
196
185
  iconLeft: true
197
186
  }, /*#__PURE__*/React.createElement(Icon, {
@@ -201,8 +190,7 @@ var EditDialogue = function EditDialogue() {
201
190
  handleOnConfirm: handleOnConfirm,
202
191
  onClose: onToggleModal(false),
203
192
  headerContent: modalHeader,
204
- footerContent: modalFooter,
205
- triggerRef: button
193
+ footerContent: modalFooter
206
194
  }, /*#__PURE__*/React.createElement(Spacer, {
207
195
  my: "r"
208
196
  }, /*#__PURE__*/React.createElement(TextInput, {
@@ -224,7 +212,7 @@ export var editDialogueModal = function editDialogueModal() {
224
212
  editDialogueModal.parameters = {
225
213
  docs: {
226
214
  source: {
227
- code: "\nconst EditDialogue = () => {\n const [visible, setVisible] = useState(false);\n const button = useRef();\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalHeader = <H3>Modify Details</H3>;\n\n const modalFooter = (\n <Flex>\n <Spacer mr=\"s\">\n <Button onClick={handleOnConfirm} variant=\"success\" iconLeft>\n <Icon icon={[\"fas\", \"save\"]} />\n Save\n </Button>\n <Button variant=\"ghost\" onClick={onToggleModal(false)} iconLeft>\n <Icon icon={[\"fas\", \"times\"]} />\n Cancel\n </Button>\n </Spacer>\n </Flex>\n );\n return (\n <>\n <Button ref={button} onClick={handleOnButtonClick} iconLeft>\n <Icon icon={[\"fas\", \"edit\"]} />\n Modify Details\n </Button>\n <Modal\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n headerContent={modalHeader}\n footerContent={modalFooter}\n triggerRef={button}\n >\n <Spacer my=\"r\">\n <TextInput\n id=\"textInput1\"\n key=\"textInput1\"\n type=\"text\"\n fullWidth\n label=\"Name\"\n placeholder=\"E.g. Awesome Project\"\n />\n <TextArea id=\"TextArea01\" label=\"Description\" fullWidth />\n </Spacer>\n </Modal>\n </>\n );\n};"
215
+ code: "\nconst EditDialogue = () => {\n const [visible, setVisible] = useState(false);\n\n const handleOnButtonClick = () => {\n setVisible(true);\n };\n\n const handleOnConfirm = () => {\n setVisible(false);\n };\n\n const onToggleModal = (visible) => () => {\n setVisible(visible);\n };\n\n const modalHeader = <H3>Modify Details</H3>;\n\n const modalFooter = (\n <Flex>\n <Spacer mr=\"s\">\n <Button onClick={handleOnConfirm} variant=\"success\" iconLeft>\n <Icon icon={[\"fas\", \"save\"]} />\n Save\n </Button>\n <Button variant=\"ghost\" onClick={onToggleModal(false)} iconLeft>\n <Icon icon={[\"fas\", \"times\"]} />\n Cancel\n </Button>\n </Spacer>\n </Flex>\n );\n return (\n <>\n <Button onClick={handleOnButtonClick} iconLeft>\n <Icon icon={[\"fas\", \"edit\"]} />\n Modify Details\n </Button>\n <Modal\n visible={visible}\n handleOnConfirm={handleOnConfirm}\n onClose={onToggleModal(false)}\n headerContent={modalHeader}\n footerContent={modalFooter}\n >\n <Spacer my=\"r\">\n <TextInput\n id=\"textInput1\"\n key=\"textInput1\"\n type=\"text\"\n fullWidth\n label=\"Name\"\n placeholder=\"E.g. Awesome Project\"\n />\n <TextArea id=\"TextArea01\" label=\"Description\" fullWidth />\n </Spacer>\n </Modal>\n </>\n );\n};"
228
216
  }
229
217
  }
230
218
  };
@@ -1,15 +1,15 @@
1
1
  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
- var _excluded = ["children", "width", "height", "maxWidth", "maxHeight", "minWidth", "minHeight", "overflow", "onClose", "triggerRef", "theme", "visible", "overlayID", "modalID", "headerContent", "footerContent"];
5
- import React, { useEffect, useMemo, useRef, useState } from "react";
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";
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
10
  import { css } from "@styled-system/css";
11
11
  import { themeGet } from "@styled-system/theme-get";
12
- import { commonKeys, useKeyPress } from "../../hooks/keypress";
12
+ import { commonKeys } from "../../hooks/keypress";
13
13
  import Icon from "../Icon";
14
14
  import Button from "../Button";
15
15
  import Flex from "../Flex";
@@ -71,6 +71,21 @@ var ScrollableContent = styled.div.withConfig({
71
71
  }, function (props) {
72
72
  return props.headerContent ? "0" : "20px";
73
73
  });
74
+ var isHidden = function isHidden(el) {
75
+ return window.getComputedStyle(el).display === "none";
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
+ };
74
89
  var Modal = function Modal(_ref) {
75
90
  var children = _ref.children,
76
91
  width = _ref.width,
@@ -81,7 +96,6 @@ var Modal = function Modal(_ref) {
81
96
  minHeight = _ref.minHeight,
82
97
  overflow = _ref.overflow,
83
98
  onClose = _ref.onClose,
84
- triggerRef = _ref.triggerRef,
85
99
  theme = _ref.theme,
86
100
  visible = _ref.visible,
87
101
  overlayID = _ref.overlayID,
@@ -102,49 +116,66 @@ var Modal = function Modal(_ref) {
102
116
  return headerContent;
103
117
  }
104
118
  }, [restProps.ariaLabel, headerContent]);
105
- useKeyPress(commonKeys.ESCAPE, onClose, options);
106
- useKeyPress(commonKeys.ESC, onClose, options);
107
119
 
108
120
  // Initial focus point for keyboard navigation
109
- var top = useRef();
121
+ var modalContainerRef = useRef();
110
122
 
111
123
  // If bottom becomes focused then re-focus the close button
112
- var bottom = useRef();
113
124
 
114
125
  // Ref to close button
115
126
  var button = useRef();
116
-
117
- // Keep trak on whether its been visible
118
- var _useState = useState(visible),
127
+ var _useState = useState(null),
119
128
  _useState2 = _slicedToArray(_useState, 2),
120
- hasOpened = _useState2[0],
121
- setHasOpened = _useState2[1];
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
+ firstInput.focus();
136
+ } else {
137
+ autoFocusable.focus();
138
+ }
139
+ }, [modalContainerRef]);
122
140
 
123
141
  // On becoming visible focus the top
124
142
  useEffect(function () {
125
143
  if (visible) {
126
- top.current.focus();
127
- setHasOpened(true);
128
- } else if (hasOpened) {
129
- triggerRef && triggerRef.current.focus();
144
+ // Keep track of last clicked element to refocus to after dialog closes
145
+ setLastActiveElement(document.activeElement);
146
+
147
+ // Prevents tabbing of elements underneath modal overlay
148
+ makeRootNotFocusable();
149
+
150
+ // See function
151
+ setFocus();
152
+ } else if (!visible) {
153
+ makeRootFocusable();
130
154
  }
131
- }, [visible, hasOpened, top, triggerRef]);
155
+ }, [visible, setFocus]);
132
156
  var component = /*#__PURE__*/React.createElement(Overlay, _extends({
133
157
  alignItems: "center",
134
158
  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
+ },
135
173
  id: overlayID
136
- }, restProps), /*#__PURE__*/React.createElement("span", {
137
- tabIndex: "0",
138
- ref: top,
139
- onFocus: function onFocus() {
140
- return bottom.current.focus();
141
- }
142
- }), /*#__PURE__*/React.createElement("div", {
174
+ }, restProps), /*#__PURE__*/React.createElement("div", {
143
175
  ref: modalRef,
144
176
  role: "dialog",
145
177
  "aria-modal": "true",
146
- "aria-label": ariaLabel,
147
- tabIndex: "-1"
178
+ "aria-label": ariaLabel
148
179
  }, /*#__PURE__*/React.createElement(Container, {
149
180
  width: width,
150
181
  height: height,
@@ -156,7 +187,8 @@ var Modal = function Modal(_ref) {
156
187
  borderRadius: "2",
157
188
  bg: "white",
158
189
  p: "r",
159
- id: modalID
190
+ id: modalID,
191
+ ref: modalContainerRef
160
192
  }, headerContent ? /*#__PURE__*/React.createElement(HeaderContent, null, /*#__PURE__*/React.createElement(Box, {
161
193
  mr: "xl",
162
194
  width: "100%"
@@ -185,15 +217,7 @@ var Modal = function Modal(_ref) {
185
217
  })), /*#__PURE__*/React.createElement(ScrollableContent, {
186
218
  headerContent: headerContent,
187
219
  overflow: overflow
188
- }, children), footerContent && /*#__PURE__*/React.createElement(FooterContent, null, footerContent))), /*#__PURE__*/React.createElement("span", {
189
- ref: bottom,
190
- tabIndex: "-1"
191
- }), /*#__PURE__*/React.createElement("span", {
192
- tabIndex: "0",
193
- onFocus: function onFocus() {
194
- return button.current.focus();
195
- }
196
- }));
220
+ }, children), footerContent && /*#__PURE__*/React.createElement(FooterContent, null, footerContent))));
197
221
  var wrapper = visible && /*#__PURE__*/ReactDOM.createPortal(theme ? /*#__PURE__*/React.createElement(ThemeProvider, {
198
222
  theme: theme
199
223
  }, component) : component, document.body);
@@ -224,10 +248,6 @@ Modal.propTypes = {
224
248
  visible: PropTypes.bool,
225
249
  /** Specifies the function to run on clicking X icon. Ensure that this function will close Modal through the `visible` prop */
226
250
  onClose: PropTypes.func,
227
- /** Required to re-focus keyboard navigation after closing a modal, generally a ref to the button */
228
- triggerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
229
- current: PropTypes.any
230
- })]),
231
251
  /** Specifies whether the Modal overflow is visible or not, default is `hidden`. If height is not enough, vertical scrollbar will be displayed (`overflow-y: auto`) */
232
252
  overflow: PropTypes.string,
233
253
  /** Specifies the id of the overlay element for targeting */
@@ -384,24 +404,6 @@ Modal.__docgenInfo = {
384
404
  },
385
405
  "required": false
386
406
  },
387
- "triggerRef": {
388
- "description": "Required to re-focus keyboard navigation after closing a modal, generally a ref to the button",
389
- "type": {
390
- "name": "union",
391
- "value": [{
392
- "name": "func"
393
- }, {
394
- "name": "shape",
395
- "value": {
396
- "current": {
397
- "name": "any",
398
- "required": false
399
- }
400
- }
401
- }]
402
- },
403
- "required": false
404
- },
405
407
  "overflow": {
406
408
  "description": "Specifies whether the Modal overflow is visible or not, default is `hidden`. If height is not enough, vertical scrollbar will be displayed (`overflow-y: auto`)",
407
409
  "type": {
@@ -11,7 +11,8 @@ export var commonKeys = {
11
11
  ARROW_RIGHT: "ArrowRight",
12
12
  ENTER: "Enter",
13
13
  ESC: "Esc",
14
- ESCAPE: "Escape"
14
+ ESCAPE: "Escape",
15
+ TAB: "Tab"
15
16
  };
16
17
  export var useKeyPress = function useKeyPress(targetKey, callback) {
17
18
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orcs-design-system",
3
- "version": "3.1.27",
3
+ "version": "3.1.28",
4
4
  "engines": {
5
5
  "node": "18.17.1"
6
6
  },