@samline/drawer 2.0.0 → 2.0.2

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.
@@ -1311,6 +1311,30 @@ function getNextHandleState({ isDragging, preventCycle, shouldCancelInteraction,
1311
1311
  };
1312
1312
  }
1313
1313
 
1314
+ function isElementLike(target) {
1315
+ const element = target;
1316
+ return Boolean(element && typeof element.getAttribute === 'function' && typeof element.hasAttribute === 'function' && typeof element.closest === 'function');
1317
+ }
1318
+ function getDragTargetMetadata(target) {
1319
+ var _ref;
1320
+ const targetElement = isElementLike(target) ? target : null;
1321
+ const ancestors = [];
1322
+ let element = targetElement;
1323
+ while(element){
1324
+ ancestors.push({
1325
+ scrollHeight: element.scrollHeight,
1326
+ clientHeight: element.clientHeight,
1327
+ scrollTop: element.scrollTop,
1328
+ role: element.getAttribute('role')
1329
+ });
1330
+ element = element.parentElement;
1331
+ }
1332
+ return {
1333
+ targetTagName: (_ref = targetElement == null ? void 0 : targetElement.tagName) != null ? _ref : '',
1334
+ hasNoDragAttribute: (targetElement == null ? void 0 : targetElement.hasAttribute('data-drawer-no-drag')) || Boolean(targetElement == null ? void 0 : targetElement.closest('[data-drawer-no-drag]')),
1335
+ ancestors
1336
+ };
1337
+ }
1314
1338
  function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeSinceOpenMs, swipeAmount, hasHighlightedText, timeSinceLastPreventedMs, scrollLockTimeout, isDraggingInDirection, ancestors }) {
1315
1339
  if (targetTagName === 'SELECT' || hasNoDragAttribute) {
1316
1340
  return {
@@ -1473,6 +1497,24 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1473
1497
  noBodyStyles,
1474
1498
  autoFocus
1475
1499
  });
1500
+ React__default.useEffect(()=>{
1501
+ var _drawerRef_current;
1502
+ if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1503
+ return;
1504
+ }
1505
+ const activeElement = document.activeElement;
1506
+ if (!(activeElement instanceof HTMLElement)) {
1507
+ return;
1508
+ }
1509
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1510
+ return;
1511
+ }
1512
+ activeElement.blur();
1513
+ }, [
1514
+ autoFocus,
1515
+ isOpen,
1516
+ modal
1517
+ ]);
1476
1518
  function getScale() {
1477
1519
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
1478
1520
  }
@@ -1496,24 +1538,12 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1496
1538
  }
