@expcat/tigercat-react 2.0.0 → 2.0.19

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.
Files changed (64) hide show
  1. package/dist/{chunk-JTFNGXOC.mjs → chunk-2ENQZECC.mjs} +53 -31
  2. package/dist/{chunk-O5RAMCBV.mjs → chunk-2JYJPNW3.mjs} +1 -1
  3. package/dist/{chunk-NBQ3Q6DD.mjs → chunk-2WGEHH5A.mjs} +1 -1
  4. package/dist/{chunk-K7MYQISG.mjs → chunk-54HN5BXW.mjs} +10 -4
  5. package/dist/{chunk-C6QK5MJT.mjs → chunk-5CKMYMTS.mjs} +1 -1
  6. package/dist/{chunk-Y7K27DVV.mjs → chunk-6H5Y7Y6E.mjs} +42 -28
  7. package/dist/chunk-6MGQAJ62.mjs +203 -0
  8. package/dist/{chunk-TO2URY7X.mjs → chunk-7AFRHC7P.mjs} +90 -61
  9. package/dist/{chunk-MGQWVJHX.mjs → chunk-ALSOPYM5.mjs} +69 -62
  10. package/dist/{chunk-YCKY72BW.mjs → chunk-BOGOQ44C.mjs} +1 -1
  11. package/dist/{chunk-Q327ESD2.mjs → chunk-BUXHI6UK.mjs} +17 -38
  12. package/dist/{chunk-TORX7SG4.mjs → chunk-CC7IOSNI.mjs} +10 -4
  13. package/dist/{chunk-OVE2ZUJJ.mjs → chunk-D33BIMGK.mjs} +1 -1
  14. package/dist/{chunk-PYDWF4ED.mjs → chunk-D3KP72UC.mjs} +34 -9
  15. package/dist/{chunk-ZEP7I6WB.mjs → chunk-DPWRXXXW.mjs} +16 -8
  16. package/dist/chunk-HKAZXG74.mjs +308 -0
  17. package/dist/{chunk-QWUDJC6K.mjs → chunk-HOYBHB7B.mjs} +38 -17
  18. package/dist/{chunk-3RY6M4AK.mjs → chunk-HS6KUPTI.mjs} +1 -1
  19. package/dist/{chunk-EKESN747.mjs → chunk-HSBN5MLS.mjs} +1 -1
  20. package/dist/{chunk-AJJJ6HWC.mjs → chunk-K4GIKSZE.mjs} +1 -1
  21. package/dist/{chunk-2UOGBS3C.mjs → chunk-KP6DEYWB.mjs} +27 -6
  22. package/dist/{chunk-PAN256RW.mjs → chunk-KVCI2346.mjs} +59 -55
  23. package/dist/{chunk-LBXNMCXN.mjs → chunk-OZ5XLR22.mjs} +6 -1
  24. package/dist/{chunk-5RVLBNLI.mjs → chunk-RJPNBYK5.mjs} +4 -4
  25. package/dist/{chunk-HELLYIX2.mjs → chunk-V6P7ZK6O.mjs} +3 -3
  26. package/dist/{chunk-4XGO3OSE.mjs → chunk-XE4YFBOZ.mjs} +12 -17
  27. package/dist/{chunk-YI7NQWUV.mjs → chunk-YI6YWH66.mjs} +14 -30
  28. package/dist/{chunk-SHCBCM2W.mjs → chunk-YIB6ZXZF.mjs} +142 -105
  29. package/dist/{chunk-SZBYEGKU.mjs → chunk-ZCGIZOMT.mjs} +1 -1
  30. package/dist/{chunk-S7IB6YST.mjs → chunk-ZG56T75O.mjs} +25 -40
  31. package/dist/{chunk-44BPUG24.mjs → chunk-ZH5ZBLAN.mjs} +38 -16
  32. package/dist/components/ActivityFeed.mjs +3 -3
  33. package/dist/components/AutoComplete.mjs +2 -1
  34. package/dist/components/Cascader.mjs +2 -1
  35. package/dist/components/CodeEditor.mjs +1 -1
  36. package/dist/components/ColorPicker.mjs +2 -1
  37. package/dist/components/CropUpload.mjs +3 -3
  38. package/dist/components/DataExport.mjs +3 -3
  39. package/dist/components/DataTableWithToolbar.mjs +6 -6
  40. package/dist/components/DatePicker.mjs +2 -1
  41. package/dist/components/Drawer.mjs +2 -2
  42. package/dist/components/Dropdown.mjs +2 -2
  43. package/dist/components/FormItem.mjs +2 -1
  44. package/dist/components/Image.mjs +5 -5
  45. package/dist/components/ImageGroup.mjs +3 -3
  46. package/dist/components/ImagePreview.mjs +2 -2
  47. package/dist/components/Loading.mjs +2 -2
  48. package/dist/components/Mentions.mjs +2 -1
  49. package/dist/components/Menu.mjs +2 -2
  50. package/dist/components/Modal.mjs +2 -2
  51. package/dist/components/NotificationCenter.mjs +3 -3
  52. package/dist/components/Popconfirm.mjs +3 -3
  53. package/dist/components/Popover.mjs +3 -3
  54. package/dist/components/Select.mjs +2 -1
  55. package/dist/components/Spotlight.mjs +2 -2
  56. package/dist/components/Table.mjs +3 -2
  57. package/dist/components/TimePicker.mjs +2 -1
  58. package/dist/components/Tooltip.mjs +3 -3
  59. package/dist/components/Tour.mjs +2 -2
  60. package/dist/components/TreeSelect.mjs +2 -1
  61. package/dist/index.mjs +5 -2
  62. package/package.json +2 -2
  63. package/dist/chunk-KVARQQAG.mjs +0 -181
  64. package/dist/chunk-SEWNVIHH.mjs +0 -153
