colibri-ui 0.8.87 → 0.8.88

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/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
- // The latest callback without restarting the closing timer.
50
- const onClosedRef = React.useRef(onClosed);
51
- React.useEffect(() => {
52
- onClosedRef.current = onClosed;
53
- }, [onClosed]);
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
- onEscKeyDown === null || onEscKeyDown === void 0 ? void 0 : onEscKeyDown(event);
88
- if (!event.defaultPrevented) onClose === null || onClose === void 0 ? void 0 : onClose();
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, onClose, onEscKeyDown]);
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
- // The latest callback without restarting the closing timer.
93
- const onClosedRef = React.useRef(onClosed);
94
- React.useEffect(() => {
95
- onClosedRef.current = onClosed;
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
- onOpenChange(false, "escape");
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, onOpenChange, initialFocusRef, returnFocusRef, isTopmost]);
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);
@@ -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
- // The latest callback without restarting the closing timer.
43
- const onClosedRef = useRef(onClosed);
44
- useEffect(() => {
45
- onClosedRef.current = onClosed;
46
- }, [onClosed]);
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
- onEscKeyDown === null || onEscKeyDown === void 0 ? void 0 : onEscKeyDown(event);
81
- if (!event.defaultPrevented) onClose === null || onClose === void 0 ? void 0 : onClose();
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, onClose, onEscKeyDown]);
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), {
@@ -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
- // The latest callback without restarting the closing timer.
85
- const onClosedRef = useRef(onClosed);
86
- useEffect(() => {
87
- onClosedRef.current = onClosed;
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
- onOpenChange(false, "escape");
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, onOpenChange, initialFocusRef, returnFocusRef, isTopmost]);
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,5 @@
1
+ /**
2
+ * Keeps the latest value in a ref. Effects read callbacks from it, so a new
3
+ * inline callback from the parent does not restart them.
4
+ */
5
+ export declare const useLatestRef: <T>(value: T) => import("react").RefObject<T>;
@@ -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,5 @@
1
+ /**
2
+ * Keeps the latest value in a ref. Effects read callbacks from it, so a new
3
+ * inline callback from the parent does not restart them.
4
+ */
5
+ export declare const useLatestRef: <T>(value: T) => import("react").RefObject<T>;
@@ -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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colibri-ui",
3
- "version": "0.8.87",
3
+ "version": "0.8.88",
4
4
  "description": "React UI components library",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",