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 +15 -13
- package/Sheet/Sheet.js +4 -1
- package/esm/Modal/index.js +4 -2
- package/esm/Sheet/Sheet.js +4 -1
- package/esm/hooks/useModalStack/index.d.ts +6 -0
- package/esm/hooks/useModalStack/index.js +24 -0
- package/hooks/useModalStack/index.d.ts +6 -0
- package/hooks/useModalStack/index.js +26 -0
- package/package.json +1 -1
- package/Modal/useModalStack.d.ts +0 -2
- package/Modal/useModalStack.js +0 -20
- package/esm/Modal/useModalStack.d.ts +0 -2
- package/esm/Modal/useModalStack.js +0 -18
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$
|
|
8
|
-
var index$
|
|
9
|
-
var index$
|
|
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$
|
|
13
|
-
var index$
|
|
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 =
|
|
62
|
-
index$
|
|
63
|
-
index$
|
|
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
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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);
|
package/esm/Modal/index.js
CHANGED
|
@@ -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
|
-
|
|
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
|
};
|
package/esm/Sheet/Sheet.js
CHANGED
|
@@ -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,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,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
package/Modal/useModalStack.d.ts
DELETED
package/Modal/useModalStack.js
DELETED
|
@@ -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,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 };
|