colibri-ui 0.8.81 → 0.8.82

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/Modal/index.js CHANGED
@@ -4,18 +4,18 @@ var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
5
5
  var React = require('react');
6
6
  var clsx = require('clsx');
7
- var index$5 = require('../hooks/useScrollLock/index.js');
8
- var index$6 = require('../hooks/useTrapFocus/index.js');
9
- var index$9 = require('../Portal/index.js');
7
+ var index$6 = require('../hooks/useScrollLock/index.js');
8
+ var index$7 = require('../hooks/useTrapFocus/index.js');
9
+ var index$5 = require('../hooks/useModalStack/index.js');
10
+ var index$a = require('../Portal/index.js');
10
11
  var index$4 = require('../hooks/useMediaSizes/index.js');
11
12
  var index = require('./components/Body/index.js');
12
- var index$7 = require('./components/Close/index.js');
13
- var index$8 = require('./components/Content/index.js');
13
+ var index$8 = require('./components/Close/index.js');
14
+ var index$9 = require('./components/Content/index.js');
14
15
  var index$1 = require('./components/Footer/index.js');
15
16
  var index$2 = require('./components/Header/index.js');
16
17
  var index$3 = require('./components/Title/index.js');
17
18
  var context = require('./context.js');
18
- var useModalStack = require('./useModalStack.js');
19
19
  var styles = require('./Modal.module.css');
20
20
 
21
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -58,9 +58,9 @@ var ModalRoot = function ModalRoot(_ref) {
58
58
  _useState4 = _slicedToArray__default.default(_useState3, 2),
59
59
  titleCount = _useState4[0],
60
60
  setTitleCount = _useState4[1];
61
- var isTopmost = useModalStack.useModalStack(titleId);
62
- index$5.useScrollLock();
63
- index$6.useTrapFocus(modalRef, isTopmost);
61
+ var isTopmost = index$5.useModalStack(titleId);
62
+ index$6.useScrollLock();
63
+ index$7.useTrapFocus(modalRef, isTopmost);
64
64
  var handleClose = React.useCallback(function () {
65
65
  onClose === null || onClose === void 0 ? void 0 : onClose();
66
66
  }, [onClose]);
@@ -93,7 +93,9 @@ var ModalRoot = function ModalRoot(_ref) {
93
93
  }, [handleClose]);
