UNPKG

@etsoo/react

Version:

TypeScript ReactJs UI Independent Framework

137 lines (136 loc) 5.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DnDList = DnDList; const jsx_runtime_1 = require("react/jsx-runtime"); const core_1 = require("@dnd-kit/core"); const sortable_1 = require("@dnd-kit/sortable"); const utilities_1 = require("@dnd-kit/utilities"); const react_1 = __importDefault(require("react")); function SortableItem(props) { // Destruct const { id, itemRenderer, style = {} } = props; // Use sortable const { attributes, listeners, setNodeRef, transform, transition, setActivatorNodeRef } = (0, sortable_1.useSortable)({ id }); const allStyle = { ...style, transform: utilities_1.CSS.Transform.toString(transform), transition }; const nodeRef = { style: allStyle, ref: setNodeRef, ...attributes }; const actionNodeRef = { ...listeners, ref: setActivatorNodeRef }; return itemRenderer(nodeRef, actionNodeRef); } /** * DnD (Drag and Drop) sortable list * @param props Props * @returns Component */ function DnDList(props) { // Destruct const { getItemStyle, keyField, itemRenderer, labelField, mRef, onChange, onDragEnd } = props; // States const [items, setItems] = react_1.default.useState([]); const [activeId, setActiveId] = react_1.default.useState(); const changeItems = (newItems) => { // Possible to alter items with the handler if (onChange) onChange(newItems); // Update state setItems(newItems); }; // Drag event handlers function handleDragStart(event) { const { active } = event; setActiveId(active.id); } function handleDragEnd(event) { const { active, over } = event; if (over && active.id !== over.id) { // Indices const oldIndex = items.findIndex((item) => item.id === active.id); const newIndex = items.findIndex((item) => item.id === over.id); // Clone const newItems = [...items]; // Removed item const [removed] = newItems.splice(oldIndex, 1); // Insert to the destination index newItems.splice(newIndex, 0, removed); changeItems(newItems); // Drag end handler if (onDragEnd) onDragEnd(newItems); } setActiveId(undefined); } // Methods react_1.default.useImperativeHandle(mRef, () => { return { addItem(newItem) { // Existence check if (items.some((item) => item[labelField] === newItem[labelField])) { return false; } // Clone const newItems = [newItem, ...items]; // Update the state changeItems(newItems); return true; }, addItems(inputItems) { // Clone const newItems = [...items]; // Insert items inputItems.forEach((newItem) => { // Existence check if (newItems.some((item) => item[labelField] === newItem[labelField])) { return; } newItems.push(newItem); }); // Update the state changeItems(newItems); return newItems.length - items.length; }, editItem(newItem, index) { // Existence check const newIndex = items.findIndex((item) => item[labelField] === newItem[labelField]); if (newIndex >= 0 && newIndex !== index) { // Label field is the same with a different item return false; } // Clone const newItems = [...items]; // Remove the item newItems.splice(index, 1, newItem); // Update the state changeItems(newItems); return true; }, deleteItem(index) { // Clone const newItems = [...items]; // Remove the item newItems.splice(index, 1); // Update the state changeItems(newItems); } }; }, [items]); react_1.default.useEffect(() => { setItems(props.items); }, [props.items]); return ((0, jsx_runtime_1.jsx)(core_1.DndContext, { onDragStart: handleDragStart, onDragEnd: handleDragEnd, children: (0, jsx_runtime_1.jsx)(sortable_1.SortableContext, { items: items, strategy: sortable_1.verticalListSortingStrategy, children: items.map((item, index) => { const id = item[keyField]; return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, style: getItemStyle(index, id === activeId), itemRenderer: (nodeRef, actionNodeRef) => itemRenderer(item, index, nodeRef, actionNodeRef) }, id)); }) }) })); }