1497
1539
  function shouldDrag(el, isDraggingInDirection) {
1498
1540
  var _window_getSelection;
1499
- let element = el;
1500
1541
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
1501
1542
  const date = new Date();
1502
- const ancestors = [];
1503
- // Keep climbing up the DOM tree as long as there's a parent
1504
- while(element){
1505
- ancestors.push({
1506
- scrollHeight: element.scrollHeight,
1507
- clientHeight: element.clientHeight,
1508
- scrollTop: element.scrollTop,
1509
- role: element.getAttribute('role')
1510
- });
1511
- // Move up to the parent element
1512
- element = element.parentNode;
1513
- }
1543
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
1514
1544
  const result = getDragPermission({
1515
- targetTagName: el.tagName,
1516
- hasNoDragAttribute: el.hasAttribute('data-drawer-no-drag') || Boolean(el.closest('[data-drawer-no-drag]')),
1545
+ targetTagName,
1546
+ hasNoDragAttribute,
1517
1547
  direction,
1518
1548
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
1519
1549
  swipeAmount,
@@ -1331,6 +1331,30 @@ function getNextHandleState({ isDragging, preventCycle, shouldCancelInteraction,
1331
1331
  };
1332
1332
  }
1333
1333
 
1334
+ function isElementLike(target) {
1335
+ const element = target;
1336
+ return Boolean(element && typeof element.getAttribute === 'function' && typeof element.hasAttribute === 'function' && typeof element.closest === 'function');
1337
+ }
1338
+ function getDragTargetMetadata(target) {
1339
+ var _ref;
1340
+ const targetElement = isElementLike(target) ? target : null;
1341
+ const ancestors = [];
1342
+ let element = targetElement;
1343
+ while(element){
1344
+ ancestors.push({
1345
+ scrollHeight: element.scrollHeight,
1346
+ clientHeight: element.clientHeight,
1347
+ scrollTop: element.scrollTop,
1348
+ role: element.getAttribute('role')
1349
+ });
1350
+ element = element.parentElement;
1351
+ }
1352
+ return {
1353
+ targetTagName: (_ref = targetElement == null ? void 0 : targetElement.tagName) != null ? _ref : '',
1354
+ hasNoDragAttribute: (targetElement == null ? void 0 : targetElement.hasAttribute('data-drawer-no-drag')) || Boolean(targetElement == null ? void 0 : targetElement.closest('[data-drawer-no-drag]')),
1355
+ ancestors
1356
+ };
1357
+ }
1334
1358
  function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeSinceOpenMs, swipeAmount, hasHighlightedText, timeSinceLastPreventedMs, scrollLockTimeout, isDraggingInDirection, ancestors }) {
1335
1359
  if (targetTagName === 'SELECT' || hasNoDragAttribute) {
1336
1360
  return {
@@ -1493,6 +1517,24 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1493
1517
  noBodyStyles,
1494
1518
  autoFocus
1495
1519
  });
1520
+ React__namespace.default.useEffect(()=>{
1521
+ var _drawerRef_current;
1522
+ if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1523
+ return;
1524
+ }
1525
+ const activeElement = document.activeElement;
1526
+ if (!(activeElement instanceof HTMLElement)) {
1527
+ return;
1528
+ }
1529
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1530
+ return;
1531
+ }
1532
+ activeElement.blur();
1533
+ }, [
1534
+ autoFocus,
1535
+ isOpen,
1536
+ modal
1537
+ ]);
1496
1538
  function getScale() {
1497
1539
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
1498
1540
  }
@@ -1516,24 +1558,12 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1516
1558
  }
