@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.
@@ -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,
@@ -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,
@@ -38,8 +38,13 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
38
38
  triggerText: StringConstructor;
39
39
  showHandle: BooleanConstructor;
40
40
  handleClassName: StringConstructor;
41
+ ariaLabel: StringConstructor;
42
+ ariaLabelledBy: StringConstructor;
43
+ ariaDescribedBy: StringConstructor;
41
44
  title: PropType<VanillaRenderable>;
45
+ titleVisuallyHidden: BooleanConstructor;
42
46
  description: PropType<VanillaRenderable>;
47
+ descriptionVisuallyHidden: BooleanConstructor;
43
48
  content: PropType<VanillaRenderable>;
44
49
  overlayClassName: StringConstructor;
45
50
  contentClassName: StringConstructor;
@@ -79,8 +84,13 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
79
84
  triggerText: StringConstructor;
80
85
  showHandle: BooleanConstructor;
81
86
  handleClassName: StringConstructor;
87
+ ariaLabel: StringConstructor;
88
+ ariaLabelledBy: StringConstructor;
89
+ ariaDescribedBy: StringConstructor;
82
90
  title: PropType<VanillaRenderable>;
91
+ titleVisuallyHidden: BooleanConstructor;
83
92
  description: PropType<VanillaRenderable>;
93
+ descriptionVisuallyHidden: BooleanConstructor;
84
94
  content: PropType<VanillaRenderable>;
85
95
  overlayClassName: StringConstructor;
86
96
  contentClassName: StringConstructor;
@@ -101,6 +111,8 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
101
111
  noBodyStyles: boolean;
102
112
  autoFocus: boolean;
103
113
  showHandle: boolean;
114
+ titleVisuallyHidden: boolean;
115
+ descriptionVisuallyHidden: boolean;
104
116
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
105
117
  declare const DrawerPlugin: Plugin;
106
118
 
@@ -38,8 +38,13 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
38
38
  triggerText: StringConstructor;
39
39
  showHandle: BooleanConstructor;
40
40
  handleClassName: StringConstructor;
41
+ ariaLabel: StringConstructor;
42
+ ariaLabelledBy: StringConstructor;
43
+ ariaDescribedBy: StringConstructor;
41
44
  title: PropType<VanillaRenderable>;
45
+ titleVisuallyHidden: BooleanConstructor;
42
46
  description: PropType<VanillaRenderable>;
47
+ descriptionVisuallyHidden: BooleanConstructor;
43
48
  content: PropType<VanillaRenderable>;
44
49
  overlayClassName: StringConstructor;
45
50
  contentClassName: StringConstructor;
@@ -79,8 +84,13 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
79
84
  triggerText: StringConstructor;
80
85
  showHandle: BooleanConstructor;
81
86
  handleClassName: StringConstructor;
87
+ ariaLabel: StringConstructor;
88
+ ariaLabelledBy: StringConstructor;
89
+ ariaDescribedBy: StringConstructor;
82
90
  title: PropType<VanillaRenderable>;
91
+ titleVisuallyHidden: BooleanConstructor;
83
92
  description: PropType<VanillaRenderable>;
93
+ descriptionVisuallyHidden: BooleanConstructor;
84
94
  content: PropType<VanillaRenderable>;
85
95
  overlayClassName: StringConstructor;
86
96
  contentClassName: StringConstructor;
@@ -101,6 +111,8 @@ declare const DrawerRoot: vue.DefineComponent<vue.ExtractPropTypes<{
101
111
  noBodyStyles: boolean;
102
112
  autoFocus: boolean;
103
113
  showHandle: boolean;
114
+ titleVisuallyHidden: boolean;
115
+ descriptionVisuallyHidden: boolean;
104
116
  }, {}, {}, {}, string, vue.ComponentProvideOptions, true, {}, any>;
105
117
  declare const DrawerPlugin: Plugin;
106
118
 
