123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import {useEffect, useMemo, useState} from 'react';
- import type {DragEndEvent} from '@dnd-kit/core';
- import {arrayMove} from '@dnd-kit/sortable';
- export type Column = {
- column: string | undefined;
- id: number;
- };
- interface UseDragAndDropColumnsProps {
- columns: string[];
- setColumns: (columns: string[]) => void;
- }
- const extractColumns = (editableColumns: Column[]) => {
- return editableColumns.map(({column}) => column ?? '');
- };
- export function useDragNDropColumns({columns, setColumns}: UseDragAndDropColumnsProps) {
- const mappedColumns = useMemo(() => {
- return columns.map((column, i) => ({id: i + 1, column}));
- }, [columns]);
- const [editableColumns, setEditableColumns] = useState<Column[]>(mappedColumns);
- useEffect(() => {
- setEditableColumns(prevEditableColumns => {
- // Only update if there's a change between columns and editableColumns
- if (
- JSON.stringify(prevEditableColumns.map(c => c.column)) !== JSON.stringify(columns)
- ) {
- return mappedColumns;
- }
- return prevEditableColumns;
- });
- }, [columns, mappedColumns]);
- const [nextId, setNextId] = useState(editableColumns.length + 1);
- function insertColumn() {
- setEditableColumns(oldEditableColumns => {
- const newEditableColumns = oldEditableColumns.slice();
- newEditableColumns.push({id: nextId, column: undefined});
- setNextId(nextId + 1); // make sure to increment the id for the next time
- setColumns(extractColumns(newEditableColumns));
- return newEditableColumns;
- });
- }
- function updateColumnAtIndex(i: number, column: string) {
- setEditableColumns(oldEditableColumns => {
- const newEditableColumns = [...oldEditableColumns];
- newEditableColumns[i].column = column;
- setColumns(extractColumns(newEditableColumns));
- return newEditableColumns;
- });
- }
- function deleteColumnAtIndex(i: number) {
- setEditableColumns(oldEditableColumns => {
- if (oldEditableColumns.length === 1) {
- setColumns(['']);
- return [{id: 1, column: undefined}];
- }
- const newEditableColumns = [
- ...oldEditableColumns.slice(0, i),
- ...oldEditableColumns.slice(i + 1),
- ];
- setColumns(extractColumns(newEditableColumns));
- return newEditableColumns;
- });
- }
- function onDragEnd(event: DragEndEvent) {
- const {active, over} = event;
- if (active.id !== over?.id) {
- const oldIndex = editableColumns.findIndex(({id}) => id === active.id);
- const newIndex = editableColumns.findIndex(({id}) => id === over?.id);
- setEditableColumns(oldEditableColumns => {
- const newEditableColumns = arrayMove(oldEditableColumns, oldIndex, newIndex);
- setColumns(extractColumns(newEditableColumns));
- return newEditableColumns;
- });
- }
- }
- return {
- editableColumns,
- insertColumn,
- updateColumnAtIndex,
- deleteColumnAtIndex,
- onDragEnd,
- };
- }
|