mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-12 15:22:35 +02:00
add draggable table column reorder
This commit is contained in:
@@ -191,6 +191,33 @@
|
||||
padding: 0 var(--theme-spacing-xl);
|
||||
}
|
||||
|
||||
.header-dragging {
|
||||
cursor: grabbing;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.header-dragged-over-left::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
width: 3px;
|
||||
content: '';
|
||||
background-color: var(--theme-colors-primary);
|
||||
}
|
||||
|
||||
.header-dragged-over-right::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
width: 3px;
|
||||
content: '';
|
||||
background-color: var(--theme-colors-primary);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
import {
|
||||
attachClosestEdge,
|
||||
type Edge,
|
||||
extractClosestEdge,
|
||||
} from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
|
||||
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
||||
import {
|
||||
draggable,
|
||||
dropTargetForElements,
|
||||
} from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
|
||||
import { disableNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/disable-native-drag-preview';
|
||||
import { useMergedRef } from '@mantine/hooks';
|
||||
import clsx from 'clsx';
|
||||
import React, { CSSProperties, ReactNode, useEffect, useRef, useState } from 'react';
|
||||
@@ -38,7 +49,13 @@ import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { useDoubleClick } from '/@/shared/hooks/use-double-click';
|
||||
import { LibraryItem, QueueSong, Song } from '/@/shared/types/domain-types';
|
||||
import { DragOperation, DragTarget, DragTargetMap } from '/@/shared/types/drag-and-drop';
|
||||
import {
|
||||
dndUtils,
|
||||
DragData,
|
||||
DragOperation,
|
||||
DragTarget,
|
||||
DragTargetMap,
|
||||
} from '/@/shared/types/drag-and-drop';
|
||||
import { TableColumn } from '/@/shared/types/types';
|
||||
|
||||
export interface ItemTableListColumn extends CellComponentProps<TableItemProps> {}
|
||||
@@ -808,15 +825,101 @@ export const TableColumnHeaderContainer = (
|
||||
props.controls.onColumnResized?.({ columnId, width });
|
||||
};
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [isDraggedOver, setIsDraggedOver] = useState<Edge | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!containerRef.current || !props.enableColumnReorder) {
|
||||
return;
|
||||
}
|
||||
|
||||
const handleReorder = (
|
||||
columnIdFrom: TableColumn,
|
||||
columnIdTo: TableColumn,
|
||||
edge: Edge | null,
|
||||
) => {
|
||||
props.controls.onColumnReordered?.({ columnIdFrom, columnIdTo, edge });
|
||||
};
|
||||
|
||||
return combine(
|
||||
draggable({
|
||||
element: containerRef.current,
|
||||
getInitialData: () => {
|
||||
const data = dndUtils.generateDragData({
|
||||
id: [props.type],
|
||||
operation: [DragOperation.REORDER],
|
||||
type: DragTarget.TABLE_COLUMN,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
onDragStart: () => {
|
||||
setIsDragging(true);
|
||||
},
|
||||
onDrop: () => {
|
||||
setIsDragging(false);
|
||||
},
|
||||
onGenerateDragPreview: (data) => {
|
||||
disableNativeDragPreview({ nativeSetDragImage: data.nativeSetDragImage });
|
||||
},
|
||||
}),
|
||||
dropTargetForElements({
|
||||
canDrop: (args) => {
|
||||
const data = args.source.data as unknown as DragData;
|
||||
const isSelf = (args.source.data.id as string[])[0] === props.type;
|
||||
return dndUtils.isDropTarget(data.type, [DragTarget.TABLE_COLUMN]) && !isSelf;
|
||||
},
|
||||
element: containerRef.current,
|
||||
getData: ({ element, input }) => {
|
||||
const data = dndUtils.generateDragData({
|
||||
id: [props.type],
|
||||
operation: [DragOperation.REORDER],
|
||||
type: DragTarget.TABLE_COLUMN,
|
||||
});
|
||||
|
||||
return attachClosestEdge(data, {
|
||||
allowedEdges: ['left', 'right'],
|
||||
element,
|
||||
input,
|
||||
});
|
||||
},
|
||||
onDrag: (args) => {
|
||||
const closestEdgeOfTarget: Edge | null = extractClosestEdge(args.self.data);
|
||||
setIsDraggedOver(closestEdgeOfTarget);
|
||||
},
|
||||
onDragLeave: () => {
|
||||
setIsDraggedOver(null);
|
||||
},
|
||||
onDrop: (args) => {
|
||||
const closestEdgeOfTarget: Edge | null = extractClosestEdge(args.self.data);
|
||||
|
||||
const from = args.source.data.id as string[];
|
||||
const to = args.self.data.id as string[];
|
||||
|
||||
handleReorder(
|
||||
from[0] as TableColumn,
|
||||
to[0] as TableColumn,
|
||||
closestEdgeOfTarget,
|
||||
);
|
||||
setIsDraggedOver(null);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}, [props.type, props.enableColumnReorder, props.controls]);
|
||||
|
||||
return (
|
||||
<Flex
|
||||
className={clsx(styles.container, styles.headerContainer, props.containerClassName, {
|
||||
[styles.headerDraggedOverLeft]: isDraggedOver === 'left',
|
||||
[styles.headerDraggedOverRight]: isDraggedOver === 'right',
|
||||
[styles.headerDragging]: isDragging,
|
||||
[styles.paddingLg]: props.cellPadding === 'lg',
|
||||
[styles.paddingMd]: props.cellPadding === 'md',
|
||||
[styles.paddingSm]: props.cellPadding === 'sm',
|
||||
[styles.paddingXl]: props.cellPadding === 'xl',
|
||||
[styles.paddingXs]: props.cellPadding === 'xs',
|
||||
})}
|
||||
ref={containerRef}
|
||||
style={props.style}
|
||||
>
|
||||
<Text
|
||||
|
||||
@@ -90,6 +90,7 @@ interface VirtualizedTableGridProps {
|
||||
controls: ItemControls;
|
||||
data: unknown[];
|
||||
enableAlternateRowColors: boolean;
|
||||
enableColumnReorder: boolean;
|
||||
enableColumnResize: boolean;
|
||||
enableDrag?: boolean;
|
||||
enableExpansion: boolean;
|
||||
@@ -128,6 +129,7 @@ const VirtualizedTableGrid = React.memo(
|
||||
controls,
|
||||
data,
|
||||
enableAlternateRowColors,
|
||||
enableColumnReorder,
|
||||
enableColumnResize,
|
||||
enableDrag,
|
||||
enableExpansion,
|
||||
@@ -169,6 +171,7 @@ const VirtualizedTableGrid = React.memo(
|
||||
controls,
|
||||
data: enableHeader ? [null, ...data] : data,
|
||||
enableAlternateRowColors,
|
||||
enableColumnReorder,
|
||||
enableColumnResize,
|
||||
enableDrag,
|
||||
enableExpansion,
|
||||
@@ -191,6 +194,7 @@ const VirtualizedTableGrid = React.memo(
|
||||
enableHeader,
|
||||
data,
|
||||
enableAlternateRowColors,
|
||||
enableColumnReorder,
|
||||
enableColumnResize,
|
||||
enableDrag,
|
||||
enableExpansion,
|
||||
@@ -475,6 +479,7 @@ export interface TableItemProps {
|
||||
controls: ItemControls;
|
||||
data: ItemTableListProps['data'];
|
||||
enableAlternateRowColors?: ItemTableListProps['enableAlternateRowColors'];
|
||||
enableColumnReorder?: boolean;
|
||||
enableColumnResize?: boolean;
|
||||
enableDrag?: ItemTableListProps['enableDrag'];
|
||||
enableExpansion?: ItemTableListProps['enableExpansion'];
|
||||
@@ -515,6 +520,11 @@ interface ItemTableListProps {
|
||||
type: 'index' | 'offset';
|
||||
};
|
||||
itemType: LibraryItem;
|
||||
onColumnReordered?: (
|
||||
columnIdFrom: TableColumn,
|
||||
columnIdTo: TableColumn,
|
||||
edge: 'top' | 'bottom' | 'left' | 'right' | null,
|
||||
) => void;
|
||||
onColumnResized?: (columnId: TableColumn, width: number) => void;
|
||||
onRangeChanged?: (range: { startIndex: number; stopIndex: number }) => void;
|
||||
onScrollEnd?: (offset: number, internalState: ItemListStateActions) => void;
|
||||
@@ -542,6 +552,7 @@ export const ItemTableList = ({
|
||||
headerHeight = 40,
|
||||
initialTop,
|
||||
itemType,
|
||||
onColumnReordered,
|
||||
onColumnResized,
|
||||
onRangeChanged,
|
||||
onScrollEnd,
|
||||
@@ -1372,6 +1383,7 @@ export const ItemTableList = ({
|
||||
}, [imperativeHandle]);
|
||||
|
||||
const controls = useDefaultItemListControls({
|
||||
onColumnReordered,
|
||||
onColumnResized,
|
||||
});
|
||||
|
||||
@@ -1390,6 +1402,7 @@ export const ItemTableList = ({
|
||||
controls={controls}
|
||||
data={data}
|
||||
enableAlternateRowColors={enableAlternateRowColors}
|
||||
enableColumnReorder={!!onColumnReordered}
|
||||
enableColumnResize={!!onColumnResized}
|
||||
enableDrag={enableDrag}
|
||||
enableExpansion={enableExpansion}
|
||||
|
||||
Reference in New Issue
Block a user