Initial commit: Plane
Some checks failed
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Admin Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Sync Repositories / sync_changes (push) Has been cancelled
Some checks failed
Branch Build CE / Build Setup (push) Has been cancelled
Branch Build CE / Build-Push Admin Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Web Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Space Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Live Collaboration Docker Image (push) Has been cancelled
Branch Build CE / Build-Push API Server Docker Image (push) Has been cancelled
Branch Build CE / Build-Push Proxy Docker Image (push) Has been cancelled
Branch Build CE / Build-Push AIO Docker Image (push) Has been cancelled
Branch Build CE / Upload Build Assets (push) Has been cancelled
Branch Build CE / Build Release (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Codespell / Check for spelling errors (push) Has been cancelled
Sync Repositories / sync_changes (push) Has been cancelled
Synced from upstream: 8853637e981ed7d8a6cff32bd98e7afe20f54362
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
||||
|
||||
interface UseGroupDropTargetProps {
|
||||
groupId: string;
|
||||
enableDragDrop?: boolean;
|
||||
onDrop?: (itemId: string, targetId: string | null, sourceGroupId: string, targetGroupId: string) => void;
|
||||
}
|
||||
|
||||
interface DragSourceData {
|
||||
id: string;
|
||||
groupId: string;
|
||||
type: "ITEM" | "GROUP";
|
||||
}
|
||||
|
||||
/**
|
||||
* A hook that turns an element into a valid drop target for group drag-and-drop.
|
||||
*
|
||||
* @returns groupRef (attach to the droppable container) and isDraggingOver (for visual feedback)
|
||||
*/
|
||||
export const useGroupDropTarget = ({ groupId, enableDragDrop = false, onDrop }: UseGroupDropTargetProps) => {
|
||||
const groupRef = useRef<HTMLDivElement | null>(null);
|
||||
const [isDraggingOver, setIsDraggingOver] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const element = groupRef.current;
|
||||
if (!element || !enableDragDrop || !onDrop) return;
|
||||
|
||||
const cleanup = dropTargetForElements({
|
||||
element,
|
||||
getData: () => ({ groupId, type: "GROUP" }),
|
||||
|
||||
canDrop: ({ source }) => {
|
||||
const data = (source?.data || {}) as Partial<DragSourceData>;
|
||||
return data.type === "ITEM" && !!data.groupId && data.groupId !== groupId;
|
||||
},
|
||||
|
||||
onDragEnter: () => setIsDraggingOver(true),
|
||||
onDragLeave: () => setIsDraggingOver(false),
|
||||
|
||||
onDrop: ({ source }) => {
|
||||
setIsDraggingOver(false);
|
||||
const data = (source?.data || {}) as Partial<DragSourceData>;
|
||||
if (data.type !== "ITEM" || !data.id || !data.groupId) return;
|
||||
if (data.groupId !== groupId) {
|
||||
onDrop(data.id, null, data.groupId, groupId);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return cleanup;
|
||||
}, [groupId, enableDragDrop, onDrop]);
|
||||
|
||||
return { groupRef, isDraggingOver };
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
import { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
||||
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
|
||||
|
||||
type UseLayoutStateProps =
|
||||
| {
|
||||
mode: "external";
|
||||
externalCollapsedGroups: string[];
|
||||
externalOnToggleGroup: (groupId: string) => void;
|
||||
enableAutoScroll?: boolean;
|
||||
}
|
||||
| {
|
||||
mode?: "internal";
|
||||
enableAutoScroll?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hook for managing layout state including:
|
||||
* - Collapsed/expanded group tracking (internal or external)
|
||||
* - Auto-scroll setup for drag-and-drop
|
||||
*/
|
||||
export const useLayoutState = (props: UseLayoutStateProps = { mode: "internal" }) => {
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
// Internal fallback state
|
||||
const [internalCollapsedGroups, setInternalCollapsedGroups] = useState<string[]>([]);
|
||||
|
||||
// Stable internal toggle function
|
||||
const internalToggleGroup = useCallback((groupId: string) => {
|
||||
setInternalCollapsedGroups((prev) =>
|
||||
prev.includes(groupId) ? prev.filter((id) => id !== groupId) : [...prev, groupId]
|
||||
);
|
||||
}, []);
|
||||
|
||||
const useExternal = props.mode === "external";
|
||||
const collapsedGroups = useExternal ? props.externalCollapsedGroups : internalCollapsedGroups;
|
||||
const onToggleGroup = useExternal ? props.externalOnToggleGroup : internalToggleGroup;
|
||||
|
||||
// Enable auto-scroll for DnD
|
||||
useEffect(() => {
|
||||
const element = containerRef.current;
|
||||
if (!element || !props.enableAutoScroll) return;
|
||||
|
||||
const cleanup = combine(
|
||||
autoScrollForElements({
|
||||
element,
|
||||
})
|
||||
);
|
||||
|
||||
return cleanup;
|
||||
}, [props.enableAutoScroll]);
|
||||
|
||||
return {
|
||||
containerRef,
|
||||
collapsedGroups,
|
||||
onToggleGroup,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user