UNPKG

@undermuz/react-json-form

Version:
195 lines (194 loc) 5.24 kB
// src/array-form/ArrayFormTabs.tsx import { useCallback, useMemo, useState } from "react"; import { closestCenter, DndContext, DragOverlay, getFirstCollision, PointerSensor, pointerWithin, rectIntersection, useDroppable, useSensor, useSensors } from "@dnd-kit/core"; import { horizontalListSortingStrategy, SortableContext, useSortable } from "@dnd-kit/sortable"; import { CSS } from "@dnd-kit/utilities"; import { createPortal } from "react-dom"; import { useJsonFormUi } from "../contexts/ui.mjs"; import ArrayFormItem from "./ArrayFormItem.mjs"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { createElement } from "react"; var SortableTab = ({ tabId, ...props }) => { const Ui = useJsonFormUi(); const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: tabId }); const style = { transform: CSS.Transform.toString(transform), transition }; if (!Ui?.Tab) { return null; } return /* @__PURE__ */ jsx( Ui.Tab, { ...props, ref: setNodeRef, style, ...attributes, ...listeners } ); }; var TrashDroppable = () => { const Ui = useJsonFormUi(); const { isOver, setNodeRef } = useDroppable({ id: "trash" }); if (!Ui?.ArrayForm?.TrashContainer) { return null; } return /* @__PURE__ */ jsx( Ui.ArrayForm.TrashContainer, { isOver, ref: setNodeRef, label: "\u041E\u0442\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u0447\u0442\u043E\u0431\u044B \u0443\u0434\u0430\u043B\u0438\u0442\u044C" } ); }; var SortableList = ({ tabs, onSortEnd, children }) => { const [activeId, setActiveId] = useState(null); const sensors = useSensors( useSensor(PointerSensor, { activationConstraint: { distance: 20 } }) ); const currentIndex = useMemo(() => { return tabs.findIndex((_i) => _i.id === activeId); }, [tabs, activeId]); const collisionDetectionStrategy = useCallback( (args) => { const pointerIntersections = pointerWithin(args); const intersections = pointerIntersections.length > 0 ? ( // If there are droppables intersecting with the pointer, return those pointerIntersections ) : rectIntersection(args); let overId = getFirstCollision(intersections, "id"); if (overId === "trash") { return intersections; } if (overId !== null) { return closestCenter(args); } return []; }, [activeId, tabs] ); return /* @__PURE__ */ jsxs( DndContext, { sensors, collisionDetection: collisionDetectionStrategy, onDragEnd: (event) => { console.log("[onDragEnd]", event); setActiveId(null); onSortEnd(event); }, onDragStart: (event) => { setActiveId(event.active.id); }, children: [ /* @__PURE__ */ jsx( SortableContext, { id: "list", items: tabs, strategy: horizontalListSortingStrategy, children } ), typeof document !== "undefined" && createPortal( /* @__PURE__ */ jsx(DragOverlay, { children: currentIndex > -1 ? /* @__PURE__ */ jsx( SortableTab, { tabId: activeId, label: `#${currentIndex + 1}` } ) : null }), document.body ), activeId !== null && /* @__PURE__ */ jsx(TrashDroppable, {}) ] } ); }; var ArrayFormTabs = (props) => { const { value, tab, addTab, removeTab, changeTab, setTabErrors, sortTabs, setTab, fillArrayDefault, onRef, ...rest } = props; const tabs = value; const Ui = useJsonFormUi(); const body = value.map((item) => { return /* @__PURE__ */ createElement( ArrayFormItem, { ...rest, key: item.id, id: item.id, isShow: item.id === tab, value: item, onRef, onChange: changeTab, onError: setTabErrors } ); }); if (!Ui?.ArrayForm || !Ui.Tab || !Ui.Icons) return /* @__PURE__ */ jsx(Fragment, { children: body }); return /* @__PURE__ */ jsxs(Ui.ArrayForm, { style: { position: "relative", zIndex: 1 }, children: [ /* @__PURE__ */ jsxs(Ui.ArrayForm.Header, { children: [ /* @__PURE__ */ jsx(Ui.ArrayForm.Tabs, { children: /* @__PURE__ */ jsx(SortableList, { tabs, onSortEnd: sortTabs, children: tabs.map((val, index) => /* @__PURE__ */ jsx( SortableTab, { label: `#${index + 1}`, tabId: val.id, active: tab === val.id, onSelect: () => setTab(val.id) }, val.id )) }) }), /* @__PURE__ */ jsxs(Ui.ArrayForm.Tabs, { actions: true, children: [ (!fillArrayDefault || value.length > 1) && /* @__PURE__ */ jsx(Ui.Tab, { onSelect: () => removeTab(tab), children: /* @__PURE__ */ jsx(Ui.Icons.Tabs.Remove, {}) }), /* @__PURE__ */ jsx(Ui.Tab, { onSelect: addTab, children: /* @__PURE__ */ jsx(Ui.Icons.Tabs.Add, {}) }) ] }) ] }), /* @__PURE__ */ jsx(Ui.ArrayForm.Body, { children: body }) ] }); }; export { ArrayFormTabs };