1517
1559
  function shouldDrag(el, isDraggingInDirection) {
1518
1560
  var _window_getSelection;
1519
- let element = el;
1520
1561
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
1521
1562
  const date = new Date();
1522
- const ancestors = [];
1523
- // Keep climbing up the DOM tree as long as there's a parent
1524
- while(element){
1525
- ancestors.push({
1526
- scrollHeight: element.scrollHeight,
1527
- clientHeight: element.clientHeight,
1528
- scrollTop: element.scrollTop,
1529
- role: element.getAttribute('role')
1530
- });
1531
- // Move up to the parent element
1532
- element = element.parentNode;
1533
- }
1563
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
1534
1564
  const result = getDragPermission({
1535
- targetTagName: el.tagName,
1536
- hasNoDragAttribute: el.hasAttribute('data-drawer-no-drag') || Boolean(el.closest('[data-drawer-no-drag]')),
1565
+ targetTagName,
1566
+ hasNoDragAttribute,
1537
1567
  direction,
1538
1568
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
1539
1569
  swipeAmount,
package/dist/index.d.mts CHANGED
@@ -8,8 +8,13 @@ interface VanillaDrawerOptions extends CommonDrawerOptions {
8
8
  triggerText?: string;
9
9
  showHandle?: boolean;
10
10
  handleClassName?: string;
11
+ ariaLabel?: string;
12
+ ariaLabelledBy?: string;
13
+ ariaDescribedBy?: string;
11
14
  title?: VanillaRenderable;
15
+ titleVisuallyHidden?: boolean;
12
16
  description?: VanillaRenderable;
17
+ descriptionVisuallyHidden?: boolean;
13
18
  content?: VanillaRenderable;
14
19
  overlayClassName?: string;
15
20
  contentClassName?: string;
package/dist/index.d.ts CHANGED
@@ -8,8 +8,13 @@ interface VanillaDrawerOptions extends CommonDrawerOptions {
8
8
  triggerText?: string;
9
9
  showHandle?: boolean;
10
10
  handleClassName?: string;
11
+ ariaLabel?: string;
12
+ ariaLabelledBy?: string;
13
+ ariaDescribedBy?: string;
11
14
  title?: VanillaRenderable;
15
+ titleVisuallyHidden?: boolean;
12
16
  description?: VanillaRenderable;
17
+ descriptionVisuallyHidden?: boolean;
13
18
  content?: VanillaRenderable;
14
19
  overlayClassName?: string;
15
20
  contentClassName?: string;
package/dist/index.js CHANGED
@@ -27868,6 +27868,31 @@ function getNextHandleState({
27868
27868
  }
27869
27869
 
27870
27870
  // src/runtime/drag-policy.ts
27871
+ function isElementLike(target) {
27872
+ const element = target;
27873
+ return Boolean(
27874
+ element && typeof element.getAttribute === "function" && typeof element.hasAttribute === "function" && typeof element.closest === "function"
27875
+ );
27876
+ }
27877
+ function getDragTargetMetadata(target) {
27878
+ const targetElement = isElementLike(target) ? target : null;
27879
+ const ancestors = [];
27880
+ let element = targetElement;
27881
+ while (element) {
27882
+ ancestors.push({
27883
+ scrollHeight: element.scrollHeight,
27884
+ clientHeight: element.clientHeight,
27885
+ scrollTop: element.scrollTop,
27886
+ role: element.getAttribute("role")
27887
+ });
27888
+ element = element.parentElement;
27889
+ }
27890
+ return {
27891
+ targetTagName: targetElement?.tagName ?? "",
27892
+ hasNoDragAttribute: targetElement?.hasAttribute("data-drawer-no-drag") || Boolean(targetElement?.closest("[data-drawer-no-drag]")),
27893
+ ancestors
27894
+ };
27895
+ }
27871
27896
  function getDragPermission({
27872
27897
  targetTagName,
27873
27898
  hasNoDragAttribute,
@@ -28048,6 +28073,19 @@ function Root2({
28048
28073
  noBodyStyles,
28049
28074
  autoFocus
28050
28075
  });
28076
+ import_react9.default.useEffect(() => {
28077
+ if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28078
+ return;
28079
+ }
28080
+ const activeElement = document.activeElement;
28081
+ if (!(activeElement instanceof HTMLElement)) {
28082
+ return;
28083
+ }
28084
+ if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28085
+ return;
28086
+ }
28087
+ activeElement.blur();
28088
+ }, [autoFocus, isOpen, modal]);
28051
28089
  function getScale() {
28052
28090
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28053
28091
  }
@@ -28065,22 +28103,12 @@ function Root2({
28065
28103
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
28066
28104
  }
28067
28105
  function shouldDrag(el, isDraggingInDirection) {
28068
- let element = el;
28069
28106
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
28070
28107
  const date = /* @__PURE__ */ new Date();
28071
- const ancestors = [];
28072
- while (element) {
28073
- ancestors.push({
28074
- scrollHeight: element.scrollHeight,
28075
- clientHeight: element.clientHeight,
28076
- scrollTop: element.scrollTop,
28077
- role: element.getAttribute("role")
28078
- });
28079
- element = element.parentNode;
28080
- }
28108
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
28081
28109
  const result = getDragPermission({
28082
- targetTagName: el.tagName,
28083
- hasNoDragAttribute: el.hasAttribute("data-drawer-no-drag") || Boolean(el.closest("[data-drawer-no-drag]")),
28110
+ targetTagName,
28111
+ hasNoDragAttribute,
28084
28112
  direction,
28085
28113
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
28086
28114
  swipeAmount,
@@ -28709,6 +28737,17 @@ var Drawer = {
28709
28737
  };
28710
28738
 
28711
28739
  // src/vanilla/render.tsx
28740
+ var VISUALLY_HIDDEN_STYLE = {
28741
+ position: "absolute",
28742
+ width: "1px",
28743
+ height: "1px",
28744
+ padding: 0,
28745
+ margin: "-1px",
28746
+ overflow: "hidden",
28747
+ clip: "rect(0, 0, 0, 0)",
28748
+ whiteSpace: "nowrap",
28749
+ border: 0
28750
+ };
28712
28751
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28713
28752
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28714
28753
  const baseProps = {
@@ -28737,7 +28776,7 @@ function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, i
28737
28776
  fadeFromIndex: void 0
28738
28777
  };
28739
28778
  }
28740
- function VanillaNode({ value }) {
28779
+ function VanillaNode({ value, dataAttribute }) {
28741
28780
  const ref = import_react10.default.useRef(null);
28742
28781
  import_react10.default.useEffect(() => {
28743
28782
  const element = ref.current;
@@ -28760,7 +28799,7 @@ function VanillaNode({ value }) {
28760
28799
  if (value == null) {
28761
28800
  return null;
28762
28801
  }
28763
- return /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "", ref });
28802
+ return /* @__PURE__ */ import_react10.default.createElement("div", { ...dataAttribute ? { [dataAttribute]: "" } : {}, ref });
28764
28803
  }
28765
28804
  function VanillaDrawerRenderer({
28766
28805
  options,
@@ -28775,8 +28814,13 @@ function VanillaDrawerRenderer({
28775
28814
  triggerText,
28776
28815
  showHandle,
28777
28816
  handleClassName,
28817
+ ariaLabel,
28818
+ ariaLabelledBy,
28819
+ ariaDescribedBy,
28778
28820
  title,
28821
+ titleVisuallyHidden,
28779
28822
  description,
28823
+ descriptionVisuallyHidden,
28780
28824
  content,
28781
28825
  overlayClassName,
28782
28826
  contentClassName,
@@ -28784,7 +28828,18 @@ function VanillaDrawerRenderer({
28784
28828
  } = options;
28785
28829
  const rootProps = toReactDrawerProps(drawerOptions, open, onOpenChange, onDragChange, onReleaseChange);
28786
28830
  const shouldRenderHandle = Boolean(drawerOptions.handleOnly || showHandle);
28787
- return /* @__PURE__ */ import_react10.default.createElement(Drawer.Root, { ...rootProps }, triggerText ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Trigger, { asChild: true }, /* @__PURE__ */ import_react10.default.createElement("button", { type: "button", "data-drawer-vanilla-trigger": "" }, triggerText)) : null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Portal, null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Overlay, { className: overlayClassName }), /* @__PURE__ */ import_react10.default.createElement(Drawer.Content, { className: contentClassName }, shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null, title != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Title, null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: title })) : null, description != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Description, null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: description })) : null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: content }))));
28831
+ const shouldRenderVanillaContent = title != null || description != null || content != null;
28832
+ return /* @__PURE__ */ import_react10.default.createElement(Drawer.Root, { ...rootProps }, triggerText ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Trigger, { asChild: true }, /* @__PURE__ */ import_react10.default.createElement("button", { type: "button", "data-drawer-vanilla-trigger": "" }, triggerText)) : null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Portal, null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Overlay, { className: overlayClassName }), /* @__PURE__ */ import_react10.default.createElement(
28833
+ Drawer.Content,
28834
+ {
28835
+ className: contentClassName,
28836
+ "aria-label": title == null ? ariaLabel : void 0,
28837
+ "aria-labelledby": title == null ? ariaLabelledBy : void 0,
28838
+ "aria-describedby": description == null ? ariaDescribedBy : void 0
28839
+ },
28840
+ shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null,
28841
+ shouldRenderVanillaContent ? /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "" }, title != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Title, { style: titleVisuallyHidden ? VISUALLY_HIDDEN_STYLE : void 0 }, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: title })) : null, description != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Description, { style: descriptionVisuallyHidden ? VISUALLY_HIDDEN_STYLE : void 0 }, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: description })) : null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: content, dataAttribute: "data-drawer-vanilla-body" })) : null
28842
+ )));
28788
28843
  }
