@mieweb/ui 0.11.0-dev.2 → 0.11.0-dev.4

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 (55) hide show
  1. package/dist/{chunk-7UTBDFFL.cjs → chunk-2S76TRBJ.cjs} +4 -4
  2. package/dist/{chunk-7UTBDFFL.cjs.map → chunk-2S76TRBJ.cjs.map} +1 -1
  3. package/dist/{chunk-PJ6CC53R.cjs → chunk-AKMTPCLC.cjs} +13 -8
  4. package/dist/chunk-AKMTPCLC.cjs.map +1 -0
  5. package/dist/{chunk-VVDE4CHU.js → chunk-C4GEPUE7.js} +13 -8
  6. package/dist/chunk-C4GEPUE7.js.map +1 -0
  7. package/dist/{chunk-NUB5HRKS.js → chunk-DT3X3RBM.js} +3 -3
  8. package/dist/{chunk-NUB5HRKS.js.map → chunk-DT3X3RBM.js.map} +1 -1
  9. package/dist/{chunk-MYAU2ZUC.cjs → chunk-GDKOYVX3.cjs} +14 -10
  10. package/dist/chunk-GDKOYVX3.cjs.map +1 -0
  11. package/dist/{chunk-S2JZL4JC.js → chunk-JM4YFLO4.js} +22 -15
  12. package/dist/chunk-JM4YFLO4.js.map +1 -0
  13. package/dist/{chunk-QX6AAVDE.cjs → chunk-L4APW65W.cjs} +15 -6
  14. package/dist/chunk-L4APW65W.cjs.map +1 -0
  15. package/dist/{chunk-RM2HPQIC.js → chunk-MQ5WJ3NO.js} +4 -4
  16. package/dist/chunk-MQ5WJ3NO.js.map +1 -0
  17. package/dist/{chunk-XRVMYT5G.cjs → chunk-QKW2QCGI.cjs} +5 -5
  18. package/dist/chunk-QKW2QCGI.cjs.map +1 -0
  19. package/dist/{chunk-O6XDA3SI.js → chunk-UY2EZYIC.js} +15 -6
  20. package/dist/chunk-UY2EZYIC.js.map +1 -0
  21. package/dist/{chunk-2BPIVWAK.js → chunk-V5VPECJI.js} +14 -10
  22. package/dist/chunk-V5VPECJI.js.map +1 -0
  23. package/dist/{chunk-O6BJMVGT.cjs → chunk-XZNHS7YQ.cjs} +24 -17
  24. package/dist/chunk-XZNHS7YQ.cjs.map +1 -0
  25. package/dist/components/AudioPlayer/index.cjs +7 -6
  26. package/dist/components/AudioPlayer/index.js +2 -1
  27. package/dist/components/CollabStatus/index.cjs +5 -4
  28. package/dist/components/CollabStatus/index.js +2 -1
  29. package/dist/components/MediaEditor/index.cjs +8 -7
  30. package/dist/components/MediaEditor/index.js +3 -2
  31. package/dist/components/Slider/index.cjs +6 -5
  32. package/dist/components/Slider/index.js +2 -1
  33. package/dist/components/SliderCalculator/index.cjs +5 -4
  34. package/dist/components/SliderCalculator/index.js +3 -2
  35. package/dist/components/SuperChat/index.cjs +11 -11
  36. package/dist/components/SuperChat/index.cjs.map +1 -1
  37. package/dist/components/SuperChat/index.js +3 -3
  38. package/dist/components/SuperChat/index.js.map +1 -1
  39. package/dist/index.cjs +139 -138
  40. package/dist/index.cjs.map +1 -1
  41. package/dist/index.d.cts +3 -2
  42. package/dist/index.d.ts +3 -2
  43. package/dist/index.js +94 -93
  44. package/dist/index.js.map +1 -1
  45. package/package.json +1 -1
  46. package/dist/chunk-2BPIVWAK.js.map +0 -1
  47. package/dist/chunk-MYAU2ZUC.cjs.map +0 -1
  48. package/dist/chunk-O6BJMVGT.cjs.map +0 -1
  49. package/dist/chunk-O6XDA3SI.js.map +0 -1
  50. package/dist/chunk-PJ6CC53R.cjs.map +0 -1
  51. package/dist/chunk-QX6AAVDE.cjs.map +0 -1
  52. package/dist/chunk-RM2HPQIC.js.map +0 -1
  53. package/dist/chunk-S2JZL4JC.js.map +0 -1
  54. package/dist/chunk-VVDE4CHU.js.map +0 -1
  55. package/dist/chunk-XRVMYT5G.cjs.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1058,8 +1058,9 @@ interface ChatBubbleProps extends React$1.HTMLAttributes<HTMLDivElement>, Varian
