@farmzone/fz-react-ui 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7926,6 +7926,15 @@ function MultiTabBar(props) {
7926
7926
  const [draggingId, setDraggingId] = useState(null);
7927
7927
  const [dropTargetId, setDropTargetId] = useState(null);
7928
7928
  const [dropSide, setDropSide] = useState("before");
7929
+ const draggingIdRef = useRef(null);
7930
+ const dropTargetIdRef = useRef(null);
7931
+ const dropSideRef = useRef("before");
7932
+ const tabsRef = useRef(tabs);
7933
+ const dropHandledRef = useRef(false);
7934
+ draggingIdRef.current = draggingId;
7935
+ dropTargetIdRef.current = dropTargetId;
7936
+ dropSideRef.current = dropSide;
7937
+ tabsRef.current = tabs;
7929
7938
  useEffect(() => {
7930
7939
  if (!activeTabId || !scrollRef.current) return;
7931
7940
  const el = tabRefs.current.get(activeTabId);
@@ -7963,60 +7972,100 @@ function MultiTabBar(props) {
7963
7972
  el.addEventListener("wheel", onWheel, { passive: false });
7964
7973
  return () => el.removeEventListener("wheel", onWheel);
7965
7974
  }, []);
7975
+ const resolveDropPosition = (clientX) => {
7976
+ for (const [tabId, el] of tabRefs.current) {
7977
+ if (tabId === draggingIdRef.current) continue;
7978
+ const rect = el.getBoundingClientRect();
7979
+ if (clientX >= rect.left && clientX < rect.right) {
7980
+ setDropSide(clientX < rect.left + rect.width / 2 ? "before" : "after");
7981
+ setDropTargetId(tabId);
7982
+ return;
7983
+ }
7984
+ }
7985
+ let rightmostTabId = null;
7986
+ let maxRight = -Infinity;
7987
+ for (const [tabId, el] of tabRefs.current) {
7988
+ if (tabId === draggingIdRef.current) continue;
7989
+ const rect = el.getBoundingClientRect();
7990
+ if (rect.right > maxRight) {
7991
+ maxRight = rect.right;
7992
+ rightmostTabId = tabId;
7993
+ }
7994
+ }
7995
+ if (rightmostTabId && clientX >= maxRight) {
7996
+ setDropSide("after");
7997
+ setDropTargetId(rightmostTabId);
7998
+ }
7999
+ };
8000
+ const reorderTabs = (targetTabId, side, sourceTabs, sourceId) => {
8001
+ if (!onTabsReorder || sourceId === targetTabId) return;
8002
+ const fromIdx = sourceTabs.findIndex((t) => t.id === sourceId);
8003
+ if (fromIdx === -1) return;
8004
+ const newTabs = [...sourceTabs];
8005
+ const moved = newTabs.splice(fromIdx, 1)[0];
8006
+ let insertIdx = newTabs.findIndex((t) => t.id === targetTabId);
8007
+ if (insertIdx === -1) return;
8008
+ if (side === "after") insertIdx += 1;
8009
+ newTabs.splice(insertIdx, 0, moved);
8010
+ onTabsReorder(newTabs);
8011
+ };
8012
+ useEffect(() => {
8013
+ if (!onTabsReorder) return;
8014
+ const onDocDragOver = (e) => {
8015
+ if (!draggingIdRef.current) return;
8016
+ e.preventDefault();
8017
+ resolveDropPosition(e.clientX);
8018
+ };
8019
+ const onDocDrop = (e) => {
8020
+ if (dropHandledRef.current) {
8021
+ dropHandledRef.current = false;
8022
+ return;
8023
+ }
8024
+ e.preventDefault();
8025
+ const id = draggingIdRef.current;
8026
+ const target = dropTargetIdRef.current;
8027
+ if (id && target) reorderTabs(target, dropSideRef.current, tabsRef.current, id);
8028
+ setDraggingId(null);
8029
+ setDropTargetId(null);
8030
+ };
8031
+ document.addEventListener("dragover", onDocDragOver);
8032
+ document.addEventListener("drop", onDocDrop);
8033
+ return () => {
8034
+ document.removeEventListener("dragover", onDocDragOver);
8035
+ document.removeEventListener("drop", onDocDrop);
8036
+ };
8037
+ }, [onTabsReorder]);
7966
8038
  const handleDragStart = (e, tabId) => {
7967
8039
  setDraggingId(tabId);
7968
8040
  e.dataTransfer.effectAllowed = "move";
7969
8041
  };
7970
- const handleDragOver = (e, tabId) => {
7971
- e.preventDefault();
7972
- if (tabId === draggingId) return;
7973
- e.dataTransfer.dropEffect = "move";
7974
- const rect = e.currentTarget.getBoundingClientRect();
7975
- setDropSide(e.clientX < rect.left + rect.width / 2 ? "before" : "after");
7976
- setDropTargetId(tabId);
7977
- };
7978
8042
  const handleDrop = (e, targetTabId) => {
7979
8043
  e.preventDefault();
7980
8044
  e.stopPropagation();
7981
- if (!draggingId || draggingId === targetTabId) {
7982
- setDraggingId(null);
7983
- setDropTargetId(null);
7984
- return;
7985
- }
7986
- if (onTabsReorder) {
7987
- const fromIdx = tabs.findIndex((t) => t.id === draggingId);
7988
- if (fromIdx !== -1) {
7989
- const newTabs = [...tabs];
7990
- const moved = newTabs.splice(fromIdx, 1)[0];
7991
- let insertIdx = newTabs.findIndex((t) => t.id === targetTabId);
7992
- if (insertIdx !== -1) {
7993
- if (dropSide === "after") insertIdx += 1;
7994
- newTabs.splice(insertIdx, 0, moved);
7995
- onTabsReorder(newTabs);
7996
- }
7997
- }
7998
- }
8045
+ dropHandledRef.current = true;
8046
+ const id = draggingIdRef.current;
8047
+ if (id && id !== targetTabId) reorderTabs(targetTabId, dropSideRef.current, tabsRef.current, id);
7999
8048
  setDraggingId(null);
8000
8049
  setDropTargetId(null);
8001
8050
  };
8002
8051
  const handleContainerDrop = (e) => {
8003
8052
  e.preventDefault();
8004
- if (!draggingId || !onTabsReorder) {
8005
- setDraggingId(null);
8006
- setDropTargetId(null);
8007
- return;
8008
- }
8009
- const fromIdx = tabs.findIndex((t) => t.id === draggingId);
8010
- if (fromIdx !== -1 && fromIdx < tabs.length - 1) {
8011
- const newTabs = [...tabs];
8012
- const moved = newTabs.splice(fromIdx, 1)[0];
8013
- newTabs.push(moved);
8014
- onTabsReorder(newTabs);
8053
+ dropHandledRef.current = true;
8054
+ const id = draggingIdRef.current;
8055
+ if (id && onTabsReorder) {
8056
+ const fromIdx = tabsRef.current.findIndex((t) => t.id === id);
8057
+ if (fromIdx !== -1 && fromIdx < tabsRef.current.length - 1) {
8058
+ const newTabs = [...tabsRef.current];
8059
+ const moved = newTabs.splice(fromIdx, 1)[0];
8060
+ newTabs.push(moved);
8061
+ onTabsReorder(newTabs);
8062
+ }
8015
8063
  }
8016
8064
  setDraggingId(null);
8017
8065
  setDropTargetId(null);
8018
8066
  };
8019
8067
  const handleDragEnd = () => {
8068
+ dropHandledRef.current = false;
8020
8069
  setDraggingId(null);
8021
8070
  setDropTargetId(null);
8022
8071
  };
@@ -8067,7 +8116,6 @@ function MultiTabBar(props) {
8067
8116
  if (!isActive) onTabClick(tab.id);
8068
8117
  },
8069
8118
  onDragStart: (e) => handleDragStart(e, tab.id),
8070
- onDragOver: (e) => handleDragOver(e, tab.id),
8071
8119
  onDrop: (e) => handleDrop(e, tab.id),
8072
8120
  onDragEnd: handleDragEnd,
8073
8121
  className: `