@@ -1,9 +1,13 @@
1
+ import {
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
1
5
  import {
2
6
  useTigerConfig
3
7
  } from "./chunk-YSIXURBW.mjs";
4
8
 
5
9
  // src/components/TreeSelect.tsx
6
- import { useState, useMemo, useRef, useEffect, useId } from "react";
10
+ import { useState, useMemo, useRef, useId } from "react";
7
11
  import {
8
12
  resolveLocaleText,
9
13
  mergeTigerLocale,
@@ -84,6 +88,21 @@ var TreeSelect = (props) => {
84
88
  () => defaultExpandAll ? new Set(getAllTreeSelectKeys(treeData)) : /* @__PURE__ */ new Set()
85
89
  );
86
90
  const containerRef = useRef(null);
91
+ const triggerRef = useRef(null);
92
+ const dropdownRef = useRef(null);
93
+ const overlay = useAnchoredOverlay({
94
+ enabled: isOpen,
95
+ referenceRef: triggerRef,
96
+ floatingRef: dropdownRef,
97
+ containerRef,
98
+ placement: "bottom-start",
99
+ offset: 4,
100
+ matchReferenceWidth: true,
101
+ dismissOnOutside: true,
102
+ dismissOnEscape: true,
103
+ restoreFocusOnDismiss: true,
104
+ onDismiss: closeDropdown
105
+ });
87
106
  const displayLabel = useMemo(() => getTreeSelectDisplayLabel(treeData, value), [treeData, value]);
88
107
  const showClearButton = clearable && !disabled && value !== void 0 && (Array.isArray(value) ? value.length > 0 : value !== "");
89
108
  const matchedKeys = useMemo(() => {
@@ -162,20 +181,11 @@ var TreeSelect = (props) => {
162
181
  closeDropdown();
163
182
  }
164
183
  }
165
- useEffect(() => {
166
- if (!isOpen) return;
167
- function handleClickOutside(e) {
168
- if (containerRef.current && !containerRef.current.contains(e.target)) {
169
- closeDropdown();
170
- }
171
- }
172
- document.addEventListener("click", handleClickOutside);
173
- return () => document.removeEventListener("click", handleClickOutside);
174
- }, [isOpen]);
175
184
  return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: classNames(treeSelectBaseClasses, className), ...divProps, children: [
176
185
  /* @__PURE__ */ jsxs(
177
186
  "button",
178
187
  {
188
+ ref: triggerRef,
179
189
  type: "button",
180
190
  className: getTreeSelectTriggerClasses(size, disabled, isOpen),
181
191
  ...getPickerComboboxAria({ expanded: isOpen, listboxId }),
@@ -223,58 +233,77 @@ var TreeSelect = (props) => {
223
233
  ]
224
234
  }
225
235
  ),
226
- isOpen && /* @__PURE__ */ jsxs("div", { ...getPickerListboxAria({ id: listboxId }), className: treeSelectDropdownClasses, children: [
227
- searchable && /* @__PURE__ */ jsx(
228
- "input",
236
+ renderOverlayPortal(
237
+ isOpen ? /* @__PURE__ */ jsxs(
238
+ "div",
229
239
  {
230
- type: "text",
231
- className: treeSelectSearchClasses,
232
- placeholder: resolveLocaleText("Search...", mergedLocale?.common?.searchPlaceholder),
233
- value: searchQuery,
234
- "aria-label": resolveLocaleText("Search tree", mergedLocale?.common?.searchPlaceholder),
235
- onChange: (e) => updateSearchValue(e.target.value)
236
- }
237
- ),
238
- visibleNodes.length > 0 ? visibleNodes.map((flatNode) => {
239
- const { node, level, hasChildren, isExpanded } = flatNode;
240
- const selected = isSelected(node.key);
241
- const indent = level * 20;
242
- return /* @__PURE__ */ jsxs(
243
- "div",
244
- {
245
- ...getPickerOptionAria({ selected, disabled: !!node.disabled }),
246
- className: getTreeSelectNodeClasses(selected, !!node.disabled, size),
247
- style: { paddingLeft: `${indent + 8}px` },
248
- onClick: (e) => {
249
- e.stopPropagation();
250
- handleNodeSelect(node);
251
- },
252
- children: [
253
- hasChildren ? /* @__PURE__ */ jsx(
254
- "span",
240
+ ref: dropdownRef,
241
+ ...getPickerListboxAria({ id: listboxId }),
242
+ className: classNames(treeSelectDropdownClasses, overlay.floatingClasses),
243
+ style: overlay.floatingStyles,
244
+ "data-positioned": overlay.positioned,
245
+ children: [
246
+ searchable && /* @__PURE__ */ jsx(
247
+ "input",
248
+ {
249
+ type: "text",
250
+ className: treeSelectSearchClasses,
251
+ placeholder: resolveLocaleText(
252
+ "Search...",
253
+ mergedLocale?.common?.searchPlaceholder
254
+ ),
255
+ value: searchQuery,
256
+ "aria-label": resolveLocaleText(
257
+ "Search tree",
258
+ mergedLocale?.common?.searchPlaceholder
259
+ ),
260
+ onChange: (e) => updateSearchValue(e.target.value)
261
+ }
262
+ ),
263
+ visibleNodes.length > 0 ? visibleNodes.map((flatNode) => {
264
+ const { node, level, hasChildren, isExpanded } = flatNode;
265
+ const selected = isSelected(node.key);
266
+ const indent = level * 20;
267
+ return /* @__PURE__ */ jsxs(
268
+ "div",
255
269
  {
256
- className: classNames(
257
- "inline-flex items-center justify-center w-4 h-4 mr-1 transition-transform",
258
- isExpanded ? "rotate-90" : ""
259
- ),
260
- onClick: (e) => toggleExpand(node.key, e),
261
- children: /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", viewBox: icon20ViewBox, fill: "currentColor", children: /* @__PURE__ */ jsx(
262
- "path",
263
- {
264
- d: chevronRightSolidIcon20PathD,
265
- fillRule: "evenodd",
266
- clipRule: "evenodd"
267
- }
268
- ) })
269
- }
270
- ) : /* @__PURE__ */ jsx("span", { className: "w-4 mr-1" }),
271
- /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: node.label })
272
- ]
273
- },
274
- String(node.key)
275
- );
276
- }) : /* @__PURE__ */ jsx("div", { className: treeSelectEmptyClasses, children: resolveLocaleText("No data", emptyText, mergedLocale?.common?.emptyText) })
277
- ] })
270
+ ...getPickerOptionAria({ selected, disabled: !!node.disabled }),
271
+ className: getTreeSelectNodeClasses(selected, !!node.disabled, size),
272
+ style: { paddingLeft: `${indent + 8}px` },
273
+ onClick: (e) => {
274
+ e.stopPropagation();
275
+ handleNodeSelect(node);
276
+ },
277
+ children: [
278
+ hasChildren ? /* @__PURE__ */ jsx(
279
+ "span",
280
+ {
281
+ className: classNames(
282
+ "inline-flex items-center justify-center w-4 h-4 mr-1 transition-transform",
283
+ isExpanded ? "rotate-90" : ""
284
+ ),
285
+ onClick: (e) => toggleExpand(node.key, e),
286
+ children: /* @__PURE__ */ jsx("svg", { className: "w-3 h-3", viewBox: icon20ViewBox, fill: "currentColor", children: /* @__PURE__ */ jsx(
287
+ "path",
288
+ {
289
+ d: chevronRightSolidIcon20PathD,
290
+ fillRule: "evenodd",
291
+ clipRule: "evenodd"
292
+ }
293
+ ) })
294
+ }
295
+ ) : /* @__PURE__ */ jsx("span", { className: "w-4 mr-1" }),
296
+ /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: node.label })
297
+ ]
298
+ },
299
+ String(node.key)
300
+ );
301
+ }) : /* @__PURE__ */ jsx("div", { className: treeSelectEmptyClasses, children: resolveLocaleText("No data", emptyText, mergedLocale?.common?.emptyText) })
302
+ ]
303
+ }
304
+ ) : null,
305
+ overlay.target
306
+ )
278
307
  ] });