1058
1058
  /** Show error styling (red border). */
1059
1059
  hasError?: boolean;
1060
1060
  /**
1061
- * Optional left-border accent color. Used by multi-participant surfaces
1062
- * (e.g. SuperChat) to tint a speaker's bubble; AI chat leaves it unset.
1061
+ * Optional inline-start border accent color. Used by multi-participant
1062
+ * surfaces (e.g. SuperChat) to tint a speaker's bubble; AI chat leaves it
1063
+ * unset.
1063
1064
  */
1064
1065
  accent?: string;
1065
1066
  }
package/dist/index.d.ts CHANGED
@@ -1058,8 +1058,9 @@ interface ChatBubbleProps extends React$1.HTMLAttributes<HTMLDivElement>, Varian
1058
1058
  /** Show error styling (red border). */
1059
1059
  hasError?: boolean;
1060
1060
  /**
1061
- * Optional left-border accent color. Used by multi-participant surfaces
1062
- * (e.g. SuperChat) to tint a speaker's bubble; AI chat leaves it unset.
1061
+ * Optional inline-start border accent color. Used by multi-participant
1062
+ * surfaces (e.g. SuperChat) to tint a speaker's bubble; AI chat leaves it
1063
+ * unset.
1063
1064
  */
1064
1065
  accent?: string;
1065
1066
  }
package/dist/index.js CHANGED
@@ -42,8 +42,8 @@ export { ViewSet } from './chunk-4RI3CQGE.js';
42
42
  export { ViewSwitcher, viewSwitcherVariants } from './chunk-2W73UQ3T.js';
43
43
  export { SourceTip } from './chunk-KFEN2SRZ.js';
44
44
  export { Sparkline } from './chunk-CG4ZKJLE.js';
45
- import { ButtonGroup, SparklesIcon, RefreshIcon, CloseIcon, JumpToBottomButton, AIMessageDisplay } from './chunk-RM2HPQIC.js';
46
- export { AILogoIcon, AIMessageDisplay, AITypingIndicator, ButtonGroup, ChatBubble, ChevronIcon, CloseIcon, CollapsiblePill, MCPToolCallDisplay, MessageAvatar, RefreshIcon, ResourceLink, SendIcon, SparklesIcon, SpinnerIcon, ToolStatusIcon, getToolIcon } from './chunk-RM2HPQIC.js';
45
+ import { ButtonGroup, SparklesIcon, RefreshIcon, CloseIcon, JumpToBottomButton, AIMessageDisplay } from './chunk-MQ5WJ3NO.js';
46
+ export { AILogoIcon, AIMessageDisplay, AITypingIndicator, ButtonGroup, ChatBubble, ChevronIcon, CloseIcon, CollapsiblePill, MCPToolCallDisplay, MessageAvatar, RefreshIcon, ResourceLink, SendIcon, SparklesIcon, SpinnerIcon, ToolStatusIcon, getToolIcon } from './chunk-MQ5WJ3NO.js';
47
47
  import { useTypingEmulation, EmptyState } from './chunk-NKG2UNXE.js';