package/dist/vue/index.js CHANGED
@@ -27871,6 +27871,31 @@ function getNextHandleState({
27871
27871
  }
27872
27872
 
27873
27873
  // src/runtime/drag-policy.ts
27874
+ function isElementLike(target) {
27875
+ const element = target;
27876
+ return Boolean(
27877
+ element && typeof element.getAttribute === "function" && typeof element.hasAttribute === "function" && typeof element.closest === "function"
27878
+ );
27879
+ }
27880
+ function getDragTargetMetadata(target) {
27881
+ const targetElement = isElementLike(target) ? target : null;
27882
+ const ancestors = [];
27883
+ let element = targetElement;
27884
+ while (element) {
27885
+ ancestors.push({
27886
+ scrollHeight: element.scrollHeight,
27887
+ clientHeight: element.clientHeight,
27888
+ scrollTop: element.scrollTop,
27889
+ role: element.getAttribute("role")
27890
+ });
27891
+ element = element.parentElement;
27892
+ }
27893
+ return {
27894
+ targetTagName: targetElement?.tagName ?? "",
27895
+ hasNoDragAttribute: targetElement?.hasAttribute("data-drawer-no-drag") || Boolean(targetElement?.closest("[data-drawer-no-drag]")),
27896
+ ancestors
27897
+ };
27898
+ }
27874
27899
  function getDragPermission({
27875
27900
  targetTagName,
27876
27901
  hasNoDragAttribute,
@@ -28051,6 +28076,19 @@ function Root2({
28051
28076
  noBodyStyles,
28052
28077
  autoFocus
28053
28078
  });
28079
+ import_react9.default.useEffect(() => {
28080
+ if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28081
+ return;
28082
+ }
28083
+ const activeElement = document.activeElement;
28084
+ if (!(activeElement instanceof HTMLElement)) {
28085
+ return;
28086
+ }
28087
+ if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28088
+ return;
28089
+ }
28090
+ activeElement.blur();
28091
+ }, [autoFocus, isOpen, modal]);
28054
28092
  function getScale() {
28055
28093
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28056
28094
  }
@@ -28068,22 +28106,12 @@ function Root2({
28068
28106
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
28069
28107
  }
28070
28108
  function shouldDrag(el, isDraggingInDirection) {
28071
- let element = el;
28072
28109
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
28073
28110
  const date = /* @__PURE__ */ new Date();
28074
- const ancestors = [];
28075
- while (element) {
28076
- ancestors.push({
28077
- scrollHeight: element.scrollHeight,
28078
- clientHeight: element.clientHeight,
28079
- scrollTop: element.scrollTop,
28080
- role: element.getAttribute("role")
28081
- });
28082
- element = element.parentNode;
28083
- }
28111
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
28084
28112
  const result = getDragPermission({
28085
- targetTagName: el.tagName,
28086
- hasNoDragAttribute: el.hasAttribute("data-drawer-no-drag") || Boolean(el.closest("[data-drawer-no-drag]")),
28113
+ targetTagName,
28114
+ hasNoDragAttribute,
28087
28115
  direction,
28088
28116
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
28089
28117
  swipeAmount,
@@ -28712,6 +28740,17 @@ var Drawer = {
28712
28740
  };
28713
28741
 
28714
28742
  // src/vanilla/render.tsx
28743
+ var VISUALLY_HIDDEN_STYLE = {
28744
+ position: "absolute",
28745
+ width: "1px",
28746
+ height: "1px",
28747
+ padding: 0,
28748
+ margin: "-1px",
28749
+ overflow: "hidden",
28750
+ clip: "rect(0, 0, 0, 0)",
28751
+ whiteSpace: "nowrap",
28752
+ border: 0
28753
+ };
28715
28754
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28716
28755
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28717
28756
  const baseProps = {
@@ -28740,7 +28779,7 @@ function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, i
28740
28779
  fadeFromIndex: void 0
28741
28780
  };
28742
28781
  }
28743
- function VanillaNode({ value }) {
28782
+ function VanillaNode({ value, dataAttribute }) {
28744
28783
  const ref = import_react10.default.useRef(null);
28745
28784
  import_react10.default.useEffect(() => {
28746
28785
  const element = ref.current;
@@ -28763,7 +28802,7 @@ function VanillaNode({ value }) {
28763
28802
  if (value == null) {
28764
28803
  return null;
28765
28804
  }
28766
- return /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "", ref });
28805
+ return /* @__PURE__ */ import_react10.default.createElement("div", { ...dataAttribute ? { [dataAttribute]: "" } : {}, ref });
28767
28806
  }
28768
28807
  function VanillaDrawerRenderer({
28769
28808
  options,
@@ -28778,8 +28817,13 @@ function VanillaDrawerRenderer({
28778
28817
  triggerText,
28779
28818
  showHandle,
28780
28819
  handleClassName,
28820
+ ariaLabel,
28821
+ ariaLabelledBy,
28822
+ ariaDescribedBy,
28781
28823
  title,
28824
+ titleVisuallyHidden,
28782
28825
  description,
28826
+ descriptionVisuallyHidden,
28783
28827
  content,
28784
28828
  overlayClassName,
28785
28829
  contentClassName,
@@ -28787,7 +28831,18 @@ function VanillaDrawerRenderer({
28787
28831
  } = options;
28788
28832
  const rootProps = toReactDrawerProps(drawerOptions, open, onOpenChange, onDragChange, onReleaseChange);
28789
28833
  const shouldRenderHandle = Boolean(drawerOptions.handleOnly || showHandle);
28790
- 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 }))));
28834
+ const shouldRenderVanillaContent = title != null || description != null || content != null;
28835
+ 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(
28836
+ Drawer.Content,
28837
+ {
28838
+ className: contentClassName,
28839
+ "aria-label": title == null ? ariaLabel : void 0,
28840
+ "aria-labelledby": title == null ? ariaLabelledBy : void 0,
28841
+ "aria-describedby": description == null ? ariaDescribedBy : void 0
28842
+ },
28843
+ shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null,
28844
+ 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
28845
+ )));
28791
28846
  }
28792
28847
 
28793
28848
  // src/vanilla/host.tsx
@@ -29227,8 +29282,13 @@ var drawerProps = {
29227
29282
  triggerText: String,
29228
29283
  showHandle: Boolean,
29229
29284
  handleClassName: String,
29285
+ ariaLabel: String,
29286
+ ariaLabelledBy: String,
29287
+ ariaDescribedBy: String,
29230
29288
  title: [String, Number, Object, Function],
29289
+ titleVisuallyHidden: Boolean,
29231
29290
  description: [String, Number, Object, Function],
29291
+ descriptionVisuallyHidden: Boolean,
29232
29292
  content: [String, Number, Object, Function],
29233
29293
  overlayClassName: String,
29234
29294
  contentClassName: String
@@ -29289,8 +29349,13 @@ var DrawerRoot = (0, import_vue.defineComponent)({
29289
29349
  triggerText: props.triggerText,
29290
29350
  showHandle: props.showHandle,
29291
29351
  handleClassName: props.handleClassName,
29352
+ ariaLabel: props.ariaLabel,
29353
+ ariaLabelledBy: props.ariaLabelledBy,
29354
+ ariaDescribedBy: props.ariaDescribedBy,
29292
29355
  title: props.title,
29356
+ titleVisuallyHidden: props.titleVisuallyHidden,
29293
29357
  description: props.description,
29358
+ descriptionVisuallyHidden: props.descriptionVisuallyHidden,
29294
29359
  content: props.content,
29295
29360
  overlayClassName: props.overlayClassName,
29296
29361
  contentClassName: props.contentClassName
@@ -27846,6 +27846,31 @@ function getNextHandleState({
27846
27846
  }
27847
27847
 
27848
27848
  // src/runtime/drag-policy.ts
27849
+ function isElementLike(target) {
27850
+ const element = target;
27851
+ return Boolean(
27852
+ element && typeof element.getAttribute === "function" && typeof element.hasAttribute === "function" && typeof element.closest === "function"
27853
+ );
27854
+ }
27855
+ function getDragTargetMetadata(target) {
27856
+ const targetElement = isElementLike(target) ? target : null;
27857
+ const ancestors = [];
27858
+ let element = targetElement;
27859
+ while (element) {
27860
+ ancestors.push({
27861
+ scrollHeight: element.scrollHeight,
27862
+ clientHeight: element.clientHeight,
27863
+ scrollTop: element.scrollTop,
27864
+ role: element.getAttribute("role")
27865
+ });
27866
+ element = element.parentElement;
27867
+ }
27868
+ return {
27869
+ targetTagName: targetElement?.tagName ?? "",
27870
+ hasNoDragAttribute: targetElement?.hasAttribute("data-drawer-no-drag") || Boolean(targetElement?.closest("[data-drawer-no-drag]")),
27871
+ ancestors
27872
+ };
27873
+ }
27849
27874
  function getDragPermission({
27850
27875
  targetTagName,
27851
27876
  hasNoDragAttribute,
@@ -28026,6 +28051,19 @@ function Root2({
28026
28051
  noBodyStyles,
28027
28052
  autoFocus
28028
28053
  });
28054
+ import_react9.default.useEffect(() => {
28055
+ if (!isOpen || !modal || autoFocus || typeof document === "undefined") {
28056
+ return;
28057
+ }
28058
+ const activeElement = document.activeElement;
28059
+ if (!(activeElement instanceof HTMLElement)) {
28060
+ return;
28061
+ }
28062
+ if (drawerRef.current?.contains(activeElement) || activeElement.closest("[data-drawer]")) {
28063
+ return;
28064
+ }
28065
+ activeElement.blur();
28066
+ }, [autoFocus, isOpen, modal]);
28029
28067
  function getScale() {
28030
28068
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
28031
28069
  }
@@ -28043,22 +28081,12 @@ function Root2({
28043
28081
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
28044
28082
  }
28045
28083
  function shouldDrag(el, isDraggingInDirection) {
28046
- let element = el;
28047
28084
  const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
28048
28085
  const date = /* @__PURE__ */ new Date();
28049
- const ancestors = [];
28050
- while (element) {
28051
- ancestors.push({
28052
- scrollHeight: element.scrollHeight,
28053
- clientHeight: element.clientHeight,
28054
- scrollTop: element.scrollTop,
28055
- role: element.getAttribute("role")
28056
- });
28057
- element = element.parentNode;
28058
- }
28086
+ const { targetTagName, hasNoDragAttribute, ancestors } = getDragTargetMetadata(el);
28059
28087
  const result = getDragPermission({
28060
- targetTagName: el.tagName,
28061
- hasNoDragAttribute: el.hasAttribute("data-drawer-no-drag") || Boolean(el.closest("[data-drawer-no-drag]")),
28088
+ targetTagName,
28089
+ hasNoDragAttribute,
28062
28090
  direction,
28063
28091
  timeSinceOpenMs: openTime.current ? date.getTime() - openTime.current.getTime() : null,
28064
28092
  swipeAmount,
@@ -28687,6 +28715,17 @@ var Drawer = {
28687
28715
  };
28688
28716
 
28689
28717
  // src/vanilla/render.tsx
28718
+ var VISUALLY_HIDDEN_STYLE = {
28719
+ position: "absolute",
28720
+ width: "1px",
28721
+ height: "1px",
28722
+ padding: 0,
28723
+ margin: "-1px",
28724
+ overflow: "hidden",
28725
+ clip: "rect(0, 0, 0, 0)",
28726
+ whiteSpace: "nowrap",
28727
+ border: 0
28728
+ };
28690
28729
  function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, internalOnReleaseChange) {
28691
28730
  const { id: _id, parentId: _parentId, onDragChange, onReleaseChange, ...drawerOptions } = options;
28692
28731
  const baseProps = {
@@ -28715,7 +28754,7 @@ function toReactDrawerProps(options, open, onOpenChange, internalOnDragChange, i
28715
28754
  fadeFromIndex: void 0
28716
28755
  };
28717
28756
  }
28718
- function VanillaNode({ value }) {
28757
+ function VanillaNode({ value, dataAttribute }) {
28719
28758
  const ref = import_react10.default.useRef(null);
28720
28759
  import_react10.default.useEffect(() => {
28721
28760
  const element = ref.current;
@@ -28738,7 +28777,7 @@ function VanillaNode({ value }) {
28738
28777
  if (value == null) {
28739
28778
  return null;
28740
28779
  }
28741
- return /* @__PURE__ */ import_react10.default.createElement("div", { "data-drawer-vanilla-node": "", ref });
28780
+ return /* @__PURE__ */ import_react10.default.createElement("div", { ...dataAttribute ? { [dataAttribute]: "" } : {}, ref });
28742
28781
  }
28743
28782
  function VanillaDrawerRenderer({
28744
28783
  options,
@@ -28753,8 +28792,13 @@ function VanillaDrawerRenderer({
28753
28792
  triggerText,
28754
28793
  showHandle,
28755
28794
  handleClassName,
28795
+ ariaLabel,
28796
+ ariaLabelledBy,
28797
+ ariaDescribedBy,
28756
28798
  title,
28799
+ titleVisuallyHidden,
28757
28800
  description,
28801
+ descriptionVisuallyHidden,
28758
28802
  content,
28759
28803
  overlayClassName,
28760
28804
  contentClassName,
@@ -28762,7 +28806,18 @@ function VanillaDrawerRenderer({
28762
28806
  } = options;
28763
28807
  const rootProps = toReactDrawerProps(drawerOptions, open, onOpenChange, onDragChange, onReleaseChange);
28764
28808
  const shouldRenderHandle = Boolean(drawerOptions.handleOnly || showHandle);
28765
- 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 }))));
28809
+ const shouldRenderVanillaContent = title != null || description != null || content != null;
28810
+ 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(
28811
+ Drawer.Content,
28812
+ {
28813
+ className: contentClassName,
28814
+ "aria-label": title == null ? ariaLabel : void 0,
28815
+ "aria-labelledby": title == null ? ariaLabelledBy : void 0,
28816
+ "aria-describedby": description == null ? ariaDescribedBy : void 0
28817
+ },
28818
+ shouldRenderHandle ? /* @__PURE__ */ import_react10.default.createElement(Drawer.Handle, { className: handleClassName }) : null,
28819
+ 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
28820
+ )));
28766
28821
  }
28767
28822
 
28768
28823
  // src/vanilla/host.tsx
@@ -29202,8 +29257,13 @@ var drawerProps = {
29202
29257
  triggerText: String,
29203
29258
  showHandle: Boolean,
29204
29259
  handleClassName: String,
29260
+ ariaLabel: String,
29261
+ ariaLabelledBy: String,
29262
+ ariaDescribedBy: String,
29205
29263
  title: [String, Number, Object, Function],
29264
+ titleVisuallyHidden: Boolean,
29206
29265
  description: [String, Number, Object, Function],
29266
+ descriptionVisuallyHidden: Boolean,
29207
29267
  content: [String, Number, Object, Function],
29208
29268
  overlayClassName: String,
29209
29269
  contentClassName: String
@@ -29264,8 +29324,13 @@ var DrawerRoot = defineComponent({
29264
29324
  triggerText: props.triggerText,
29265
29325
  showHandle: props.showHandle,
29266
29326
  handleClassName: props.handleClassName,
29327
+ ariaLabel: props.ariaLabel,
29328
+ ariaLabelledBy: props.ariaLabelledBy,
29329
+ ariaDescribedBy: props.ariaDescribedBy,
29267
29330
  title: props.title,
29331
+ titleVisuallyHidden: props.titleVisuallyHidden,
29268
29332
  description: props.description,
29333
+ descriptionVisuallyHidden: props.descriptionVisuallyHidden,
29269
29334
  content: props.content,
29270
29335
  overlayClassName: props.overlayClassName,
29271
29336
  contentClassName: props.contentClassName
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samline/drawer",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "A universal drawer package for React, Vue, Svelte, vanilla JS, and browser usage.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",