colibri-ui 0.8.87 → 0.8.89
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/Accordion/Accordion.module.css +4 -0
- package/Accordion/index.js +23 -6
- package/Accordion/index.props.d.ts +2 -0
- package/Drawer/Drawer.js +11 -9
- package/Sheet/Sheet.js +8 -8
- package/esm/Accordion/Accordion.module.css +4 -0
- package/esm/Accordion/index.js +24 -7
- package/esm/Accordion/index.props.d.ts +2 -0
- package/esm/Drawer/Drawer.js +11 -9
- package/esm/Sheet/Sheet.js +8 -8
- package/esm/hooks/useLatestRef/index.d.ts +5 -0
- package/esm/hooks/useLatestRef/index.js +15 -0
- package/hooks/useLatestRef/index.d.ts +5 -0
- package/hooks/useLatestRef/index.js +17 -0
- package/package.json +1 -1
package/Accordion/index.js
CHANGED
|
@@ -18,15 +18,29 @@ const Accordion = ({
|
|
|
18
18
|
boldTitle = false,
|
|
19
19
|
children,
|
|
20
20
|
className,
|
|
21
|
-
tabIndex
|
|
21
|
+
tabIndex,
|
|
22
|
+
defaultOpen = false
|
|
22
23
|
}) => {
|
|
23
|
-
const [isOpen, setIsOpen] = React.useState(
|
|
24
|
+
const [isOpen, setIsOpen] = React.useState(defaultOpen);
|
|
24
25
|
const contentRef = React.useRef(null);
|
|
26
|
+
const innerRef = React.useRef(null);
|
|
25
27
|
const toggleAccordion = () => setIsOpen(!isOpen);
|
|
26
|
-
React.
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
React.useLayoutEffect(() => {
|
|
29
|
+
const content = contentRef.current;
|
|
30
|
+
const inner = innerRef.current;
|
|
31
|
+
if (!content || !inner) return;
|
|
32
|
+
if (!isOpen) {
|
|
33
|
+
content.style.blockSize = "0";
|
|
34
|
+
return;
|
|
29
35
|
}
|
|
36
|
+
const updateBlockSize = () => {
|
|
37
|
+
content.style.blockSize = `${inner.scrollHeight}px`;
|
|
38
|
+
};
|
|
39
|
+
updateBlockSize();
|
|
40
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
41
|
+
const observer = new ResizeObserver(updateBlockSize);
|
|
42
|
+
observer.observe(inner);
|
|
43
|
+
return () => observer.disconnect();
|
|
30
44
|
}, [isOpen]);
|
|
31
45
|
return /*#__PURE__*/React__default.default.createElement("div", {
|
|
32
46
|
className: clsx__default.default(styles__default.default.root, className)
|
|
@@ -53,7 +67,10 @@ const Accordion = ({
|
|
|
53
67
|
}))), /*#__PURE__*/React__default.default.createElement("div", {
|
|
54
68
|
ref: contentRef,
|
|
55
69
|
className: styles__default.default.content
|
|
56
|
-
},
|
|
70
|
+
}, /*#__PURE__*/React__default.default.createElement("div", {
|
|
71
|
+
ref: innerRef,
|
|
72
|
+
className: styles__default.default.inner
|
|
73
|
+
}, children)));
|
|
57
74
|
};
|
|
58
75
|
|
|
59
76
|
exports.Accordion = Accordion;
|
package/Drawer/Drawer.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var tslib = require('tslib');
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var ReactDOM = require('react-dom');
|
|
6
|
+
var index = require('../hooks/useLatestRef/index.js');
|
|
6
7
|
var styles = require('./Drawer.module.css');
|
|
7
8
|
|
|
8
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -46,11 +47,11 @@ const Drawer = /*#__PURE__*/React.forwardRef(function DrawerRoot(_a, forwardedRe
|
|
|
46
47
|
const previousFocus = React.useRef(null);
|
|
47
48
|
const [rendered, setRendered] = React.useState(opened);
|
|
48
49
|
const [closing, setClosing] = React.useState(false);
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
// Callbacks from props change on every parent render; effects read them
|
|
51
|
+
// from refs, so focus, scroll lock and the closing timer do not restart.
|
|
52
|
+
const onClosedRef = index.useLatestRef(onClosed);
|
|
53
|
+
const onCloseRef = index.useLatestRef(onClose);
|
|
54
|
+
const onEscKeyDownRef = index.useLatestRef(onEscKeyDown);
|
|
54
55
|
const setPanelRef = element => {
|
|
55
56
|
panelRef.current = element;
|
|
56
57
|
if (typeof forwardedRef === "function") forwardedRef(element);else if (forwardedRef) forwardedRef.current = element;
|
|
@@ -70,7 +71,7 @@ const Drawer = /*#__PURE__*/React.forwardRef(function DrawerRoot(_a, forwardedRe
|
|
|
70
71
|
(_a = onClosedRef.current) === null || _a === void 0 ? void 0 : _a.call(onClosedRef);
|
|
71
72
|
}, 200);
|
|
72
73
|
return () => window.clearTimeout(timeout);
|
|
73
|
-
}, [opened, rendered]);
|
|
74
|
+
}, [onClosedRef, opened, rendered]);
|
|
74
75
|
React.useEffect(() => {
|
|
75
76
|
if (!opened || typeof document === "undefined") return;
|
|
76
77
|
previousFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -83,9 +84,10 @@ const Drawer = /*#__PURE__*/React.forwardRef(function DrawerRoot(_a, forwardedRe
|
|
|
83
84
|
(_d = (_c = (_b = initialFocusRef === null || initialFocusRef === void 0 ? void 0 : initialFocusRef.current) !== null && _b !== void 0 ? _b : firstFocusable) !== null && _c !== void 0 ? _c : panelRef.current) === null || _d === void 0 ? void 0 : _d.focus();
|
|
84
85
|
});
|
|
85
86
|
const handleKeyDown = event => {
|
|
87
|
+
var _a, _b;
|
|
86
88
|
if (event.key === "Escape" && closeOnEsc) {
|
|
87
|
-
|
|
88
|
-
if (!event.defaultPrevented)
|
|
89
|
+
(_a = onEscKeyDownRef.current) === null || _a === void 0 ? void 0 : _a.call(onEscKeyDownRef, event);
|
|
90
|
+
if (!event.defaultPrevented) (_b = onCloseRef.current) === null || _b === void 0 ? void 0 : _b.call(onCloseRef);
|
|
89
91
|
return;
|
|
90
92
|
}
|
|
91
93
|
if (!asModal || event.key !== "Tab" || !panelRef.current) return;
|
|
@@ -113,7 +115,7 @@ const Drawer = /*#__PURE__*/React.forwardRef(function DrawerRoot(_a, forwardedRe
|
|
|
113
115
|
if (asModal) document.body.style.overflow = previousOverflow;
|
|
114
116
|
(_a = focusAfterElement !== null && focusAfterElement !== void 0 ? focusAfterElement : previousFocus.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
115
117
|
};
|
|
116
|
-
}, [opened, asModal, closeOnEsc, focusAfterRef, initialFocusRef,
|
|
118
|
+
}, [opened, asModal, closeOnEsc, focusAfterRef, initialFocusRef, onCloseRef, onEscKeyDownRef]);
|
|
117
119
|
if (!rendered || typeof document === "undefined") return null;
|
|
118
120
|
const sidePlacement = placement === "left" || placement === "right";
|
|
119
121
|
const panelStyle = Object.assign(Object.assign({}, style), {
|
package/Sheet/Sheet.js
CHANGED
|
@@ -4,6 +4,7 @@ var tslib = require('tslib');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var ReactDOM = require('react-dom');
|
|
6
6
|
var clsx = require('clsx');
|
|
7
|
+
var index$1 = require('../hooks/useLatestRef/index.js');
|
|
7
8
|
var index = require('../hooks/useModalStack/index.js');
|
|
8
9
|
var styles = require('./Sheet.module.css');
|
|
9
10
|
|
|
@@ -89,11 +90,10 @@ const Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwarde
|
|
|
89
90
|
if (!controlledSnap) setInternalSnap(next);
|
|
90
91
|
onSnapPointChange === null || onSnapPointChange === void 0 ? void 0 : onSnapPointChange(next);
|
|
91
92
|
};
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}, [onClosed]);
|
|
93
|
+
// Callbacks from props change on every parent render; effects read them
|
|
94
|
+
// from refs, so focus, scroll lock and the closing timer do not restart.
|
|
95
|
+
const onClosedRef = index$1.useLatestRef(onClosed);
|
|
96
|
+
const onOpenChangeRef = index$1.useLatestRef(onOpenChange);
|
|
97
97
|
React.useEffect(() => {
|
|
98
98
|
if (open) {
|
|
99
99
|
setRendered(true);
|
|
@@ -110,7 +110,7 @@ const Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwarde
|
|
|
110
110
|
(_a = onClosedRef.current) === null || _a === void 0 ? void 0 : _a.call(onClosedRef);
|
|
111
111
|
}, Number.isFinite(duration) ? duration : 220);
|
|
112
112
|
return () => window.clearTimeout(timer);
|
|
113
|
-
}, [open, rendered]);
|
|
113
|
+
}, [onClosedRef, open, rendered]);
|
|
114
114
|
React.useEffect(() => {
|
|
115
115
|
var _a;
|
|
116
116
|
if (!open || typeof document === "undefined") return;
|
|
@@ -127,7 +127,7 @@ const Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwarde
|
|
|
127
127
|
if (event.defaultPrevented || !isTopmost()) return;
|
|
128
128
|
if (event.key === "Escape" && closeOnEscape) {
|
|
129
129
|
event.preventDefault();
|
|
130
|
-
|
|
130
|
+
onOpenChangeRef.current(false, "escape");
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
if (!modal || event.key !== "Tab" || !panelRef.current) return;
|
|
@@ -154,7 +154,7 @@ const Sheet = /*#__PURE__*/React.forwardRef(function SheetComponent(_a, forwarde
|
|
|
154
154
|
if (modal && lockBodyScroll) document.body.style.overflow = previousOverflow;
|
|
155
155
|
returnFocusElement === null || returnFocusElement === void 0 ? void 0 : returnFocusElement.focus();
|
|
156
156
|
};
|
|
157
|
-
}, [open, modal, lockBodyScroll, closeOnEscape,
|
|
157
|
+
}, [open, modal, lockBodyScroll, closeOnEscape, onOpenChangeRef, initialFocusRef, returnFocusRef, isTopmost]);
|
|
158
158
|
const startDrag = event => {
|
|
159
159
|
if (!draggable || !panelRef.current) return;
|
|
160
160
|
event.currentTarget.setPointerCapture(event.pointerId);
|
package/esm/Accordion/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef,
|
|
1
|
+
import React, { useState, useRef, useLayoutEffect } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import 'tslib';
|
|
4
4
|
import { Chevron } from '../Icons/Chevron.js';
|
|
@@ -10,15 +10,29 @@ const Accordion = ({
|
|
|
10
10
|
boldTitle = false,
|
|
11
11
|
children,
|
|
12
12
|
className,
|
|
13
|
-
tabIndex
|
|
13
|
+
tabIndex,
|
|
14
|
+
defaultOpen = false
|
|
14
15
|
}) => {
|
|
15
|
-
const [isOpen, setIsOpen] = useState(
|
|
16
|
+
const [isOpen, setIsOpen] = useState(defaultOpen);
|
|
16
17
|
const contentRef = useRef(null);
|
|
18
|
+
const innerRef = useRef(null);
|
|
17
19
|
const toggleAccordion = () => setIsOpen(!isOpen);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
useLayoutEffect(() => {
|
|
21
|
+
const content = contentRef.current;
|
|
22
|
+
const inner = innerRef.current;
|
|
23
|
+
if (!content || !inner) return;
|
|
24
|
+
if (!isOpen) {
|
|
25
|
+
content.style.blockSize = "0";
|
|
26
|
+
return;
|
|
21
27
|
}
|
|
28
|
+
const updateBlockSize = () => {
|
|
29
|
+
content.style.blockSize = `${inner.scrollHeight}px`;
|
|
30
|
+
};
|
|
31
|
+
updateBlockSize();
|
|
32
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
33
|
+
const observer = new ResizeObserver(updateBlockSize);
|
|
34
|
+
observer.observe(inner);
|
|
35
|
+
return () => observer.disconnect();
|
|
22
36
|
}, [isOpen]);
|
|
23
37
|
return /*#__PURE__*/React.createElement("div", {
|
|
24
38
|
className: clsx(styles.root, className)
|
|
@@ -45,7 +59,10 @@ const Accordion = ({
|
|
|
45
59
|
}))), /*#__PURE__*/React.createElement("div", {
|
|
46
60
|
ref: contentRef,
|
|
47
61
|
className: styles.content
|
|
48
|
-
},
|
|
62
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
63
|
+
ref: innerRef,
|
|
64
|
+
className: styles.inner
|
|
65
|
+
}, children)));
|
|
49
66
|
};
|
|
50
67
|
|
|
51
68
|
export { Accordion };
|
package/esm/Drawer/Drawer.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { __rest } from 'tslib';
|
|
2
2
|
import React, { forwardRef, useRef, useState, useEffect } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
|
+
import { useLatestRef } from '../hooks/useLatestRef/index.js';
|
|
4
5
|
import styles from './Drawer.module.css';
|
|
5
6
|
|
|
6
7
|
const cx = (...classNames) => classNames.filter(Boolean).join(" ");
|
|
@@ -39,11 +40,11 @@ const Drawer = /*#__PURE__*/forwardRef(function DrawerRoot(_a, forwardedRef) {
|
|
|
39
40
|
const previousFocus = useRef(null);
|
|
40
41
|
const [rendered, setRendered] = useState(opened);
|
|
41
42
|
const [closing, setClosing] = useState(false);
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// Callbacks from props change on every parent render; effects read them
|
|
44
|
+
// from refs, so focus, scroll lock and the closing timer do not restart.
|
|
45
|
+
const onClosedRef = useLatestRef(onClosed);
|
|
46
|
+
const onCloseRef = useLatestRef(onClose);
|
|
47
|
+
const onEscKeyDownRef = useLatestRef(onEscKeyDown);
|
|
47
48
|
const setPanelRef = element => {
|
|
48
49
|
panelRef.current = element;
|
|
49
50
|
if (typeof forwardedRef === "function") forwardedRef(element);else if (forwardedRef) forwardedRef.current = element;
|
|
@@ -63,7 +64,7 @@ const Drawer = /*#__PURE__*/forwardRef(function DrawerRoot(_a, forwardedRef) {
|
|
|
63
64
|
(_a = onClosedRef.current) === null || _a === void 0 ? void 0 : _a.call(onClosedRef);
|
|
64
65
|
}, 200);
|
|
65
66
|
return () => window.clearTimeout(timeout);
|
|
66
|
-
}, [opened, rendered]);
|
|
67
|
+
}, [onClosedRef, opened, rendered]);
|
|
67
68
|
useEffect(() => {
|
|
68
69
|
if (!opened || typeof document === "undefined") return;
|
|
69
70
|
previousFocus.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
@@ -76,9 +77,10 @@ const Drawer = /*#__PURE__*/forwardRef(function DrawerRoot(_a, forwardedRef) {
|
|
|
76
77
|
(_d = (_c = (_b = initialFocusRef === null || initialFocusRef === void 0 ? void 0 : initialFocusRef.current) !== null && _b !== void 0 ? _b : firstFocusable) !== null && _c !== void 0 ? _c : panelRef.current) === null || _d === void 0 ? void 0 : _d.focus();
|
|
77
78
|
});
|
|
78
79
|
const handleKeyDown = event => {
|
|
80
|
+
var _a, _b;
|
|
79
81
|
if (event.key === "Escape" && closeOnEsc) {
|
|
80
|
-
|
|
81
|
-
if (!event.defaultPrevented)
|
|
82
|
+
(_a = onEscKeyDownRef.current) === null || _a === void 0 ? void 0 : _a.call(onEscKeyDownRef, event);
|
|
83
|
+
if (!event.defaultPrevented) (_b = onCloseRef.current) === null || _b === void 0 ? void 0 : _b.call(onCloseRef);
|
|
82
84
|
return;
|
|
83
85
|
}
|
|
84
86
|
if (!asModal || event.key !== "Tab" || !panelRef.current) return;
|
|
@@ -106,7 +108,7 @@ const Drawer = /*#__PURE__*/forwardRef(function DrawerRoot(_a, forwardedRef) {
|
|
|
106
108
|
if (asModal) document.body.style.overflow = previousOverflow;
|
|
107
109
|
(_a = focusAfterElement !== null && focusAfterElement !== void 0 ? focusAfterElement : previousFocus.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
108
110
|
};
|
|
109
|
-
}, [opened, asModal, closeOnEsc, focusAfterRef, initialFocusRef,
|
|
111
|
+
}, [opened, asModal, closeOnEsc, focusAfterRef, initialFocusRef, onCloseRef, onEscKeyDownRef]);
|
|
110
112
|
if (!rendered || typeof document === "undefined") return null;
|
|
111
113
|
const sidePlacement = placement === "left" || placement === "right";
|
|
112
114
|
const panelStyle = Object.assign(Object.assign({}, style), {
|
package/esm/Sheet/Sheet.js
CHANGED
|
@@ -2,6 +2,7 @@ import { __rest } from 'tslib';
|
|
|
2
2
|
import React, { forwardRef, useState, useRef, useId, useMemo, useEffect } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
|
+
import { useLatestRef } from '../hooks/useLatestRef/index.js';
|
|
5
6
|
import { useModalStack } from '../hooks/useModalStack/index.js';
|
|
6
7
|
import styles from './Sheet.module.css';
|
|
7
8
|
|
|
@@ -81,11 +82,10 @@ const Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef)
|
|
|
81
82
|
if (!controlledSnap) setInternalSnap(next);
|
|
82
83
|
onSnapPointChange === null || onSnapPointChange === void 0 ? void 0 : onSnapPointChange(next);
|
|
83
84
|
};
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}, [onClosed]);
|
|
85
|
+
// Callbacks from props change on every parent render; effects read them
|
|
86
|
+
// from refs, so focus, scroll lock and the closing timer do not restart.
|
|
87
|
+
const onClosedRef = useLatestRef(onClosed);
|
|
88
|
+
const onOpenChangeRef = useLatestRef(onOpenChange);
|
|
89
89
|
useEffect(() => {
|
|
90
90
|
if (open) {
|
|
91
91
|
setRendered(true);
|
|
@@ -102,7 +102,7 @@ const Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef)
|
|
|
102
102
|
(_a = onClosedRef.current) === null || _a === void 0 ? void 0 : _a.call(onClosedRef);
|
|
103
103
|
}, Number.isFinite(duration) ? duration : 220);
|
|
104
104
|
return () => window.clearTimeout(timer);
|
|
105
|
-
}, [open, rendered]);
|
|
105
|
+
}, [onClosedRef, open, rendered]);
|
|
106
106
|
useEffect(() => {
|
|
107
107
|
var _a;
|
|
108
108
|
if (!open || typeof document === "undefined") return;
|
|
@@ -119,7 +119,7 @@ const Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef)
|
|
|
119
119
|
if (event.defaultPrevented || !isTopmost()) return;
|
|
120
120
|
if (event.key === "Escape" && closeOnEscape) {
|
|
121
121
|
event.preventDefault();
|
|
122
|
-
|
|
122
|
+
onOpenChangeRef.current(false, "escape");
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
125
|
if (!modal || event.key !== "Tab" || !panelRef.current) return;
|
|
@@ -146,7 +146,7 @@ const Sheet = /*#__PURE__*/forwardRef(function SheetComponent(_a, forwardedRef)
|
|
|
146
146
|
if (modal && lockBodyScroll) document.body.style.overflow = previousOverflow;
|
|
147
147
|
returnFocusElement === null || returnFocusElement === void 0 ? void 0 : returnFocusElement.focus();
|
|
148
148
|
};
|
|
149
|
-
}, [open, modal, lockBodyScroll, closeOnEscape,
|
|
149
|
+
}, [open, modal, lockBodyScroll, closeOnEscape, onOpenChangeRef, initialFocusRef, returnFocusRef, isTopmost]);
|
|
150
150
|
const startDrag = event => {
|
|
151
151
|
if (!draggable || !panelRef.current) return;
|
|
152
152
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Keeps the latest value in a ref. Effects read callbacks from it, so a new
|
|
5
|
+
* inline callback from the parent does not restart them.
|
|
6
|
+
*/
|
|
7
|
+
const useLatestRef = value => {
|
|
8
|
+
const ref = useRef(value);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
ref.current = value;
|
|
11
|
+
}, [value]);
|
|
12
|
+
return ref;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { useLatestRef };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keeps the latest value in a ref. Effects read callbacks from it, so a new
|
|
7
|
+
* inline callback from the parent does not restart them.
|
|
8
|
+
*/
|
|
9
|
+
const useLatestRef = value => {
|
|
10
|
+
const ref = React.useRef(value);
|
|
11
|
+
React.useEffect(() => {
|
|
12
|
+
ref.current = value;
|
|
13
|
+
}, [value]);
|
|
14
|
+
return ref;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.useLatestRef = useLatestRef;
|