48
48
  export { AttachmentPreview, ConversationHeader, ConversationListItem, ConversationListSkeleton, DateSeparator, EmptyState, LightboxModal, LoadMoreButton, MessageBubble, MessageList, MessageStatusIcon, MessageThread, MessagingSplitView, ReadReceiptIndicator, SkeletonMessage, TypingIndicator, bubbleVariants, formatDateLabel, formatFileSize, formatLastSeen, getConversationSubtitle, getConversationTitle, groupMessagesByDate, headerVariants, isSameSenderGroup, useMessageScroll, useMessages, useReadReceipts, useTypingEmulation, useTypingIndicator } from './chunk-NKG2UNXE.js';
49
49
  import { notifyComposerMigrationOnce, ChatComposer, DEFAULT_MAX_FILE_SIZE, DEFAULT_ACCEPTED_FILE_TYPES } from './chunk-GJPCWR4C.js';
@@ -53,7 +53,7 @@ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, Tabl
53
53
  export { DateButton, DatePicker, RadioOption, SchedulePicker, TimeButton, TimePicker, dateButtonVariants, radioOptionVariants, timeButtonVariants } from './chunk-23AYDOCH.js';
54
54
  export { ScrollArea, scrollAreaVariants } from './chunk-HS25RPDW.js';
55
55
  export { SectionSpyNav } from './chunk-FIKO4WR6.js';
56
- export { AnimatedNumber, SliderCalculator } from './chunk-NUB5HRKS.js';
56
+ export { AnimatedNumber, SliderCalculator } from './chunk-DT3X3RBM.js';
57
57
  import { Skeleton } from './chunk-ZIUADGAR.js';
58
58
  export { Skeleton, SkeletonCard, SkeletonTable, SkeletonText, skeletonVariants } from './chunk-ZIUADGAR.js';
59
59
  export { PhoneInput, PhoneInputGroup } from './chunk-XOIIUO6O.js';
