UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

152 lines (151 loc) 5.99 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DnDSortableItemStyle = void 0; exports.DnDSortableList = DnDSortableList; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = __importDefault(require("react")); const styles_1 = require("@mui/material/styles"); const sortable_1 = require("@dnd-kit/react/sortable"); const react_2 = require("@dnd-kit/react"); /** * DnD sortable item default style * @param index Item index * @param isDragging Is dragging * @param theme Theme * @returns Style */ const DnDSortableItemStyle = (index, isDragging, theme) => ({ padding: theme.spacing(1), transform: isDragging ? "scale(1.03)" : "none", zIndex: isDragging ? 1 : "auto", boxShadow: isDragging ? `-1px 0 8px 0 ${theme.palette.grey[400]}, 0px 8px 8px 0 ${theme.palette.grey[200]}` : "none", background: isDragging ? theme.palette.primary.light : index % 2 === 0 ? theme.palette.grey[100] : theme.palette.grey[50] }); exports.DnDSortableItemStyle = DnDSortableItemStyle; function SortableItem(props) { const theme = (0, styles_1.useTheme)(); const { id, data, index, itemRenderer, itemStyle = (index, isDragging) => (0, exports.DnDSortableItemStyle)(index, isDragging, theme) } = props; const state = (0, sortable_1.useSortable)({ id, data, index }); const style = itemStyle(index, state.isDragging); return itemRenderer(data, style, state); } /** * DnD sortable list component * @param props Props * @returns Component */ function DnDSortableList(props) { // Destruct const Component = props.component || react_1.default.Fragment; const { componentProps, idField, itemRenderer, itemStyle, labelField, mRef, onChange, onDragStart, onDragEnd } = props; const idFn = typeof idField === "function" ? idField : (item) => !idField ? Reflect.get(item, "id") : item[idField]; const labelFn = react_1.default.useCallback(typeof labelField === "function" ? labelField : (item) => item[labelField], [labelField]); // States const [items, setItems] = react_1.default.useState([]); react_1.default.useEffect(() => { setItems(props.items); }, [props.items]); const changeItems = react_1.default.useCallback((newItems) => { // Possible to alter items with the handler onChange?.(newItems); // Update state setItems(newItems); }, [onChange]); // Methods react_1.default.useImperativeHandle(mRef, () => { return { addItem(newItem) { // Existence check if (items.some((item) => labelFn(item) === labelFn(newItem))) { 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) => labelFn(item) === labelFn(newItem))) { return; } newItems.push(newItem); }); // Update the state changeItems(newItems); return newItems.length - items.length; }, editItem(newItem, index) { // Existence check const newIndex = items.findIndex((item) => labelFn(item) === labelFn(newItem)); 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); }, getItems() { return items; } }; }, [items, labelFn, changeItems]); function handleDragEnd(...args) { // Event const event = args[0]; // Cancelled if (event.canceled) return; if ((0, sortable_1.isSortableOperation)(event.operation) && event.operation.source) { const { initialIndex, index } = event.operation.source; if (initialIndex === index) return; // Clone const newItems = [...items]; // Removed item const [removed] = newItems.splice(initialIndex, 1); // Insert to the destination index newItems.splice(index, 0, removed); changeItems(newItems); // Drag end handler onDragEnd?.(newItems, ...args); } } return ((0, jsx_runtime_1.jsx)(react_2.DragDropProvider, { onDragStart: (event) => onDragStart?.(items, event), onDragEnd: (event, manager) => handleDragEnd(event, manager), children: (0, jsx_runtime_1.jsx)(Component, { ...componentProps, children: items.map((item, index) => { const id = idFn(item); return ((0, jsx_runtime_1.jsx)(SortableItem, { id: id, index: index, data: item, itemRenderer: itemRenderer, itemStyle: itemStyle }, id)); }) }) })); }