@samline/drawer 2.0.5 → 2.0.7

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/README.md CHANGED
@@ -17,6 +17,7 @@ bun add @samline/drawer
17
17
  ## Quick Start
18
18
 
19
19
  ```ts
20
+ import '@samline/drawer/styles.css'
20
21
  import { createDrawer } from '@samline/drawer'
21
22
 
22
23
  const drawer = createDrawer({
@@ -1470,6 +1470,7 @@ function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeS
1470
1470
  };
1471
1471
  }
1472
1472
 
1473
+ const useSafeLayoutEffect = typeof window === 'undefined' ? React__namespace.default.useEffect : React__namespace.default.useLayoutEffect;
1473
1474
  function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction = 'bottom', defaultOpen = false, disablePreventScroll = true, snapToSequentialPoint = false, preventScrollRestoration = false, repositionInputs = true, onAnimationEnd, container, autoFocus = false }) {
1474
1475
  var _drawerRef_current, _drawerRef_current1;
1475
1476
  const animationEndTimeoutRef = React__namespace.default.useRef(null);
@@ -1527,6 +1528,27 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1527
1528
  const drawerHeightRef = React__namespace.default.useRef(((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0);
1528
1529
  const drawerWidthRef = React__namespace.default.useRef(((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0);
1529
1530
  const initialDrawerHeight = React__namespace.default.useRef(0);
1531
+ const releaseHiddenFocusBeforeOpen = React__namespace.default.useCallback(()=>{
1532
+ var _drawerRef_current;
1533
+ if (!modal || autoFocus || typeof document === 'undefined') {
1534
+ return;
1535
+ }
1536
+ const activeElement = document.activeElement;
1537
+ if (!activeElement || activeElement === document.body) {
1538
+ return;
1539
+ }
1540
+ const activeElementNode = activeElement;
1541
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElementNode)) || (activeElementNode.closest == null ? void 0 : activeElementNode.closest.call(activeElementNode, '[data-drawer]'))) {
1542
+ return;
1543
+ }
1544
+ if (typeof activeElementNode.blur !== 'function') {
1545
+ return;
1546
+ }
1547
+ activeElementNode.blur();
1548
+ }, [
1549
+ autoFocus,
1550
+ modal
1551
+ ]);
1530
1552
  const onSnapPointChange = React__namespace.default.useCallback((activeSnapPointIndex)=>{
1531
1553
  // Change openTime ref when we reach the last snap point to prevent dragging for 500ms incase it's scrollable.
1532
1554
  if (snapPoints && activeSnapPointIndex === snapPointsOffset.length - 1) openTime.current = new Date();
@@ -1577,23 +1599,14 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1577
1599
  noBodyStyles,
1578
1600
  autoFocus
1579
1601
  });
1580
- React__namespace.default.useEffect(()=>{
1581
- var _drawerRef_current;
1582
- if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1602
+ useSafeLayoutEffect(()=>{
1603
+ if (!isOpen) {
1583
1604
  return;
1584
1605
  }
1585
- const activeElement = document.activeElement;
1586
- if (!(activeElement instanceof HTMLElement)) {
1587
- return;
1588
- }
1589
- if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1590
- return;
1591
- }
1592
- activeElement.blur();
1606
+ releaseHiddenFocusBeforeOpen();
1593
1607
  }, [
1594
- autoFocus,
1595
1608
  isOpen,
1596
- modal
1609
+ releaseHiddenFocusBeforeOpen
1597
1610
  ]);
1598
1611
  function getScale() {
1599
1612
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
@@ -2002,6 +2015,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
2002
2015
  onOpenChange: (open)=>{
2003
2016
  if (!dismissible && !open) return;
2004
2017
  if (open) {
2018
+ releaseHiddenFocusBeforeOpen();
2005
2019
  setHasBeenOpened(true);
2006
2020
  } else {
2007
2021
  closeDrawer(true);
@@ -1450,6 +1450,7 @@ function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeS
1450
1450
  };
1451
1451
  }
1452
1452
 
1453
+ const useSafeLayoutEffect = typeof window === 'undefined' ? React__default.useEffect : React__default.useLayoutEffect;
1453
1454
  function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction = 'bottom', defaultOpen = false, disablePreventScroll = true, snapToSequentialPoint = false, preventScrollRestoration = false, repositionInputs = true, onAnimationEnd, container, autoFocus = false }) {
1454
1455
  var _drawerRef_current, _drawerRef_current1;
1455
1456
  const animationEndTimeoutRef = React__default.useRef(null);
@@ -1507,6 +1508,27 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1507
1508
  const drawerHeightRef = React__default.useRef(((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0);
1508
1509
  const drawerWidthRef = React__default.useRef(((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0);
1509
1510
  const initialDrawerHeight = React__default.useRef(0);
1511
+ const releaseHiddenFocusBeforeOpen = React__default.useCallback(()=>{
1512
+ var _drawerRef_current;
1513
+ if (!modal || autoFocus || typeof document === 'undefined') {
1514
+ return;
1515
+ }
1516
+ const activeElement = document.activeElement;
1517
+ if (!activeElement || activeElement === document.body) {
1518
+ return;
1519
+ }
1520
+ const activeElementNode = activeElement;
1521
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElementNode)) || (activeElementNode.closest == null ? void 0 : activeElementNode.closest.call(activeElementNode, '[data-drawer]'))) {
1522
+ return;
1523
+ }
1524
+ if (typeof activeElementNode.blur !== 'function') {
1525
+ return;
1526
+ }
1527
+ activeElementNode.blur();
1528
+ }, [
1529
+ autoFocus,
1530
+ modal
1531
+ ]);
1510
1532
  const onSnapPointChange = React__default.useCallback((activeSnapPointIndex)=>{
1511
1533
  // Change openTime ref when we reach the last snap point to prevent dragging for 500ms incase it's scrollable.
1512
1534
  if (snapPoints && activeSnapPointIndex === snapPointsOffset.length - 1) openTime.current = new Date();
@@ -1557,23 +1579,14 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1557
1579
  noBodyStyles,
1558
1580
  autoFocus
1559
1581
  });
1560
- React__default.useEffect(()=>{
1561
- var _drawerRef_current;
1562
- if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1582
+ useSafeLayoutEffect(()=>{
1583
+ if (!isOpen) {
1563
1584
  return;
1564
1585
  }
1565
- const activeElement = document.activeElement;
1566
- if (!(activeElement instanceof HTMLElement)) {
1567
- return;
1568
- }
1569
- if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1570
- return;
1571
- }
1572
- activeElement.blur();
1586
+ releaseHiddenFocusBeforeOpen();
1573
1587
  }, [
1574
- autoFocus,
1575
1588
  isOpen,
1576
- modal
1589
+ releaseHiddenFocusBeforeOpen
1577
1590
  ]);
1578
1591
  function getScale() {
1579
1592
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
@@ -1982,6 +1995,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1982
1995
  onOpenChange: (open)=>{
1983
1996
  if (!dismissible && !open) return;
1984
1997
  if (open) {
1998
+ releaseHiddenFocusBeforeOpen();
1985
1999
  setHasBeenOpened(true);
1986
2000
  } else {
1987
2001
  closeDrawer(true);
@@ -27989,6 +27989,7 @@ function getDragPermission({
27989
27989
  }
27990
27990
 
27991
27991
  // src/react/components.tsx
27992
+ var useSafeLayoutEffect = typeof window === "undefined" ? import_react9.default.useEffect : import_react9.default.useLayoutEffect;
27992
27993
  function Root2({
27993
27994
  open: openProp,
27994
27995
  onOpenChange,
@@ -28074,6 +28075,23 @@ function Root2({
28074
28075
  const drawerHeightRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().height || 0);
28075
28076
  const drawerWidthRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().width || 0);
28076
28077
  const initialDrawerHeight = import_react9.default.useRef(0);
28078
+ const releaseHiddenFocusBeforeOpen2 = import_react9.default.useCallback(() => {
28079
+ if (!modal || autoFocus || typeof document === "undefined") {
28080
+ return;
28081
+ }
28082
+ const activeElement = document.activeElement;
28083
+ if (!activeElement || activeElement === document.body) {
28084
+ return;
28085
+ }
28086
+ const activeElementNode = activeElement;
28087
+ if (drawerRef.current?.contains(activeElementNode) || activeElementNode.closest?.("[data-drawer]")) {
28088
+ return;
28089
+ }
28090
+ if (typeof activeElementNode.blur !== "function") {
28091
+ return;
28092
+ }
28093
+ activeElementNode.blur();
28094
+ }, [autoFocus, modal]);
28077
28095
  const onSnapPointChange = import_react9.default.useCallback((activeSnapPointIndex2) => {
28078
28096
  if (snapPoints && activeSnapPointIndex2 === snapPointsOffset.length - 1) openTime.current = /* @__PURE__ */ new Date();
28079
28097
  }, []);
@@ -28132,19 +28150,12 @@ function Root2({
28132
28150
  noBodyStyles,
28133
28151
  autoFocus
28134
28152
  });
28135
- import_react9.default.useEffect(() => {
28136
- if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28137
- return;
28138
- }
28139
- const activeElement = document.activeElement;
28140
- if (!(activeElement instanceof HTMLElement)) {
28141
- return;
28142
- }
28143
- if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28153
+ useSafeLayoutEffect(() => {
28154
+ if (!isOpen) {
28144
28155
  return;
28145
28156
  }
28146
- activeElement.blur();
28147
- }, [autoFocus, isOpen, modal]);
28157
+ releaseHiddenFocusBeforeOpen2();
28158
+ }, [isOpen, releaseHiddenFocusBeforeOpen2]);
28148
28159
  function getScale() {
28149
28160
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28150
28161
  }
@@ -28528,6 +28539,7 @@ function Root2({
28528
28539
  onOpenChange: (open) => {
28529
28540
  if (!dismissible && !open) return;
28530
28541
  if (open) {
28542
+ releaseHiddenFocusBeforeOpen2();
28531
28543
  setHasBeenOpened(true);
28532
28544
  } else {
28533
28545
  closeDrawer2(true);
@@ -28881,7 +28893,7 @@ var VISUALLY_HIDDEN_STYLE = {
28881
28893
  whiteSpace: "nowrap",
28882
28894
  border: 0
28883
28895
  };
28884
- var useSafeLayoutEffect = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28896
+ var useSafeLayoutEffect2 = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28885
28897
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28886
28898
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28887
28899
  const baseProps = {
@@ -28915,7 +28927,7 @@ function VanillaNode({
28915
28927
  dataAttribute
28916
28928
  }) {
28917
28929
  const ref = import_react10.default.useRef(null);
28918
- useSafeLayoutEffect(() => {
28930
+ useSafeLayoutEffect2(() => {
28919
28931
  const element = ref.current;
28920
28932
  if (!element) {
28921
28933
  return;
@@ -29121,6 +29133,7 @@ function openAncestorChain(parentId) {
29121
29133
  openAncestorChain(nextParentId);
29122
29134
  }
29123
29135
  if (!parentRuntime.controller.getSnapshot().state.isOpen) {
29136
+ releaseHiddenFocusBeforeOpen(parentRuntime.options);
29124
29137
  parentRuntime.controller.setOpen(true);
29125
29138
  notifyOpenStateChange(parentRuntime, true);
29126
29139
  renderVanillaDrawer(parentRuntime.id);
@@ -29140,6 +29153,7 @@ function bindTriggerElement(runtime) {
29140
29153
  }
29141
29154
  const triggerElement = runtime.options.triggerElement;
29142
29155
  const handleClick = () => {
29156
+ releaseHiddenFocusBeforeOpen(runtime.options);
29143
29157
  runtime.controller.setOpen(true);
29144
29158
  renderVanillaDrawer(runtime.id);
29145
29159
  };
@@ -29175,6 +29189,16 @@ function notifyOpenStateChange(runtime, open) {
29175
29189
  function canUseDOM3() {
29176
29190
  return typeof window !== "undefined" && typeof document !== "undefined";
29177
29191
  }
29192
+ function releaseHiddenFocusBeforeOpen(options) {
29193
+ if (!canUseDOM3() || options.modal === false || options.autoFocus) {
29194
+ return;
29195
+ }
29196
+ const activeElement = document.activeElement;
29197
+ if (!activeElement || activeElement === document.body || typeof activeElement.blur !== "function") {
29198
+ return;
29199
+ }
29200
+ activeElement.blur();
29201
+ }
29178
29202
  function getRuntimeDrawerElement(runtime) {
29179
29203
  if (!runtime.element) {
29180
29204
  return null;
@@ -29228,6 +29252,9 @@ function renderVanillaDrawer(id) {
29228
29252
  open: snapshot.state.isOpen,
29229
29253
  onOpenChange: (open) => {
29230
29254
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29255
+ if (open) {
29256
+ releaseHiddenFocusBeforeOpen(runtime.options);
29257
+ }
29231
29258
  runtime.controller.setOpen(open);
29232
29259
  if (previousOpen !== open) {
29233
29260
  notifyOpenStateChange(runtime, open);
@@ -29274,6 +29301,9 @@ function buildVanillaController(id) {
29274
29301
  if (!runtime) {
29275
29302
  return createDrawer({ id, open }).getSnapshot();
29276
29303
  }
29304
+ if (open) {
29305
+ releaseHiddenFocusBeforeOpen(runtime.options);
29306
+ }
29277
29307
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29278
29308
  const snapshot = runtime.controller.setOpen(open);
29279
29309
  if (previousOpen !== open) {
@@ -29344,6 +29374,9 @@ function createDrawer(options = {}) {
29344
29374
  notifyOpenStateChange(existing, snapshot.state.isOpen);
29345
29375
  }
29346
29376
  }
29377
+ if (nextOptions.open && !previousOpen) {
29378
+ releaseHiddenFocusBeforeOpen(nextOptions);
29379
+ }
29347
29380
  renderVanillaDrawer(id);
29348
29381
  if (nextOptions.parentId && nextOptions.open) {
29349
29382
  openAncestorChain(nextOptions.parentId);
@@ -27989,6 +27989,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
27989
27989
  }
27990
27990
 
27991
27991
  // src/react/components.tsx
27992
+ var useSafeLayoutEffect = typeof window === "undefined" ? import_react9.default.useEffect : import_react9.default.useLayoutEffect;
27992
27993
  function Root2({
27993
27994
  open: openProp,
27994
27995
  onOpenChange,
@@ -28074,6 +28075,23 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
28074
28075
  const drawerHeightRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().height || 0);
28075
28076
  const drawerWidthRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().width || 0);
28076
28077
  const initialDrawerHeight = import_react9.default.useRef(0);
28078
+ const releaseHiddenFocusBeforeOpen2 = import_react9.default.useCallback(() => {
28079
+ if (!modal || autoFocus || typeof document === "undefined") {
28080
+ return;
28081
+ }
28082
+ const activeElement = document.activeElement;
28083
+ if (!activeElement || activeElement === document.body) {
28084
+ return;
28085
+ }
28086
+ const activeElementNode = activeElement;
28087
+ if (drawerRef.current?.contains(activeElementNode) || activeElementNode.closest?.("[data-drawer]")) {
28088
+ return;
28089
+ }
28090
+ if (typeof activeElementNode.blur !== "function") {
28091
+ return;
28092
+ }
28093
+ activeElementNode.blur();
28094
+ }, [autoFocus, modal]);
28077
28095
  const onSnapPointChange = import_react9.default.useCallback((activeSnapPointIndex2) => {
28078
28096
  if (snapPoints && activeSnapPointIndex2 === snapPointsOffset.length - 1) openTime.current = /* @__PURE__ */ new Date();
28079
28097
  }, []);
@@ -28132,19 +28150,12 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
28132
28150
  noBodyStyles,
28133
28151
  autoFocus
28134
28152
  });
28135
- import_react9.default.useEffect(() => {
28136
- if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28137
- return;
28138
- }
28139
- const activeElement = document.activeElement;
28140
- if (!(activeElement instanceof HTMLElement)) {
28141
- return;
28142
- }
28143
- if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28153
+ useSafeLayoutEffect(() => {
28154
+ if (!isOpen) {
28144
28155
  return;
28145
28156
  }
28146
- activeElement.blur();
28147
- }, [autoFocus, isOpen, modal]);
28157
+ releaseHiddenFocusBeforeOpen2();
28158
+ }, [isOpen, releaseHiddenFocusBeforeOpen2]);
28148
28159
  function getScale() {
28149
28160
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28150
28161
  }
@@ -28528,6 +28539,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
28528
28539
  onOpenChange: (open) => {
28529
28540
  if (!dismissible && !open) return;
28530
28541
  if (open) {
28542
+ releaseHiddenFocusBeforeOpen2();
28531
28543
  setHasBeenOpened(true);
28532
28544
  } else {
28533
28545
  closeDrawer2(true);
@@ -28881,7 +28893,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
28881
28893
  whiteSpace: "nowrap",
28882
28894
  border: 0
28883
28895
  };
28884
- var useSafeLayoutEffect = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28896
+ var useSafeLayoutEffect2 = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28885
28897
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28886
28898
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28887
28899
  const baseProps = {
@@ -28915,7 +28927,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
28915
28927
  dataAttribute
28916
28928
  }) {
28917
28929
  const ref = import_react10.default.useRef(null);
28918
- useSafeLayoutEffect(() => {
28930
+ useSafeLayoutEffect2(() => {
28919
28931
  const element = ref.current;
28920
28932
  if (!element) {
28921
28933
  return;
@@ -29121,6 +29133,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29121
29133
  openAncestorChain(nextParentId);
29122
29134
  }
29123
29135
  if (!parentRuntime.controller.getSnapshot().state.isOpen) {
29136
+ releaseHiddenFocusBeforeOpen(parentRuntime.options);
29124
29137
  parentRuntime.controller.setOpen(true);
29125
29138
  notifyOpenStateChange(parentRuntime, true);
29126
29139
  renderVanillaDrawer(parentRuntime.id);
@@ -29140,6 +29153,7 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29140
29153
  }
29141
29154
  const triggerElement = runtime.options.triggerElement;
29142
29155
  const handleClick = () => {
29156
+ releaseHiddenFocusBeforeOpen(runtime.options);
29143
29157
  runtime.controller.setOpen(true);
29144
29158
  renderVanillaDrawer(runtime.id);
29145
29159
  };
@@ -29175,6 +29189,16 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29175
29189
  function canUseDOM3() {
29176
29190
  return typeof window !== "undefined" && typeof document !== "undefined";
29177
29191
  }
29192
+ function releaseHiddenFocusBeforeOpen(options) {
29193
+ if (!canUseDOM3() || options.modal === false || options.autoFocus) {
29194
+ return;
29195
+ }
29196
+ const activeElement = document.activeElement;
29197
+ if (!activeElement || activeElement === document.body || typeof activeElement.blur !== "function") {
29198
+ return;
29199
+ }
29200
+ activeElement.blur();
29201
+ }
29178
29202
  function getRuntimeDrawerElement(runtime) {
29179
29203
  if (!runtime.element) {
29180
29204
  return null;
@@ -29228,6 +29252,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29228
29252
  open: snapshot.state.isOpen,
29229
29253
  onOpenChange: (open) => {
29230
29254
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29255
+ if (open) {
29256
+ releaseHiddenFocusBeforeOpen(runtime.options);
29257
+ }
29231
29258
  runtime.controller.setOpen(open);
29232
29259
  if (previousOpen !== open) {
29233
29260
  notifyOpenStateChange(runtime, open);
@@ -29274,6 +29301,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29274
29301
  if (!runtime) {
29275
29302
  return createDrawer({ id, open }).getSnapshot();
29276
29303
  }
29304
+ if (open) {
29305
+ releaseHiddenFocusBeforeOpen(runtime.options);
29306
+ }
29277
29307
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29278
29308
  const snapshot = runtime.controller.setOpen(open);
29279
29309
  if (previousOpen !== open) {
@@ -29344,6 +29374,9 @@ For more information, see https://radix-ui.com/primitives/docs/components/${titl
29344
29374
  notifyOpenStateChange(existing, snapshot.state.isOpen);
29345
29375
  }
29346
29376
  }
29377
+ if (nextOptions.open && !previousOpen) {
29378
+ releaseHiddenFocusBeforeOpen(nextOptions);
29379
+ }
29347
29380
  renderVanillaDrawer(id);
29348
29381
  if (nextOptions.parentId && nextOptions.open) {
29349
29382
  openAncestorChain(nextOptions.parentId);
@@ -27963,6 +27963,7 @@ function getDragPermission({
27963
27963
  }
27964
27964
 
27965
27965
  // src/react/components.tsx
27966
+ var useSafeLayoutEffect = typeof window === "undefined" ? import_react9.default.useEffect : import_react9.default.useLayoutEffect;
27966
27967
  function Root2({
27967
27968
  open: openProp,
27968
27969
  onOpenChange,
@@ -28048,6 +28049,23 @@ function Root2({
28048
28049
  const drawerHeightRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().height || 0);
28049
28050
  const drawerWidthRef = import_react9.default.useRef(drawerRef.current?.getBoundingClientRect().width || 0);
28050
28051
  const initialDrawerHeight = import_react9.default.useRef(0);
28052
+ const releaseHiddenFocusBeforeOpen2 = import_react9.default.useCallback(() => {
28053
+ if (!modal || autoFocus || typeof document === "undefined") {
28054
+ return;
28055
+ }
28056
+ const activeElement = document.activeElement;
28057
+ if (!activeElement || activeElement === document.body) {
28058
+ return;
28059
+ }
28060
+ const activeElementNode = activeElement;
28061
+ if (drawerRef.current?.contains(activeElementNode) || activeElementNode.closest?.("[data-drawer]")) {
28062
+ return;
28063
+ }
28064
+ if (typeof activeElementNode.blur !== "function") {
28065
+ return;
28066
+ }
28067
+ activeElementNode.blur();
28068
+ }, [autoFocus, modal]);
28051
28069
  const onSnapPointChange = import_react9.default.useCallback((activeSnapPointIndex2) => {
28052
28070
  if (snapPoints && activeSnapPointIndex2 === snapPointsOffset.length - 1) openTime.current = /* @__PURE__ */ new Date();
28053
28071
  }, []);
@@ -28106,19 +28124,12 @@ function Root2({
28106
28124
  noBodyStyles,
28107
28125
  autoFocus
28108
28126
  });
28109
- import_react9.default.useEffect(() => {
28110
- if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28111
- return;
28112
- }
28113
- const activeElement = document.activeElement;
28114
- if (!(activeElement instanceof HTMLElement)) {
28115
- return;
28116
- }
28117
- if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28127
+ useSafeLayoutEffect(() => {
28128
+ if (!isOpen) {
28118
28129
  return;
28119
28130
  }
28120
- activeElement.blur();
28121
- }, [autoFocus, isOpen, modal]);
28131
+ releaseHiddenFocusBeforeOpen2();
28132
+ }, [isOpen, releaseHiddenFocusBeforeOpen2]);
28122
28133
  function getScale() {
28123
28134
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28124
28135
  }
@@ -28502,6 +28513,7 @@ function Root2({
28502
28513
  onOpenChange: (open) => {
28503
28514
  if (!dismissible && !open) return;
28504
28515
  if (open) {
28516
+ releaseHiddenFocusBeforeOpen2();
28505
28517
  setHasBeenOpened(true);
28506
28518
  } else {
28507
28519
  closeDrawer2(true);
@@ -28855,7 +28867,7 @@ var VISUALLY_HIDDEN_STYLE = {
28855
28867
  whiteSpace: "nowrap",
28856
28868
  border: 0
28857
28869
  };
28858
- var useSafeLayoutEffect = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28870
+ var useSafeLayoutEffect2 = typeof window === "undefined" ? import_react10.default.useEffect : import_react10.default.useLayoutEffect;
28859
28871
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28860
28872
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28861
28873
  const baseProps = {
@@ -28889,7 +28901,7 @@ function VanillaNode({
28889
28901
  dataAttribute
28890
28902
  }) {
28891
28903
  const ref = import_react10.default.useRef(null);
28892
- useSafeLayoutEffect(() => {
28904
+ useSafeLayoutEffect2(() => {
28893
28905
  const element = ref.current;
28894
28906
  if (!element) {
28895
28907
  return;
@@ -29095,6 +29107,7 @@ function openAncestorChain(parentId) {
29095
29107
  openAncestorChain(nextParentId);
29096
29108
  }
29097
29109
  if (!parentRuntime.controller.getSnapshot().state.isOpen) {
29110
+ releaseHiddenFocusBeforeOpen(parentRuntime.options);
29098
29111
  parentRuntime.controller.setOpen(true);
29099
29112
  notifyOpenStateChange(parentRuntime, true);
29100
29113
  renderVanillaDrawer(parentRuntime.id);
@@ -29114,6 +29127,7 @@ function bindTriggerElement(runtime) {
29114
29127
  }
29115
29128
  const triggerElement = runtime.options.triggerElement;
29116
29129
  const handleClick = () => {
29130
+ releaseHiddenFocusBeforeOpen(runtime.options);
29117
29131
  runtime.controller.setOpen(true);
29118
29132
  renderVanillaDrawer(runtime.id);
29119
29133
  };
@@ -29149,6 +29163,16 @@ function notifyOpenStateChange(runtime, open) {
29149
29163
  function canUseDOM3() {
29150
29164
  return typeof window !== "undefined" && typeof document !== "undefined";
29151
29165
  }
29166
+ function releaseHiddenFocusBeforeOpen(options) {
29167
+ if (!canUseDOM3() || options.modal === false || options.autoFocus) {
29168
+ return;
29169
+ }
29170
+ const activeElement = document.activeElement;
29171
+ if (!activeElement || activeElement === document.body || typeof activeElement.blur !== "function") {
29172
+ return;
29173
+ }
29174
+ activeElement.blur();
29175
+ }
29152
29176
  function getRuntimeDrawerElement(runtime) {
29153
29177
  if (!runtime.element) {
29154
29178
  return null;
@@ -29202,6 +29226,9 @@ function renderVanillaDrawer(id) {
29202
29226
  open: snapshot.state.isOpen,
29203
29227
  onOpenChange: (open) => {
29204
29228
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29229
+ if (open) {
29230
+ releaseHiddenFocusBeforeOpen(runtime.options);
29231
+ }
29205
29232
  runtime.controller.setOpen(open);
29206
29233
  if (previousOpen !== open) {
29207
29234
  notifyOpenStateChange(runtime, open);
@@ -29248,6 +29275,9 @@ function buildVanillaController(id) {
29248
29275
  if (!runtime) {
29249
29276
  return createDrawer({ id, open }).getSnapshot();
29250
29277
  }
29278
+ if (open) {
29279
+ releaseHiddenFocusBeforeOpen(runtime.options);
29280
+ }
29251
29281
  const previousOpen = runtime.controller.getSnapshot().state.isOpen;
29252
29282
  const snapshot = runtime.controller.setOpen(open);
29253
29283
  if (previousOpen !== open) {
@@ -29318,6 +29348,9 @@ function createDrawer(options = {}) {
29318
29348
  notifyOpenStateChange(existing, snapshot.state.isOpen);
29319
29349
  }
29320
29350
  }
29351
+ if (nextOptions.open && !previousOpen) {
29352
+ releaseHiddenFocusBeforeOpen(nextOptions);
29353
+ }
29321
29354
  renderVanillaDrawer(id);
29322
29355
  if (nextOptions.parentId && nextOptions.open) {
29323
29356
  openAncestorChain(nextOptions.parentId);
@@ -1470,6 +1470,7 @@ function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeS
1470
1470
  };
1471
1471
  }
1472
1472
 
1473
+ const useSafeLayoutEffect = typeof window === 'undefined' ? React__namespace.default.useEffect : React__namespace.default.useLayoutEffect;
1473
1474
  function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction = 'bottom', defaultOpen = false, disablePreventScroll = true, snapToSequentialPoint = false, preventScrollRestoration = false, repositionInputs = true, onAnimationEnd, container, autoFocus = false }) {
1474
1475
  var _drawerRef_current, _drawerRef_current1;
1475
1476
  const animationEndTimeoutRef = React__namespace.default.useRef(null);
@@ -1527,6 +1528,27 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1527
1528
  const drawerHeightRef = React__namespace.default.useRef(((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0);
1528
1529
  const drawerWidthRef = React__namespace.default.useRef(((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0);
1529
1530
  const initialDrawerHeight = React__namespace.default.useRef(0);
1531
+ const releaseHiddenFocusBeforeOpen = React__namespace.default.useCallback(()=>{
1532
+ var _drawerRef_current;
1533
+ if (!modal || autoFocus || typeof document === 'undefined') {
1534
+ return;
1535
+ }
1536
+ const activeElement = document.activeElement;
1537
+ if (!activeElement || activeElement === document.body) {
1538
+ return;
1539
+ }
1540
+ const activeElementNode = activeElement;
1541
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElementNode)) || (activeElementNode.closest == null ? void 0 : activeElementNode.closest.call(activeElementNode, '[data-drawer]'))) {
1542
+ return;
1543
+ }
1544
+ if (typeof activeElementNode.blur !== 'function') {
1545
+ return;
1546
+ }
1547
+ activeElementNode.blur();
1548
+ }, [
1549
+ autoFocus,
1550
+ modal
1551
+ ]);
1530
1552
  const onSnapPointChange = React__namespace.default.useCallback((activeSnapPointIndex)=>{
1531
1553
  // Change openTime ref when we reach the last snap point to prevent dragging for 500ms incase it's scrollable.
1532
1554
  if (snapPoints && activeSnapPointIndex === snapPointsOffset.length - 1) openTime.current = new Date();
@@ -1577,23 +1599,14 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1577
1599
  noBodyStyles,
1578
1600
  autoFocus
1579
1601
  });
1580
- React__namespace.default.useEffect(()=>{
1581
- var _drawerRef_current;
1582
- if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1602
+ useSafeLayoutEffect(()=>{
1603
+ if (!isOpen) {
1583
1604
  return;
1584
1605
  }
1585
- const activeElement = document.activeElement;
1586
- if (!(activeElement instanceof HTMLElement)) {
1587
- return;
1588
- }
1589
- if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1590
- return;
1591
- }
1592
- activeElement.blur();
1606
+ releaseHiddenFocusBeforeOpen();
1593
1607
  }, [
1594
- autoFocus,
1595
1608
  isOpen,
1596
- modal
1609
+ releaseHiddenFocusBeforeOpen
1597
1610
  ]);
1598
1611
  function getScale() {
1599
1612
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
@@ -2002,6 +2015,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
2002
2015
  onOpenChange: (open)=>{
2003
2016
  if (!dismissible && !open) return;
2004
2017
  if (open) {
2018
+ releaseHiddenFocusBeforeOpen();
2005
2019
  setHasBeenOpened(true);
2006
2020
  } else {
2007
2021
  closeDrawer(true);