@@ -63,8 +63,8 @@ export { QuickAction, QuickActionGroup, QuickActionIcons, quickActionIconVariant
63
63
  export { ReadingProgressBar } from './chunk-WKSUL2ZN.js';
64
64
  import { RecordButton } from './chunk-VNWJTCBQ.js';
65
65
  export { RecordButton, formatDuration, recordButtonVariants } from './chunk-VNWJTCBQ.js';
66
- export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from './chunk-S2JZL4JC.js';
67
- export { Slider, sliderRangeVariants, sliderThumbVariants, sliderTrackVariants } from './chunk-2BPIVWAK.js';
66
+ export { FillerWordsModal, MediaEditor, SilenceSettingsModal, SpeedMarkerMenu, WordEditorModal } from './chunk-JM4YFLO4.js';
67
+ export { Slider, sliderRangeVariants, sliderThumbVariants, sliderTrackVariants } from './chunk-V5VPECJI.js';
68
68
  export { MediaFeed } from './chunk-2X54ZLT6.js';
69
69
  import './chunk-RISZWWEQ.js';
70
70
  export { MediaPlayer, inferMediaKind, mediaPlayerVariants } from './chunk-N54FYWG6.js';
@@ -109,13 +109,13 @@ import { Checkbox } from './chunk-753Z3NXL.js';
109
109
  export { Checkbox, CheckboxGroup, checkboxVariants } from './chunk-753Z3NXL.js';
110
110
  import './chunk-XXA4NZUC.js';
111
111
  export { ClampedText } from './chunk-VU3ZMJBN.js';
112
- export { CollabStatus, defaultCollabStatusLabels, useYjsCollabStatus } from './chunk-O6XDA3SI.js';
112
+ export { CollabStatus, defaultCollabStatusLabels, useYjsCollabStatus } from './chunk-UY2EZYIC.js';
113
113
  export { Collapsible, CollapsibleContent, CollapsibleTrigger } from './chunk-VSRO4PAI.js';
114
114
  import { Alert, AlertTitle, AlertDescription } from './chunk-3JWAABYI.js';
115
115
  export { Alert, AlertDescription, AlertTitle, alertVariants } from './chunk-3JWAABYI.js';
116
116
  import { AlertDialog } from './chunk-56VTM4OX.js';
117
117
  export { AlertDialog, ConfirmDialogProvider, defaultAlertDialogLabels, useConfirm } from './chunk-56VTM4OX.js';
118
- export { AudioPlayer, ProgressBar, audioPlayerVariants, formatTime as formatAudioTime, playButtonVariants } from './chunk-VVDE4CHU.js';
118
+ export { AudioPlayer, ProgressBar, audioPlayerVariants, formatTime as formatAudioTime, playButtonVariants } from './chunk-C4GEPUE7.js';
119
119
  export { AudioRecorder, audioRecorderVariants, controlButtonVariants, formatTime, waveformContainerVariants } from './chunk-2DW4PUJD.js';
120
120
  export { Autocomplete } from './chunk-UBOVDAD7.js';
121
121
  export { BoardView, cardVariants as boardViewCardVariants, defaultBoardLabels } from './chunk-F7SZSOB3.js';
@@ -2869,6 +2869,7 @@ function HeyOzwellToggle({
2869
2869
  "aria-hidden": "true",
2870
2870
  style: {
2871
2871
  position: "absolute",
2872
+ // rtl-ignore -- symmetric centering: left:50% + translate(-50%) is direction-independent
2872
2873
  left: "50%",
2873
2874
  top: "50%",
2874
2875
  width: size * 1.7,
@@ -5441,6 +5442,7 @@ function VoiceSetup({
5441
5442
  {
5442
5443
  style: {
5443
5444
  position: "absolute",
5445
+ // rtl-ignore -- symmetric centering: left:50% + translate(-50%) is direction-independent
5444
5446
  left: "50%",
5445
5447
  top: "50%",
5446
5448
  width: 150,
@@ -5457,6 +5459,7 @@ function VoiceSetup({
5457
5459
  {
5458
5460
  style: {
5459
5461
  position: "absolute",
5462
+ // rtl-ignore -- symmetric centering: left:50% + translate(-50%) is direction-independent
5460
5463
  left: "50%",
5461
5464
  top: "50%",
5462
5465
  width: 180,
@@ -5525,7 +5528,7 @@ function VoiceSetup({
5525
5528
  {
5526
5529
  className: "absolute flex items-center justify-center rounded-full text-white",
5527
5530
  style: {
5528
- right: -2,
5531
+ insetInlineEnd: -2,
5529
5532
  bottom: -2,
5530
5533
  width: 36,
5531
5534
  height: 36,
@@ -5832,23 +5835,34 @@ function HandsFreeChat({
5832
5835
  const placeholder = !oz.active ? "Ozwell is off \u2014 tap the octopus to listen" : phase === "listening" ? ready ? "Say \u201Chey ozwell\u201D, or type\u2026" : error ? `\u26A0\uFE0F ${error}` : "\u2026 loading models" : oz.chatProps.inputPlaceholder;
5833
5836
  return /* @__PURE__ */ jsxs("div", { style: { height: "100vh", display: "flex", flexDirection: "column" }, children: [
5834
5837
  /* @__PURE__ */ jsxs("div", { style: { flex: 1, minHeight: 0, position: "relative" }, children: [
5835
- /* @__PURE__ */ jsx("div", { style: { position: "absolute", top: 11, right: 16, zIndex: 10 }, children: /* @__PURE__ */ jsx(
5836
- OzwellSettingsMenu,
5838
+ /* @__PURE__ */ jsx(
5839
+ "div",
5837
5840
  {
5838
- trigger: /* @__PURE__ */ jsx(
5839
- HeyOzwellToggle,
5841
+ style: {
5842
+ position: "absolute",
5843
+ top: 11,
5844
+ insetInlineEnd: 16,
5845
+ zIndex: 10
5846
+ },
5847
+ children: /* @__PURE__ */ jsx(
5848
+ OzwellSettingsMenu,
5840
5849
  {
5841
- ...oz.toggleProps,
5842
- logoSrc,
5843
- size: 34
5850
+ trigger: /* @__PURE__ */ jsx(
5851
+ HeyOzwellToggle,
5852
+ {
5853
+ ...oz.toggleProps,
5854
+ logoSrc,
5855
+ size: 34
5856
+ }
5857
+ ),
5858
+ open: oz.settingsOpen,
5859
+ onOpenChange: oz.setSettingsOpen,
5860
+ modelStatus: oz.modelStatus,
5861
+ onManageVoices: () => setVoicesOpen(true)
5844
5862
  }
5845
- ),
5846
- open: oz.settingsOpen,
5847
- onOpenChange: oz.setSettingsOpen,
5848
- modelStatus: oz.modelStatus,
5849
- onManageVoices: () => setVoicesOpen(true)
5863
+ )
5850
5864
  }
5851
- ) }),
5865
+ ),
5852
5866
  /* @__PURE__ */ jsx(
5853
5867
  AIChat,
5854
5868
  {
@@ -14552,9 +14566,20 @@ function RowActionMenu({
14552
14566
  actions
14553
14567
  }) {
14554
14568
  const [open, setOpen] = React13.useState(false);
14555
- const menuRef = React13.useRef(null);
14556
14569
  const buttonRef = React13.useRef(null);
14557
- const outsideRefs = React13.useMemo(() => [menuRef, buttonRef], []);
14570
+ const direction = useDirection(buttonRef);
14571
+ const {
14572
+ anchorRef,
14573
+ floatingRef,
14574
+ style: menuStyle
14575
+ } = useAnchoredPosition({
14576
+ open,
14577
+ placement: direction === "rtl" ? "bottom-start" : "bottom-end"
14578
+ });
14579
+ const outsideRefs = React13.useMemo(
14580
+ () => [floatingRef, buttonRef],
14581
+ [floatingRef]
14582
+ );
14558
14583
  useClickOutside(outsideRefs, () => setOpen(false), open);
14559
14584
  React13.useEffect(() => {
14560
14585
  if (!open) return;
@@ -14564,20 +14589,14 @@ function RowActionMenu({
14564
14589
  document.addEventListener("keydown", handleKey);
14565
14590
  return () => document.removeEventListener("keydown", handleKey);
14566
14591
  }, [open]);
14567
- const [menuPos, setMenuPos] = React13.useState(null);
14568
- React13.useLayoutEffect(() => {
14569
- if (!open || !buttonRef.current) return;
14570
- const rect = buttonRef.current.getBoundingClientRect();
14571
- setMenuPos({
14572
- top: rect.bottom + 4,
14573
- left: rect.right
14574
- });
14575
- }, [open]);
14576
14592
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
14577
14593
  /* @__PURE__ */ jsx(
14578
14594
  "button",
14579
14595
  {
14580
- ref: buttonRef,
14596
+ ref: (el) => {
14597
+ buttonRef.current = el;
14598
+ anchorRef.current = el;
14599
+ },
14581
14600
  type: "button",
14582
14601
  onClick: (e) => {
14583
14602
  e.stopPropagation();
@@ -14596,18 +14615,14 @@ function RowActionMenu({
14596
14615
  children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
14597
14616
  }
14598
14617
  ),
14599
- open && menuPos && ReactDOM.createPortal(
14618
+ open && ReactDOM.createPortal(
14600
14619
  /* @__PURE__ */ jsx(
14601
14620
  "div",
14602
14621
  {
14603
- ref: menuRef,
14622
+ ref: floatingRef,
14604
14623
  role: "menu",
14605
- style: {
14606
- position: "fixed",
14607
- top: menuPos.top,
14608
- left: menuPos.left,
14609
- transform: "translateX(-100%)"
14610
- },
14624
+ dir: direction,
14625
+ style: menuStyle,
14611
14626
  className: cn(
14612
14627
  "z-[9999] min-w-[10rem]",
14613
14628
  "rounded-lg border border-neutral-200 bg-white py-1 shadow-lg",
@@ -16324,18 +16339,26 @@ function WidgetRowActionMenu({
16324
16339
  actions
16325
16340
  }) {
16326
16341
  const [open, setOpen] = React13.useState(false);
16327
- const menuRef = React13.useRef(null);
16328
16342
  const buttonRef = React13.useRef(null);
16343
+ const direction = useDirection(buttonRef);
16344
+ const {
16345
+ anchorRef,
16346
+ floatingRef,
16347
+ style: menuStyle
16348
+ } = useAnchoredPosition({
16349
+ open,
16350
+ placement: direction === "rtl" ? "bottom-start" : "bottom-end"
16351
+ });
16329
16352
  React13.useEffect(() => {
16330
16353
  if (!open) return;
16331
16354
  function handleClick(e) {
16332
- if (menuRef.current && !menuRef.current.contains(e.target) && buttonRef.current && !buttonRef.current.contains(e.target)) {
16355
+ if (floatingRef.current && !floatingRef.current.contains(e.target) && buttonRef.current && !buttonRef.current.contains(e.target)) {
16333
16356
  setOpen(false);
16334
16357
  }
16335
16358
  }
16336
16359
  document.addEventListener("mousedown", handleClick);
16337
16360
  return () => document.removeEventListener("mousedown", handleClick);
16338
- }, [open]);
16361
+ }, [open, floatingRef]);
16339
16362
  React13.useEffect(() => {
16340
16363
  if (!open) return;
16341
16364
  function handleKey(e) {
@@ -16344,15 +16367,6 @@ function WidgetRowActionMenu({
16344
16367
  document.addEventListener("keydown", handleKey);
16345
16368
  return () => document.removeEventListener("keydown", handleKey);
16346
16369
  }, [open]);
16347
- const [menuPos, setMenuPos] = React13.useState(null);
16348
- React13.useLayoutEffect(() => {
16349
- if (!open || !buttonRef.current) return;
16350
- const rect = buttonRef.current.getBoundingClientRect();
16351
- setMenuPos({
16352
- top: rect.bottom + 4,
16353
- left: rect.right
16354
- });
16355
- }, [open]);
16356
16370
  const visibleActions = actions.filter(
16357
16371
  (action) => !action.hidden?.(row, rowIndex)
16358
16372
  );
@@ -16361,7 +16375,10 @@ function WidgetRowActionMenu({
16361
16375
  /* @__PURE__ */ jsx(
16362
16376
  "button",
16363
16377
  {
16364
- ref: buttonRef,
16378
+ ref: (el) => {
16379
+ buttonRef.current = el;
16380
+ anchorRef.current = el;
16381
+ },
16365
16382
  type: "button",
16366
16383
  onClick: (e) => {
16367
16384
  e.stopPropagation();
@@ -16380,18 +16397,14 @@ function WidgetRowActionMenu({
16380
16397
  children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
16381
16398
  }
16382
16399
  ),
16383
- open && menuPos && createPortal(
16400
+ open && createPortal(
16384
16401
  /* @__PURE__ */ jsx(
16385
16402
  "div",
16386
16403
  {
16387
- ref: menuRef,
16404
+ ref: floatingRef,
16388
16405
  role: "menu",
16389
- style: {
16390
- position: "fixed",
16391
- top: menuPos.top,
16392
- left: menuPos.left,
16393
- transform: "translateX(-100%)"
16394
- },
16406
+ dir: direction,
16407
+ style: menuStyle,
16395
16408
  className: cn(
16396
16409
  "z-[9999] min-w-[10rem]",
16397
16410
  "rounded-lg border border-neutral-200 bg-white py-1 shadow-lg",
@@ -23246,18 +23259,26 @@ function FileRowActionMenu({
23246
23259
  onDelete
23247
23260
  }) {
23248
23261
  const [open, setOpen] = React13.useState(false);
23249
- const menuRef = React13.useRef(null);
23250
23262
  const buttonRef = React13.useRef(null);
23263
+ const direction = useDirection(buttonRef);
23264
+ const {
23265
+ anchorRef,
23266
+ floatingRef,
23267
+ style: menuStyle
23268
+ } = useAnchoredPosition({
23269
+ open,
23270
+ placement: direction === "rtl" ? "bottom-start" : "bottom-end"
23271
+ });
23251
23272
  React13.useEffect(() => {
23252
23273
  if (!open) return;
23253
23274
  function handleClick(e) {
23254
- if (menuRef.current && !menuRef.current.contains(e.target) && buttonRef.current && !buttonRef.current.contains(e.target)) {
23275
+ if (floatingRef.current && !floatingRef.current.contains(e.target) && buttonRef.current && !buttonRef.current.contains(e.target)) {
23255
23276
  setOpen(false);
23256
23277
  }
23257
23278
  }
23258
23279
  document.addEventListener("mousedown", handleClick);
23259
23280
  return () => document.removeEventListener("mousedown", handleClick);
23260
- }, [open]);
23281
+ }, [open, floatingRef]);
23261
23282
  React13.useEffect(() => {
23262
23283
  if (!open) return;
23263
23284
  function handleKey(e) {
@@ -23266,25 +23287,6 @@ function FileRowActionMenu({
23266
23287
  document.addEventListener("keydown", handleKey);
23267
23288
  return () => document.removeEventListener("keydown", handleKey);
23268
23289
  }, [open]);
23269
- const [menuPos, setMenuPos] = React13.useState(null);
23270
- React13.useLayoutEffect(() => {
23271
- if (!open || !buttonRef.current) return;
23272
- function updatePosition() {
23273
- if (!buttonRef.current) return;
23274
- const rect = buttonRef.current.getBoundingClientRect();
23275
- setMenuPos({
23276
- top: rect.bottom + 4,
23277
- left: rect.right
23278
- });
23279
- }
23280
- updatePosition();
23281
- window.addEventListener("scroll", updatePosition, true);
23282
- window.addEventListener("resize", updatePosition);
23283
- return () => {
23284
- window.removeEventListener("scroll", updatePosition, true);
23285
- window.removeEventListener("resize", updatePosition);
23286
- };
23287
- }, [open]);
23288
23290
  const actions = [
23289
23291
  onPreview && {
23290
23292
  key: "preview",
@@ -23311,7 +23313,10 @@ function FileRowActionMenu({
23311
23313
  /* @__PURE__ */ jsx(
23312
23314
  "button",
23313
23315
  {
23314
- ref: buttonRef,
23316
+ ref: (el) => {
23317
+ buttonRef.current = el;
23318
+ anchorRef.current = el;
23319
+ },
23315
23320
  type: "button",
23316
23321
  onClick: (e) => {
23317
23322
  e.stopPropagation();
@@ -23330,18 +23335,14 @@ function FileRowActionMenu({
23330
23335
  children: /* @__PURE__ */ jsx(MoreHorizontal, { size: 14 })
23331
23336
  }
23332
23337
  ),
23333
- open && menuPos && createPortal(
23338
+ open && createPortal(
23334
23339
  /* @__PURE__ */ jsx(
23335
23340
  "div",
23336
23341
  {
23337
- ref: menuRef,
23342
+ ref: floatingRef,
23338
23343
  role: "menu",
23339
- style: {
23340
- position: "fixed",
23341
- top: menuPos.top,
23342
- left: menuPos.left,
23343
- transform: "translateX(-100%)"
23344
- },
23344
+ dir: direction,
23345
+ style: menuStyle,
23345
23346
  className: cn(
23346
23347
  "z-[9999] min-w-[10rem]",
23347
23348
  "rounded-lg border border-neutral-200 bg-white py-1 shadow-lg",