94
94
  React.useEffect(function () {
95
95
  var handleEscape = function handleEscape(event) {
96
- if (event.key === "Escape" && isTopmost()) {
96
+ // A layer that closed on this Escape already called preventDefault.
97
+ if (event.key === "Escape" && !event.defaultPrevented && isTopmost()) {
98
+ event.preventDefault();
97
99
  handleClose();
98
100
  }
99
101
  };
@@ -105,7 +107,7 @@ var ModalRoot = function ModalRoot(_ref) {
105
107
  var isCompound = React.Children.toArray(children).some(isCompoundPart);
106
108
  var standaloneClose = /*#__PURE__*/React__default.default.createElement("div", {
107
109
  className: styles__default.default["close-wrapper"]
108
- }, /*#__PURE__*/React__default.default.createElement(index$7.Close, {
110
+ }, /*#__PURE__*/React__default.default.createElement(index$8.Close, {
109
111
  onClick: handleClose,
110
112
  "aria-label": "Close modal"
111
113
  }));
@@ -113,11 +115,11 @@ var ModalRoot = function ModalRoot(_ref) {
113
115
  if (isCompound) {
114
116
  content = /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, !hasHeader(children) && standaloneClose, children);
115
117
  } else {
116
- content = /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, title ? (/*#__PURE__*/React__default.default.createElement(index$2.Header, null, /*#__PURE__*/React__default.default.createElement(index$3.Title, null, title))) : standaloneClose, /*#__PURE__*/React__default.default.createElement(index$8.Content, null, children));
118
+ content = /*#__PURE__*/React__default.default.createElement(React__default.default.Fragment, null, title ? (/*#__PURE__*/React__default.default.createElement(index$2.Header, null, /*#__PURE__*/React__default.default.createElement(index$3.Title, null, title))) : standaloneClose, /*#__PURE__*/React__default.default.createElement(index$9.Content, null, children));
117
119
  }
118
120
  // Wait for the parent window node instead of flashing in document.body.
119
121
  if (withinParent && parentModal && !parentContainer) return null;
120
- return /*#__PURE__*/React__default.default.createElement(index$9.Portal, {
122
+ return /*#__PURE__*/React__default.default.createElement(index$a.Portal, {
121
123
  node: parentContainer
122
124
  }, /*#__PURE__*/React__default.default.createElement(context.ModalContext.Provider, {
123
125
  value: contextValue
package/Sheet/Sheet.js CHANGED
@@ -6,6 +6,7 @@ var tslib = require('tslib');
6
6
  var React = require('react');
7
7
  var ReactDOM = require('react-dom');
8
8
  var clsx = require('clsx');
9
+ var index = require('../hooks/useModalStack/index.js');
9
10
  var styles = require('./Sheet.module.css');
10
11
 
11
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -97,6 +98,7 @@ var Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwardedR
97
98
  });
98
99
  var titleId = React.useId();
99
100
  var descriptionId = React.useId();
101
+ var isTopmost = index.useModalStack(titleId, open && modal);
100
102
  var setPanelRef = function setPanelRef(node) {
101
103
  panelRef.current = node;
102
104
  if (typeof forwardedRef === "function") forwardedRef(node);else if (forwardedRef) forwardedRef.current = node;
@@ -141,6 +143,7 @@ var Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwardedR
141
143
  (_d = (_c = (_b = initialFocusRef === null || initialFocusRef === void 0 ? void 0 : initialFocusRef.current) !== null && _b !== void 0 ? _b : first) !== null && _c !== void 0 ? _c : panelRef.current) === null || _d === void 0 ? void 0 : _d.focus();
142
144
  });
143
145
  var onKeyDown = function onKeyDown(event) {
146
+ if (event.defaultPrevented || !isTopmost()) return;
144
147
  if (event.key === "Escape" && closeOnEscape) {
145
148
  event.preventDefault();
146
149
  onOpenChange(false, "escape");
@@ -170,7 +173,7 @@ var Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwardedR
170
173
  if (modal && lockBodyScroll) document.body.style.overflow = previousOverflow;
171
174
  returnFocusElement === null || returnFocusElement === void 0 ? void 0 : returnFocusElement.focus();
172
175
  };
173
- }, [open, modal, lockBodyScroll, closeOnEscape, onOpenChange, initialFocusRef, returnFocusRef]);
176
+ }, [open, modal, lockBodyScroll, closeOnEscape, onOpenChange, initialFocusRef, returnFocusRef, isTopmost]);
174
177
  var startDrag = function startDrag(event) {
175
178
  if (!draggable || !panelRef.current) return;
176
179
  event.currentTarget.setPointerCapture(event.pointerId);
@@ -4,6 +4,7 @@ import React, { useRef, useState, useContext, useId, useCallback, useMemo, useEf
4
4
  import clsx from 'clsx';
5
5
  import { useScrollLock } from '../hooks/useScrollLock/index.js';
6
6
  import { useTrapFocus } from '../hooks/useTrapFocus/index.js';
7
+ import { useModalStack } from '../hooks/useModalStack/index.js';
7
8
  import { Portal } from '../Portal/index.js';
8
9
  import { useMediaSizes } from '../hooks/useMediaSizes/index.js';
9
10
  import { Body } from './components/Body/index.js';
@@ -13,7 +14,6 @@ import { Footer } from './components/Footer/index.js';
13
14
  import { Header } from './components/Header/index.js';
14
15
  import { Title } from './components/Title/index.js';
15
16
  import { ModalContext } from './context.js';
16
- import { useModalStack } from './useModalStack.js';
17
17
  import styles from './Modal.module.css';
18
18
 
19
19
  var compoundParts = [Header, Body, Footer];
@@ -83,7 +83,9 @@ var ModalRoot = function ModalRoot(_ref) {
83
83
  }, [handleClose]);
84
84
  useEffect(function () {
85
85
  var handleEscape = function handleEscape(event) {
86
- if (event.key === "Escape" && isTopmost()) {
86
+ // A layer that closed on this Escape already called preventDefault.
87
+ if (event.key === "Escape" && !event.defaultPrevented && isTopmost()) {
88
+ event.preventDefault();
87
89
  handleClose();
88
90
  }
89
91
  };
@@ -4,6 +4,7 @@ import { __rest } from 'tslib';
4
4
  import React, { forwardRef, useState, useRef, useId, useMemo, useEffect } from 'react';
5
5
  import { createPortal } from 'react-dom';
6
6
  import clsx from 'clsx';
7
+ import { useModalStack } from '../hooks/useModalStack/index.js';
7
8
  import styles from './Sheet.module.css';
8
9
 
9
10
  var defaultSnapPoints = ["60dvh"];
@@ -87,6 +88,7 @@ var Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef) {
87
88
  });
88
89
  var titleId = useId();
89
90
  var descriptionId = useId();
91
+ var isTopmost = useModalStack(titleId, open && modal);
90
92
  var setPanelRef = function setPanelRef(node) {
91
93
  panelRef.current = node;
92
94
  if (typeof forwardedRef === "function") forwardedRef(node);else if (forwardedRef) forwardedRef.current = node;
@@ -131,6 +133,7 @@ var Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef) {
131
133
  (_d = (_c = (_b = initialFocusRef === null || initialFocusRef === void 0 ? void 0 : initialFocusRef.current) !== null && _b !== void 0 ? _b : first) !== null && _c !== void 0 ? _c : panelRef.current) === null || _d === void 0 ? void 0 : _d.focus();
132
134
  });
133
135
  var onKeyDown = function onKeyDown(event) {
136
+ if (event.defaultPrevented || !isTopmost()) return;
134
137
  if (event.key === "Escape" && closeOnEscape) {
135
138
  event.preventDefault();
136
139
  onOpenChange(false, "escape");
@@ -160,7 +163,7 @@ var Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef) {
160
163
  if (modal && lockBodyScroll) document.body.style.overflow = previousOverflow;
161
164
  returnFocusElement === null || returnFocusElement === void 0 ? void 0 : returnFocusElement.focus();
162
165
  };
163
- }, [open, modal, lockBodyScroll, closeOnEscape, onOpenChange, initialFocusRef, returnFocusRef]);
166
+ }, [open, modal, lockBodyScroll, closeOnEscape, onOpenChange, initialFocusRef, returnFocusRef, isTopmost]);
164
167
  var startDrag = function startDrag(event) {
165
168
  if (!draggable || !panelRef.current) return;
166
169
  event.currentTarget.setPointerCapture(event.pointerId);
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tracks open modals so only the topmost one reacts to Escape and Tab.
3
+ * An inactive entry is not registered and counts as topmost only while no
4
+ * modal is open.
5
+ */
6
+ export declare const useModalStack: (id: string, active?: boolean) => () => boolean;
@@ -0,0 +1,24 @@
1
+ import { useEffect, useCallback } from 'react';
2
+
3
+ var stack = [];
4
+ /**
5
+ * Tracks open modals so only the topmost one reacts to Escape and Tab.
6
+ * An inactive entry is not registered and counts as topmost only while no
7
+ * modal is open.
8
+ */
9
+ var useModalStack = function useModalStack(id) {
10
+ var active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
11
+ useEffect(function () {
12
+ if (!active) return;
13
+ stack.push(id);
14
+ return function () {
15
+ var index = stack.lastIndexOf(id);
16
+ if (index !== -1) stack.splice(index, 1);
17
+ };
18
+ }, [id, active]);
19
+ return useCallback(function () {
20
+ return stack.length ? stack[stack.length - 1] === id : !active;
21
+ }, [id, active]);
22
+ };
23
+
24
+ export { useModalStack };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tracks open modals so only the topmost one reacts to Escape and Tab.
3
+ * An inactive entry is not registered and counts as topmost only while no
4
+ * modal is open.
5
+ */
6
+ export declare const useModalStack: (id: string, active?: boolean) => () => boolean;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ var stack = [];
6
+ /**
7
+ * Tracks open modals so only the topmost one reacts to Escape and Tab.
8
+ * An inactive entry is not registered and counts as topmost only while no
9
+ * modal is open.
10
+ */
11
+ var useModalStack = function useModalStack(id) {
12
+ var active = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
13
+ React.useEffect(function () {
14
+ if (!active) return;
15
+ stack.push(id);
16
+ return function () {
17
+ var index = stack.lastIndexOf(id);
18
+ if (index !== -1) stack.splice(index, 1);
19
+ };
20
+ }, [id, active]);
21
+ return React.useCallback(function () {
22
+ return stack.length ? stack[stack.length - 1] === id : !active;
23
+ }, [id, active]);
24
+ };
25
+
26
+ exports.useModalStack = useModalStack;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colibri-ui",
3
- "version": "0.8.81",
3
+ "version": "0.8.82",
4
4
  "description": "React UI components library",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,2 +0,0 @@
1
- /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
2
- export declare const useModalStack: (id: string) => () => boolean;
@@ -1,20 +0,0 @@
1
- 'use strict';
2
-
3
- var React = require('react');
4
-
5
- var stack = [];
6
- /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
7
- var useModalStack = function useModalStack(id) {
8
- React.useEffect(function () {
9
- stack.push(id);
10
- return function () {
11
- var index = stack.lastIndexOf(id);
12
- if (index !== -1) stack.splice(index, 1);
13
- };
14
- }, [id]);
15
- return React.useCallback(function () {
16
- return stack[stack.length - 1] === id;
17
- }, [id]);
18
- };
19
-
20
- exports.useModalStack = useModalStack;
@@ -1,2 +0,0 @@
1
- /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
2
- export declare const useModalStack: (id: string) => () => boolean;
@@ -1,18 +0,0 @@
1
- import { useEffect, useCallback } from 'react';
2
-
3
- var stack = [];
4
- /** Tracks open modals so only the topmost one reacts to Escape and Tab. */
5
- var useModalStack = function useModalStack(id) {
6
- useEffect(function () {
7
- stack.push(id);
8
- return function () {
9
- var index = stack.lastIndexOf(id);
10
- if (index !== -1) stack.splice(index, 1);
11
- };
12
- }, [id]);
13
- return useCallback(function () {
14
- return stack[stack.length - 1] === id;
15
- }, [id]);
16
- };
17
-
18
- export { useModalStack };