279
308
  };
280
309
 
@@ -1,6 +1,10 @@
1
1
  import {
2
2
  useControlledState
3
3
  } from "./chunk-MEFARVQI.mjs";
4
+ import {
5
+ renderOverlayPortal,
6
+ useAnchoredOverlay
7
+ } from "./chunk-HKAZXG74.mjs";
4
8
  import {
5
9
  useTigerConfig
6
10
  } from "./chunk-YSIXURBW.mjs";
@@ -316,19 +320,6 @@ function useTimePickerState(allProps) {
316
320
  const handleInputClick = () => {
317
321
  togglePanel();
318
322
  };
319
- useEffect(() => {
320
- const handleClickOutside = (event) => {
321
- if (panelRef.current && inputWrapperRef.current && !panelRef.current.contains(event.target) && !inputWrapperRef.current.contains(event.target)) {
322
- closePanel();
323
- }
324
- };
325
- if (isOpen) {
326
- document.addEventListener("click", handleClickOutside);
327
- return () => {
328
- document.removeEventListener("click", handleClickOutside);
329
- };
330
- }
331
- }, [isOpen]);
332
323
  useEffect(() => {
333
324
  if (!isOpen) return;
334
325
  const panel = panelRef.current;
@@ -599,6 +590,17 @@ var Icon = ({ path, className }) => /* @__PURE__ */ jsx3(
599
590
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
600
591
  var TimePicker = (allProps) => {
601
592
  const ctx = useTimePickerState(allProps);
593
+ const overlay = useAnchoredOverlay({
594
+ enabled: ctx.isOpen,
595
+ referenceRef: ctx.inputWrapperRef,
596
+ floatingRef: ctx.panelRef,
597
+ placement: "bottom-start",
598
+ offset: 4,
599
+ layout: "bottom-sheet-sm",
600
+ dismissOnOutside: true,
601
+ dismissOnEscape: true,
602
+ onDismiss: ctx.closePanel
603
+ });
602
604
  return /* @__PURE__ */ jsxs3("div", { className: ctx.containerClasses, ...ctx.divProps, children: [
603
605
  /* @__PURE__ */ jsxs3("div", { ref: ctx.inputWrapperRef, className: timePickerInputWrapperClasses, children: [
604
606
  /* @__PURE__ */ jsx4(
@@ -640,55 +642,60 @@ var TimePicker = (allProps) => {
640
642
  }
641
643
  )
642
644
  ] }),
643
- ctx.isOpen && /* @__PURE__ */ jsxs3(
644
- "div",
645
- {
646
- ref: ctx.panelRef,
647
- className: timePickerPanelClasses,
648
- role: "dialog",
649
- "aria-label": ctx.labels.dialog,
650
- onKeyDown: ctx.handlePanelKeyDown,
651
- children: [
652
- ctx.isRangeMode && /* @__PURE__ */ jsxs3("div", { className: timePickerRangeHeaderClasses, children: [
653
- /* @__PURE__ */ jsx4(
654
- "button",
655
- {
656
- type: "button",
657
- className: getTimePickerRangeTabButtonClasses(ctx.activePart === "start"),
658
- onClick: () => ctx.setActivePart("start"),
659
- "aria-label": ctx.labels.start,
660
- "aria-selected": ctx.activePart === "start",
661
- children: ctx.labels.start
662
- }
663
- ),
664
- /* @__PURE__ */ jsx4(
665
- "button",
666
- {
667
- type: "button",
668
- className: getTimePickerRangeTabButtonClasses(ctx.activePart === "end"),
669
- onClick: () => ctx.setActivePart("end"),
670
- "aria-label": ctx.labels.end,
671
- "aria-selected": ctx.activePart === "end",
672
- children: ctx.labels.end
673
- }
674
- )
675
- ] }),
676
- renderTimePickerMobile(ctx),
677
- renderTimePickerDesktop(ctx),
678
- /* @__PURE__ */ jsxs3("div", { className: timePickerFooterClasses, children: [
679
- /* @__PURE__ */ jsx4("button", { type: "button", className: timePickerFooterButtonClasses, onClick: ctx.setNow, children: ctx.labels.now }),
680
- /* @__PURE__ */ jsx4(
681
- "button",
682
- {
683
- type: "button",
684
- className: timePickerFooterButtonClasses,
685
- onClick: ctx.closePanel,
686
- children: ctx.labels.ok
687
- }
688
- )
689
- ] })
690
- ]
691
- }
645
+ renderOverlayPortal(
646
+ ctx.isOpen ? /* @__PURE__ */ jsxs3(
647
+ "div",
648
+ {
649
+ ref: ctx.panelRef,
650
+ className: `${timePickerPanelClasses} ${overlay.floatingClasses}`,
651
+ style: overlay.floatingStyles,
652
+ "data-positioned": overlay.positioned,
653
+ role: "dialog",
654
+ "aria-label": ctx.labels.dialog,
655
+ onKeyDown: ctx.handlePanelKeyDown,
656
+ children: [
657
+ ctx.isRangeMode && /* @__PURE__ */ jsxs3("div", { className: timePickerRangeHeaderClasses, children: [
658
+ /* @__PURE__ */ jsx4(
659
+ "button",
660
+ {
661
+ type: "button",
662
+ className: getTimePickerRangeTabButtonClasses(ctx.activePart === "start"),
663
+ onClick: () => ctx.setActivePart("start"),
664
+ "aria-label": ctx.labels.start,
665
+ "aria-selected": ctx.activePart === "start",
666
+ children: ctx.labels.start
667
+ }
668
+ ),
669
+ /* @__PURE__ */ jsx4(
670
+ "button",
671
+ {
672
+ type: "button",
673
+ className: getTimePickerRangeTabButtonClasses(ctx.activePart === "end"),
674
+ onClick: () => ctx.setActivePart("end"),
675
+ "aria-label": ctx.labels.end,
676
+ "aria-selected": ctx.activePart === "end",
677
+ children: ctx.labels.end
678
+ }
679
+ )
680
+ ] }),
681
+ renderTimePickerMobile(ctx),
682
+ renderTimePickerDesktop(ctx),
683
+ /* @__PURE__ */ jsxs3("div", { className: timePickerFooterClasses, children: [
684
+ /* @__PURE__ */ jsx4("button", { type: "button", className: timePickerFooterButtonClasses, onClick: ctx.setNow, children: ctx.labels.now }),
685
+ /* @__PURE__ */ jsx4(
686
+ "button",
687
+ {
688
+ type: "button",
689
+ className: timePickerFooterButtonClasses,
690
+ onClick: ctx.closePanel,
691
+ children: ctx.labels.ok
692
+ }
693
+ )
694
+ ] })
695
+ ]
696
+ }
697
+ ) : null,
698
+ overlay.target
692
699
  )
693
700
  ] });
694
701
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Select
3
- } from "./chunk-PAN256RW.mjs";
3
+ } from "./chunk-KVCI2346.mjs";
4
4
  import {
5
5
  Radio
6
6
  } from "./chunk-IIWUQK2P.mjs";
@@ -1,7 +1,7 @@
1
1
  import {
2
- renderBodyPortal,
3
- useFloating
4
- } from "./chunk-SEWNVIHH.mjs";
2
+ renderOverlayPortal,
3
+ useAnchoredOverlay
4
+ } from "./chunk-HKAZXG74.mjs";
5
5
 
6
6
  // src/components/Menu.tsx
7
7
  import React5 from "react";
@@ -268,8 +268,6 @@ import React4, { useState as useState2, useMemo as useMemo2, useCallback as useC
268
268
  import {
269
269
  classNames as classNames3,
270
270
  getSubMenuTitleClasses,
271
- getSubmenuPopupZIndex,
272
- getTransformOrigin,
273
271
  getMenuItemIndent as getMenuItemIndent2,
274
272
  isKeyOpen,
275
273
  menuItemIconClasses as menuItemIconClasses2,
@@ -367,16 +365,18 @@ var SubMenu = ({
367
365
  const isExpanded = isPopup ? isHovered || isOpenByKeyboard : isOpen;
368
366
  const popupPortal = Boolean(isPopup && menuContext?.popupPortal);
369
367
  const popupPlacement = menuContext?.mode === "horizontal" && level === 0 ? "bottom-start" : "right-start";
370
- const {
371
- x: popupX,
372
- y: popupY,
373
- placement: currentPopupPlacement
374
- } = useFloating({
368
+ const overlay = useAnchoredOverlay({
375
369
  referenceRef: titleRef,
376
370
  floatingRef: popupRef,
377
- enabled: popupPortal && isExpanded,
371
+ enabled: isPopup && isExpanded,
378
372
  placement: popupPlacement,
379
- offset: 4
373
+ offset: 4,
374
+ portal: popupPortal,
375
+ dismissOnEscape: true,
376
+ onDismiss: () => {
377
+ setIsOpenByKeyboard(false);
378
+ setIsHovered(false);
379
+ }
380
380
  });
381
381
  const isInlineOrVertical = menuContext?.mode !== "horizontal" && !isPopup;
382
382
  const [hasRenderedInline, setHasRenderedInline] = useState2(
@@ -572,22 +572,14 @@ var SubMenu = ({
572
572
  }
573
573
  return child;
574
574
  });
575
- const popupZIndex = isPopup ? getSubmenuPopupZIndex(level) : {};
576
575
  if (isPopup) {
577
- const popupStyle = popupPortal ? {
578
- display: isExpanded ? "block" : "none",
579
- position: "absolute",
580
- left: popupX,
581
- top: popupY,
582
- transformOrigin: getTransformOrigin(currentPopupPlacement),
583
- ...popupZIndex
584
- } : { display: isExpanded ? "block" : "none", ...popupZIndex };
585
576
  const popup = /* @__PURE__ */ jsx4(
586
577
  "ul",
587
578
  {
588
- ref: popupPortal ? popupRef : void 0,
589
- className: contentClasses,
590
- style: popupStyle,
579
+ ref: popupRef,
580
+ className: classNames3(contentClasses, overlay.floatingClasses),
581
+ style: { ...overlay.floatingStyles, display: isExpanded ? "block" : "none" },
582
+ "data-positioned": overlay.positioned,
591
583
  role: "menu",
592
584
  "aria-hidden": isExpanded ? void 0 : "true",
593
585
  onMouseEnter: popupPortal ? handleMouseEnter : void 0,
@@ -596,20 +588,7 @@ var SubMenu = ({
596
588
  children: enhancedChildren
597
589
  }
598
590
  );
599
- if (popupPortal) {
600
- return renderBodyPortal(popup);
601
- }
602
- return /* @__PURE__ */ jsx4(
603
- "ul",
604
- {
605
- className: contentClasses,
606
- style: { display: isExpanded ? "block" : "none", ...popupZIndex },
607
- role: "menu",
608
- "aria-hidden": isExpanded ? void 0 : "true",
609
- "data-tiger-submenu-popup": "",
610
- children: enhancedChildren
611
- }
612
- );
591
+ return renderOverlayPortal(popup, overlay.target, !popupPortal);
613
592
  }
614
593
  if (!hasRenderedInline) return null;
615
594
  const isHidden = !isExpanded;
@@ -3,7 +3,7 @@ import {
3
3
  useBodyScrollLock,
4
4
  useEscapeKey,
5
5
  useFocusTrap
6
- } from "./chunk-SEWNVIHH.mjs";
6
+ } from "./chunk-HKAZXG74.mjs";
7
7
  import {
8
8
  useTigerConfig
9
9
  } from "./chunk-YSIXURBW.mjs";
@@ -117,7 +117,6 @@ var Drawer = ({
117
117
  },
118
118
  [maskClosable, handleClose]
119
119
  );
120
- useEscapeKey({ enabled: open, onEscape: handleClose });
121
120
  useBodyScrollLock({ enabled: open });
122
121
  const previousVisible = useRef(false);
123
122
  useEffect(() => {
@@ -138,6 +137,7 @@ var Drawer = ({
138
137
  const reactId = useId();
139
138
  const drawerId = useMemo(() => `tiger-drawer-${reactId}`, [reactId]);
140
139
  const titleId = `${drawerId}-title`;
140
+ const overlayHostId = `${drawerId}-overlay-host`;
141
141
  const {
142
142
  ["aria-labelledby"]: _ariaLabelledby,
143
143
  role: _role,
@@ -146,10 +146,12 @@ var Drawer = ({
146
146
  } = rest;
147
147
  const ariaLabelledby = rest["aria-labelledby"] ?? (title || header ? titleId : void 0);
148
148
  const dialogRef = useRef(null);
149
+ const rootRef = useRef(null);
149
150
  const closeButtonRef = useRef(null);
150
151
  const previousActiveElementRef = useRef(null);
151
152
  const touchStartRef = useRef(null);
152
153
  const touchCurrentRef = useRef(null);
154
+ useEscapeKey({ enabled: open, onEscape: handleClose, layerRef: rootRef });
153
155
  const resolvedCloseAriaLabel = resolveLocaleText(
154
156
  "Close drawer",
155
157
  closeAriaLabel,
@@ -167,7 +169,7 @@ var Drawer = ({
167
169
  }
168
170
  restoreFocus(previousActiveElementRef.current);
169
171
  }, [open]);
170
- useFocusTrap({ enabled: open, containerRef: dialogRef });
172
+ useFocusTrap({ enabled: open, containerRef: rootRef });
171
173
  const resetTouchGesture = useCallback(() => {
172
174
  touchStartRef.current = null;
173
175
  touchCurrentRef.current = null;
@@ -235,10 +237,12 @@ var Drawer = ({
235
237
  const drawerContent = /* @__PURE__ */ jsxs(
236
238
  "div",
237
239
  {
240
+ ref: rootRef,
238
241
  className: containerClasses,
239
242
  style: { zIndex },
240
243
  hidden: !open && !isClosingBeforeDestroy,
241
244
  "aria-hidden": !open ? "true" : void 0,
245
+ "data-tiger-overlay-layer": "",
242
246
  "data-tiger-drawer-root": "",
243
247
  children: [
244
248
  mask && /* @__PURE__ */ jsx(
@@ -265,6 +269,7 @@ var Drawer = ({
265
269
  role: "dialog",
266
270
  "aria-modal": "true",
267
271
  "aria-labelledby": ariaLabelledby,
272
+ "aria-owns": overlayHostId,
268
273
  tabIndex: -1,
269
274
  ref: dialogRef,
270
275
  onTouchStart: handleTouchStart,
@@ -291,7 +296,8 @@ var Drawer = ({
291
296
  footer && /* @__PURE__ */ jsx("div", { className: footerClasses, children: footer })
292
297
  ]
293
298
  }
294
- )
299
+ ),
300
+ /* @__PURE__ */ jsx("div", { id: overlayHostId, className: "contents", "data-tiger-overlay-host": "" })
295
301
  ]
296
302
  }
297
303
  );
@@ -2,7 +2,7 @@ import {
2
2
  Dropdown,
3
3
  DropdownItem,
4
4
  DropdownMenu
5
- } from "./chunk-YI7NQWUV.mjs";
5
+ } from "./chunk-YI6YWH66.mjs";
6
6
  import {
7
7
  useTigerConfig
8
8
  } from "./chunk-YSIXURBW.mjs";
@@ -1,6 +1,10 @@
1
1
  import {
2
2
  useControlledState
3
3
  } from "./chunk-MEFARVQI.mjs";
4
+ import {
5
+ renderOverlayPortal,
6
+ useAnchoredOverlay
7
+ } from "./chunk-HKAZXG74.mjs";
4
8
  import {
5
9
  useTigerConfig
6
10
  } from "./chunk-YSIXURBW.mjs";
@@ -106,6 +110,7 @@ function useDatePickerState(props) {
106
110
  );
107
111
  const calendarRef = useRef(null);
108
112
  const mobileCalendarRef = useRef(null);
113
+ const panelRef = useRef(null);
109
114
  const inputWrapperRef = useRef(null);
110
115
  const inputRef = useRef(null);
111
116
  const pendingFocusIsoRef = useRef(null);
@@ -390,12 +395,6 @@ function useDatePickerState(props) {
390
395
  };
391
396
  useEffect(() => {
392
397
  if (isOpen) {
393
- const handleClickOutside = (event) => {
394
- if (calendarRef.current && mobileCalendarRef.current && inputWrapperRef.current && !calendarRef.current.contains(event.target) && !mobileCalendarRef.current.contains(event.target) && !inputWrapperRef.current.contains(event.target)) {
395
- closeCalendar();
396
- }
397
- };
398
- document.addEventListener("click", handleClickOutside);
399
398
  const preferred = pendingFocusIsoRef.current ?? getPreferredFocusIso();
400
399
  pendingFocusIsoRef.current = null;
401
400
  setTimeout(() => {
@@ -403,7 +402,7 @@ function useDatePickerState(props) {
403
402
  const fallback = getFirstEnabledIsoInView();
404
403
  if (fallback) focusDateButtonByIso(fallback);
405
404
  }, 0);
406
- return () => document.removeEventListener("click", handleClickOutside);
405
+ return;
407
406
  }
408
407
  setTimeout(() => restoreFocus(), 0);
409
408
  }, [
@@ -433,6 +432,7 @@ function useDatePickerState(props) {
433
432
  return {
434
433
  inputWrapperRef,
435
434
  inputRef,
435
+ panelRef,
436
436
  calendarRef,
437
437
  mobileCalendarRef,
438
438
  isOpen,
@@ -726,6 +726,17 @@ function renderDatePickerCalendar(ctx) {
726
726
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
727
727
  var DatePicker = (props) => {
728
728
  const ctx = useDatePickerState(props);
729
+ const overlay = useAnchoredOverlay({
730
+ enabled: ctx.isOpen,
731
+ referenceRef: ctx.inputWrapperRef,
732
+ floatingRef: ctx.panelRef,
733
+ placement: "bottom-start",
734
+ offset: 4,
735
+ layout: "bottom-sheet-sm",
736
+ dismissOnOutside: true,
737
+ dismissOnEscape: true,
738
+ onDismiss: ctx.closeCalendar
739
+ });
729
740
  return /* @__PURE__ */ jsxs3("div", { className: ctx.containerClasses, ...ctx.divProps, children: [
730
741
  /* @__PURE__ */ jsxs3("div", { ref: ctx.inputWrapperRef, className: datePickerInputWrapperClasses, children: [
731
742
  /* @__PURE__ */ jsx4(
@@ -767,8 +778,22 @@ var DatePicker = (props) => {
767
778
  }
768
779
  )
769
780
  ] }),
770
- ctx.isOpen && renderDatePickerMobile(ctx),
771
- ctx.isOpen && renderDatePickerCalendar(ctx)
781
+ renderOverlayPortal(
782
+ ctx.isOpen ? /* @__PURE__ */ jsxs3(
783
+ "div",
784
+ {
785
+ ref: ctx.panelRef,
786
+ className: overlay.floatingClasses,
787
+ style: overlay.floatingStyles,
788
+ "data-positioned": overlay.positioned,
789
+ children: [
790
+ renderDatePickerMobile(ctx),
791
+ renderDatePickerCalendar(ctx)
792
+ ]
793
+ }
794
+ ) : null,
795
+ overlay.target
796
+ )
772
797
  ] });
773
798
  };
774
799