add comments in MultipleContainers

pull/5370/head
drafish 5 months ago committed by yann300
parent 8348dc0e11
commit 5cac56ccc9
  1. 11
      apps/quick-dapp/src/components/MultipleContainers/index.tsx
  2. 39
      apps/quick-dapp/src/components/MultipleContainers/multipleContainersKeyboardCoordinates.ts

@ -42,9 +42,11 @@ export default {
title: 'Presets/Sortable/Multiple Containers',
};
// This function is used to animate layout changes.
const animateLayoutChanges: AnimateLayoutChanges = (args) =>
defaultAnimateLayoutChanges({ ...args, wasDragging: true });
// This is a container component that can be dragged and dropped.
function DroppableContainer({
children,
columns = 1,
@ -81,6 +83,7 @@ function DroppableContainer({
items.includes(over.id)
: false;
// Return the container.
return (
<Container
ref={disabled ? undefined : setNodeRef}
@ -103,6 +106,7 @@ function DroppableContainer({
);
}
// This setting is used for drop animation.
const dropAnimation: DropAnimation = {
sideEffects: defaultDropAnimationSideEffects({
styles: {
@ -113,8 +117,10 @@ const dropAnimation: DropAnimation = {
}),
};
// This type is used to define the items.
type Items = Record<UniqueIdentifier, UniqueIdentifier[]>;
// This interface is used to define the props for the MultipleContainers component.
interface Props {
adjustScale?: boolean;
cancelDrop?: CancelDrop;
@ -146,6 +152,9 @@ interface Props {
const PLACEHOLDER_ID = 'placeholder';
const empty: UniqueIdentifier[] = [];
// This is a complex component. It allows items in multiple containers to be sorted using drag and drop.
// The containers themselves can also be sorted. The DndContext component from the @dnd-kit/core package provides the drag and drop context.
// The MultipleContainers component is the main component, it handles the sorting logic when an item is dragged over another item or when an item is dropped.
export function MultipleContainers({
adjustScale = false,
cancelDrop,
@ -584,6 +593,7 @@ interface SortableItemProps {
onRemove?: () => void;
}
// The SortableItem component represents an individual item that can be dragged and dropped.
function SortableItem({
disabled,
id,
@ -640,6 +650,7 @@ function SortableItem({
);
}
// The useMountStatus function is used to track the mount status of a component.
function useMountStatus() {
const [isMounted, setIsMounted] = useState(false);

@ -6,6 +6,7 @@ import {
KeyboardCoordinateGetter,
} from '@dnd-kit/core';
// Define the directions that can be used with the keyboard
const directions: string[] = [
KeyboardCode.Down,
KeyboardCode.Right,
@ -13,66 +14,93 @@ const directions: string[] = [
KeyboardCode.Left,
];
// This is a custom coordinate getter for keyboard events.
// It's used to handle keyboard navigation when moving items around in a drag and drop context.
// It determines the next position of an item based on the direction of the keyboard event.
// The function filters droppable containers based on their position relative to the currently dragged item,
// then finds the closest container in the direction of the keyboard event and returns its coordinates.
export const coordinateGetter: KeyboardCoordinateGetter = (
event,
{ context: { active, droppableRects, droppableContainers, collisionRect } }
) => {
// If the key pressed is one of the defined directions
if (directions.includes(event.code)) {
// Prevent the default browser behaviour
event.preventDefault();
// If there is no active draggable or collision rectangle, return
if (!active || !collisionRect) {
return;
}
// Create an array to store the droppable containers that meet the criteria
const filteredContainers: DroppableContainer[] = [];
// For each enabled droppable container
droppableContainers.getEnabled().forEach((entry) => {
// If the container is not defined or it is disabled, return
if (!entry || entry?.disabled) {
return;
}
// Get the rectangle of the droppable container
const rect = droppableRects.get(entry.id);
// If the rectangle is not defined, return
if (!rect) {
return;
}
// Get the data of the droppable container
const data = entry.data.current;
// If the data is defined
if (data) {
const { type, children } = data;
// If the droppable container is of type 'container' and it has children
if (type === 'container' && children?.length > 0) {
// If the active draggable is not of type 'container', return
if (active.data.current?.type !== 'container') {
return;
}
}
}
// Depending on the direction of the keyboard event
switch (event.code) {
// If the direction is down and the top of the collision rectangle is above the top of the container rectangle
case KeyboardCode.Down:
if (collisionRect.top < rect.top) {
// Add the container to the array of filtered containers
filteredContainers.push(entry);
}
break;
// If the direction is up and the top of the collision rectangle is below the top of the container rectangle
case KeyboardCode.Up:
if (collisionRect.top > rect.top) {
// Add the container to the array of filtered containers
filteredContainers.push(entry);
}
break;
// If the direction is left and the left of the collision rectangle is to the right of the right of the container rectangle
case KeyboardCode.Left:
if (collisionRect.left >= rect.left + rect.width) {
// Add the container to the array of filtered containers
filteredContainers.push(entry);
}
break;
// If the direction is right and the right of the collision rectangle is to the left of the left of the container rectangle
case KeyboardCode.Right:
if (collisionRect.left + collisionRect.width <= rect.left) {
// Add the container to the array of filtered containers
filteredContainers.push(entry);
}
break;
}
});
// Get the closest corners of the collision rectangle and the filtered containers
const collisions = closestCorners({
active,
collisionRect: collisionRect,
@ -80,28 +108,38 @@ export const coordinateGetter: KeyboardCoordinateGetter = (
droppableContainers: filteredContainers,
pointerCoordinates: null,
});
// Get the id of the first collision
const closestId = getFirstCollision(collisions, 'id');
// If there is a closest id
if (closestId != null) {
// Get the droppable container with the closest id
const newDroppable = droppableContainers.get(closestId);
// Get the node and rectangle of the droppable container
const newNode = newDroppable?.node.current;
const newRect = newDroppable?.rect.current;
// If there is a node and rectangle
if (newNode && newRect) {
// If the droppable container is the placeholder
if (newDroppable.id === 'placeholder') {
// Return the center coordinates of the droppable container
return {
x: newRect.left + (newRect.width - collisionRect.width) / 2,
y: newRect.top + (newRect.height - collisionRect.height) / 2,
};
}
// If the droppable container is of type 'container'
if (newDroppable.data.current?.type === 'container') {
// Return specific coordinates within the droppable container
return {
x: newRect.left + 20,
y: newRect.top + 74,
};
}
// Otherwise, return the top left coordinates of the droppable container
return {
x: newRect.left,
y: newRect.top,
@ -110,5 +148,6 @@ export const coordinateGetter: KeyboardCoordinateGetter = (
}
}
// If none of the above conditions are met, return undefined
return undefined;
};

Loading…
Cancel
Save