28789
28844
 
28790
28845
  // src/vanilla/host.tsx
package/dist/index.mjs CHANGED
@@ -27843,6 +27843,31 @@ function getNextHandleState({
27843
27843
  }
27844
27844
 
27845
27845
  // src/runtime/drag-policy.ts
27846
+ function isElementLike(target) {
27847
+ const element = target;
27848
+ return Boolean(
27849
+ element && typeof element.getAttribute === "function" && typeof element.hasAttribute === "function" && typeof element.closest === "function"
27850
+ );
27851
+ }
27852
+ function getDragTargetMetadata(target) {
27853
+ const targetElement = isElementLike(target) ? target : null;
27854
+ const ancestors = [];
27855
+ let element = targetElement;
27856
+ while (element) {
27857
+ ancestors.push({
27858
+ scrollHeight: element.scrollHeight,
27859
+ clientHeight: element.clientHeight,
27860
+ scrollTop: element.scrollTop,
27861
+ role: element.getAttribute("role")
27862
+ });
27863
+ element = element.parentElement;
27864
+ }
27865
+ return {
27866
+ targetTagName: targetElement?.tagName ?? "",
27867
+ hasNoDragAttribute: targetElement?.hasAttribute("data-drawer-no-drag") || Boolean(targetElement?.closest("[data-drawer-no-drag]")),
27868
+ ancestors
27869
+ };
27870
+ }
27846
27871
  function getDragPermission({
27847
27872
  targetTagName,
27848
27873
  hasNoDragAttribute,
@@ -28023,6 +28048,19 @@ function Root2({
28023
28048
  noBodyStyles,
28024
28049
  autoFocus
28025
28050
  });
28051
+ import_react9.default.useEffect(() => {
28052
+ if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28053
+ return;
28054
+ }
28055
+ const activeElement = document.activeElement;
28056
+ if (!(activeElement instanceof HTMLElement)) {
28057
+ return;
28058
+ }
28059
+ if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28060
+ return;
28061
+ }
28062
+ activeElement.blur();
28063
+ }, [autoFocus, isOpen, modal]);
28026
28064
  function getScale() {
28027
28065
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28028
28066
  }
@@ -28040,22 +28078,12 @@ function Root2({
28040
28078
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
28041
28079
  }
28042
28080
  function shouldDrag(el, isDraggingInDirection) {
28043
- let element = el;
28044
28081
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
28045
28082
  const date = /* @__PURE__ */ new Date();
28046
- const ancestors = [];
28047
- while (element) {
28048
- ancestors.push({
28049
- scrollHeight: element.scrollHeight,
28050
- clientHeight: element.clientHeight,
28051
- scrollTop: element.scrollTop,
28052
- role: element.getAttribute("role")
28053
- });
28054
- element = element.parentNode;
28055
- }
28083
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
28056
28084
  const result = getDragPermission({
28057
- targetTagName: el.tagName,
28058
- hasNoDragAttribute: el.hasAttribute("data-drawer-no-drag") || Boolean(el.closest("[data-drawer-no-drag]")),
28085
+ targetTagName,
28086
+ hasNoDragAttribute,
28059
28087
  direction,
28060
28088
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
28061
28089
  swipeAmount,
@@ -28684,6 +28712,17 @@ var Drawer = {
28684
28712
  };
28685
28713
 
28686
28714
  // src/vanilla/render.tsx
28715
+ var VISUALLY_HIDDEN_STYLE = {
28716
+ position: "absolute",
28717
+ width: "1px",
28718
+ height: "1px",
28719
+ padding: 0,
28720
+ margin: "-1px",
28721
+ overflow: "hidden",
28722
+ clip: "rect(0, 0, 0, 0)",
28723
+ whiteSpace: "nowrap",
28724
+ border: 0
28725
+ };
28687
28726
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28688
28727
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28689
28728
  const baseProps = {
@@ -28712,7 +28751,7 @@ function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, i
28712
28751
  fadeFromIndex: void 0
28713
28752
  };
28714
28753
  }
28715
- function VanillaNode({ value }) {
28754
+ function VanillaNode({ value, dataAttribute }) {
28716
28755
  const ref = import_react10.default.useRef(null);
28717
28756
  import_react10.default.useEffect(() => {
28718
28757
  const element = ref.current;
@@ -28735,7 +28774,7 @@ function VanillaNode({ value }) {
28735
28774
  if (value == null) {
28736
28775
  return null;
28737
28776
  }
28738
- return /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "", ref });
28777
+ return /* @__PURE__ */ import_react10.default.createElement("div", { ...dataAttribute ? { [dataAttribute]: "" } : {}, ref });
28739
28778
  }
28740
28779
  function VanillaDrawerRenderer({
28741
28780
  options,
@@ -28750,8 +28789,13 @@ function VanillaDrawerRenderer({
28750
28789
  triggerText,
28751
28790
  showHandle,
28752
28791
  handleClassName,
28792
+ ariaLabel,
28793
+ ariaLabelledBy,
28794
+ ariaDescribedBy,
28753
28795
  title,
28796
+ titleVisuallyHidden,
28754
28797
  description,
28798
+ descriptionVisuallyHidden,
28755
28799
  content,
28756
28800
  overlayClassName,
28757
28801
  contentClassName,
@@ -28759,7 +28803,18 @@ function VanillaDrawerRenderer({
28759
28803
  } = options;
28760
28804
  const rootProps = toReactDrawerProps(drawerOptions, open, onOpenChange, onDragChange, onReleaseChange);
28761
28805
  const shouldRenderHandle = Boolean(drawerOptions.handleOnly || showHandle);
28762
- return /* @__PURE__ */ import_react10.default.createElement(Drawer.Root, { ...rootProps }, triggerText ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Trigger, { asChild: true }, /* @__PURE__ */ import_react10.default.createElement("button", { type: "button", "data-drawer-vanilla-trigger": "" }, triggerText)) : null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Portal, null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Overlay, { className: overlayClassName }), /* @__PURE__ */ import_react10.default.createElement(Drawer.Content, { className: contentClassName }, shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null, title != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Title, null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: title })) : null, description != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Description, null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: description })) : null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: content }))));
28806
+ const shouldRenderVanillaContent = title != null || description != null || content != null;
28807
+ return /* @__PURE__ */ import_react10.default.createElement(Drawer.Root, { ...rootProps }, triggerText ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Trigger, { asChild: true }, /* @__PURE__ */ import_react10.default.createElement("button", { type: "button", "data-drawer-vanilla-trigger": "" }, triggerText)) : null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Portal, null, /* @__PURE__ */ import_react10.default.createElement(Drawer.Overlay, { className: overlayClassName }), /* @__PURE__ */ import_react10.default.createElement(
28808
+ Drawer.Content,
28809
+ {
28810
+ className: contentClassName,
28811
+ "aria-label": title == null ? ariaLabel : void 0,
28812
+ "aria-labelledby": title == null ? ariaLabelledBy : void 0,
28813
+ "aria-describedby": description == null ? ariaDescribedBy : void 0
28814
+ },
28815
+ shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null,
28816
+ shouldRenderVanillaContent ? /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "" }, title != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Title, { style: titleVisuallyHidden ? VISUALLY_HIDDEN_STYLE : void 0 }, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: title })) : null, description != null ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Description, { style: descriptionVisuallyHidden ? VISUALLY_HIDDEN_STYLE : void 0 }, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: description })) : null, /* @__PURE__ */ import_react10.default.createElement(VanillaNode, { value: content, dataAttribute: "data-drawer-vanilla-body" })) : null
28817
+ )));
28763
28818
  }
