@etsoo/react
Version:
TypeScript ReactJs UI Independent Framework
137 lines (136 loc) • 5.2 kB
JavaScript
;
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));
}) }) }));
}