28764
28819
 
28765
28820
  // src/vanilla/host.tsx
@@ -1334,6 +1334,30 @@ function getNextHandleState({ isDragging, preventCycle, shouldCancelInteraction,
1334
1334
  };
1335
1335
  }
1336
1336
 
1337
+ function isElementLike(target) {
1338
+ const element = target;
1339
+ return Boolean(element && typeof element.getAttribute === 'function' && typeof element.hasAttribute === 'function' && typeof element.closest === 'function');
1340
+ }
1341
+ function getDragTargetMetadata(target) {
1342
+ var _ref;
1343
+ const targetElement = isElementLike(target) ? target : null;
1344
+ const ancestors = [];
1345
+ let element = targetElement;
1346
+ while(element){
1347
+ ancestors.push({
1348
+ scrollHeight: element.scrollHeight,
1349
+ clientHeight: element.clientHeight,
1350
+ scrollTop: element.scrollTop,
1351
+ role: element.getAttribute('role')
1352
+ });
1353
+ element = element.parentElement;
1354
+ }
1355
+ return {
1356
+ targetTagName: (_ref = targetElement == null ? void 0 : targetElement.tagName) != null ? _ref : '',
1357
+ hasNoDragAttribute: (targetElement == null ? void 0 : targetElement.hasAttribute('data-drawer-no-drag')) || Boolean(targetElement == null ? void 0 : targetElement.closest('[data-drawer-no-drag]')),
1358
+ ancestors
1359
+ };
1360
+ }
1337
1361
  function getDragPermission({ targetTagName, hasNoDragAttribute, direction, timeSinceOpenMs, swipeAmount, hasHighlightedText, timeSinceLastPreventedMs, scrollLockTimeout, isDraggingInDirection, ancestors }) {
1338
1362
  if (targetTagName === 'SELECT' || hasNoDragAttribute) {
1339
1363
  return {
@@ -1496,6 +1520,24 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1496
1520
  noBodyStyles,
1497
1521
  autoFocus
1498
1522
  });
1523
+ React__namespace.default.useEffect(()=>{
1524
+ var _drawerRef_current;
1525
+ if (!isOpen || !modal || autoFocus || typeof document === 'undefined') {
1526
+ return;
1527
+ }
1528
+ const activeElement = document.activeElement;
1529
+ if (!(activeElement instanceof HTMLElement)) {
1530
+ return;
1531
+ }
1532
+ if (((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.contains(activeElement)) || activeElement.closest('[data-drawer]')) {
1533
+ return;
1534
+ }
1535
+ activeElement.blur();
1536
+ }, [
1537
+ autoFocus,
1538
+ isOpen,
1539
+ modal
1540
+ ]);
1499
1541
  function getScale() {
1500
1542
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
1501
1543
  }
@@ -1519,24 +1561,12 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
1519
1561
  }
1520
1562
  function shouldDrag(el, isDraggingInDirection) {
1521
1563
  var _window_getSelection;
1522
- let element = el;
1523
1564
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
1524
1565
  const date = new Date();
1525
- const ancestors = [];
1526
- // Keep climbing up the DOM tree as long as there's a parent
1527
- while(element){
1528
- ancestors.push({
1529
- scrollHeight: element.scrollHeight,
1530
- clientHeight: element.clientHeight,
1531
- scrollTop: element.scrollTop,
1532
- role: element.getAttribute('role')
1533
- });
1534
- // Move up to the parent element
1535
- element = element.parentNode;
1536
- }
1566
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
1537
1567
  const result = getDragPermission({
1538
- targetTagName: el.tagName,
1539
- hasNoDragAttribute: el.hasAttribute('data-drawer-no-drag') || Boolean(el.closest('[data-drawer-no-drag]')),
1568
+ targetTagName,
1569
+ hasNoDragAttribute,
1540
1570
  direction,
1541
1571
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
1542
1572
  swipeAmount,
@@ -2179,6 +2209,17 @@ function getParentNestedVisualState({ direction, viewportSize, hasOpenChild, per
2179
2209
  };
2180
2210
  }
2181
2211
 
2212
+ const VISUALLY_HIDDEN_STYLE = {
2213
+ position: 'absolute',
2214
+ width: '1px',
2215
+ height: '1px',
2216
+ padding: 0,
2217
+ margin: '-1px',
2218
+ overflow: 'hidden',
2219
+ clip: 'rect(0, 0, 0, 0)',
2220
+ whiteSpace: 'nowrap',
2221
+ border: 0
2222
+ };
2182
2223
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
2183
2224
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
2184
2225
  const baseProps = {
@@ -2208,7 +2249,7 @@ function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, i
2208
2249
  fadeFromIndex: undefined
2209
2250
  };
2210
2251
  }
2211
- function VanillaNode({ value }) {
2252
+ function VanillaNode({ value, dataAttribute }) {
2212
2253
  const ref = React__namespace.default.useRef(null);
2213
2254
  React__namespace.default.useEffect(()=>{
2214
2255
  const element = ref.current;
@@ -2234,14 +2275,17 @@ function VanillaNode({ value }) {
2234
2275
  return null;
2235
2276
  }
2236
2277
  return /*#__PURE__*/ React__namespace.default.createElement("div", {
2237
- "data-drawer-vanilla-node": "",
2278
+ ...dataAttribute ? {
2279
+ [dataAttribute]: ''
2280
+ } : {},
2238
2281
  ref: ref
2239
2282
  });
2240
2283
  }
2241
2284
  function VanillaDrawerRenderer({ options, open, onOpenChange, onDragChange, onReleaseChange }) {
2242
- const { mountElement: _mountElement, triggerElement: _triggerElement, triggerText, showHandle, handleClassName, title, description, content, overlayClassName, contentClassName, ...drawerOptions } = options;
2285
+ const { mountElement: _mountElement, triggerElement: _triggerElement, triggerText, showHandle, handleClassName, ariaLabel, ariaLabelledBy, ariaDescribedBy, title, titleVisuallyHidden, description, descriptionVisuallyHidden, content, overlayClassName, contentClassName, ...drawerOptions } = options;
2243
2286
  const rootProps = toReactDrawerProps(drawerOptions, open, onOpenChange, onDragChange, onReleaseChange);
2244
2287
  const shouldRenderHandle = Boolean(drawerOptions.handleOnly || showHandle);
2288
+ const shouldRenderVanillaContent = title != null || description != null || content != null;
2245
2289
  return /*#__PURE__*/ React__namespace.default.createElement(Drawer.Root, rootProps, triggerText ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Trigger, {
2246
2290
  asChild: true
2247
2291
  }, /*#__PURE__*/ React__namespace.default.createElement("button", {
@@ -2250,16 +2294,26 @@ function VanillaDrawerRenderer({ options, open, onOpenChange, onDragChange, onRe
2250
2294
  }, triggerText)) : null, /*#__PURE__*/ React__namespace.default.createElement(Drawer.Portal, null, /*#__PURE__*/ React__namespace.default.createElement(Drawer.Overlay, {
2251
2295
  className: overlayClassName
2252
2296
  }), /*#__PURE__*/ React__namespace.default.createElement(Drawer.Content, {
2253
- className: contentClassName
2297
+ className: contentClassName,
2298
+ "aria-label": title == null ? ariaLabel : undefined,
2299
+ "aria-labelledby": title == null ? ariaLabelledBy : undefined,
2300
+ "aria-describedby": description == null ? ariaDescribedBy : undefined
2254
2301
  }, shouldRenderHandle ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Handle, {
2255
2302
  className: handleClassName
2256
- }) : null, title != null ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Title, null, /*#__PURE__*/ React__namespace.default.createElement(VanillaNode, {
2303
+ }) : null, shouldRenderVanillaContent ? /*#__PURE__*/ React__namespace.default.createElement("div", {
2304
+ "data-drawer-vanilla-node": ""
2305
+ }, title != null ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Title, {
2306
+ style: titleVisuallyHidden ? VISUALLY_HIDDEN_STYLE : undefined
2307
+ }, /*#__PURE__*/ React__namespace.default.createElement(VanillaNode, {
2257
2308
  value: title
2258
- })) : null, description != null ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Description, null, /*#__PURE__*/ React__namespace.default.createElement(VanillaNode, {
2309
+ })) : null, description != null ? /*#__PURE__*/ React__namespace.default.createElement(Drawer.Description, {
2310
+ style: descriptionVisuallyHidden ? VISUALLY_HIDDEN_STYLE : undefined
2311
+ }, /*#__PURE__*/ React__namespace.default.createElement(VanillaNode, {
2259
2312
  value: description
2260
2313
  })) : null, /*#__PURE__*/ React__namespace.default.createElement(VanillaNode, {
2261
- value: content
2262
- }))));
2314
+ value: content,
2315
+ dataAttribute: "data-drawer-vanilla-body"
2316
+ })) : null)));
2263
2317
  }
2264
2318
 
2265
2319
  function canUseDOM$1() {