UNPKG

@magicbe/design

Version:

React + Antd Drag Drop Visual design

436 lines (435 loc) 24.1 kB
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import React, { Fragment, useEffect, useState } from "react"; import { useDesignContext } from "../context"; import { debounce, find, findIndex, first, isEqual, last, remove, unionWith } from "lodash"; import createInstance from "@emotion/css/create-instance"; import { DesignViewsContextProvider, useDesignViewsContext } from "./Context"; import { HoverHolder, ActiveHolder, RootHolder, WidgetHolder, DropWapperHolder, HolderContextMenu } from "./Holders"; import { DATA_DROP, DATA_DROP_WAPPER, DATA_WIDGET } from "../utils/const"; import { DeepRenderComponent } from "./Render"; import { SchemaUtil } from "../utils/schema"; import { message, theme } from "antd"; import { cloneSchemas, findSchemaUuidList, flattSchemaTree, readJson, wrappSchemaTree, writeText } from "../utils/clipboard"; var _a = createInstance({ key: "design" }), css = _a.css, cx = _a.cx; var DesignViews = React.forwardRef(function (_a, ref) { var className = _a.className; return (_jsx(DesignViewsContextProvider, { children: _jsx(DesignViewsRender, { className: className, ref: ref }) })); }); /**主窗口 */ var DesignViewsRender = React.forwardRef(function (_a, ref) { var className = _a.className; var token = theme.useToken().token; var _b = useDesignContext(), setDragWidget = _b.setDragWidget, setHoverAttrs = _b.setHoverAttrs, setActiveSchemaKey = _b.setActiveSchemaKey, schemas = _b.schemas, setSchemas = _b.setSchemas, dragSchemas = _b.dragSchemas, setDragSchemas = _b.setDragSchemas, dragWidget = _b.dragWidget; var _c = useDesignViewsContext(), wapperRef = _c.wapperRef, setHolderToRoot = _c.setHolderToRoot, setHolderToDrop = _c.setHolderToDrop, setHolderToDropWapper = _c.setHolderToDropWapper, setHolderToWidget = _c.setHolderToWidget, setHolderToWidgetLocal = _c.setHolderToWidgetLocal, setHolderContextMenuAttr = _c.setHolderContextMenuAttr, holderToWidgetLocal = _c.holderToWidgetLocal; var _d = useState([]), schemasElement = _d[0], setSchemasElement = _d[1]; var cls = css(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n vertical-align: top;\n border: none;\n position: relative;\n background-color: #F6F6F6F6;\n padding-bottom: 50px;\n "], ["\n vertical-align: top;\n border: none;\n position: relative;\n background-color: #F6F6F6F6;\n padding-bottom: 50px;\n "]))); useEffect(function () { return setSchemasElement(getSchemasElement()); }, [schemas]); var getSchemasElement = function () { var elements = [] .concat(schemas === null || schemas === void 0 ? void 0 : schemas.map(function (_a) { var _b; var uuid = _a.uuid; return (_b = wapperRef.current) === null || _b === void 0 ? void 0 : _b.querySelector("*[".concat(DATA_WIDGET, "=\"").concat(uuid, "\"]")); })) /**插槽容器 */ .concat(schemas === null || schemas === void 0 ? void 0 : schemas.map(function (_a) { var _b; var uuid = _a.uuid; return (_b = wapperRef.current) === null || _b === void 0 ? void 0 : _b.querySelector("*[".concat(DATA_DROP_WAPPER, "=\"").concat(uuid, "\"]")); })) /**插槽容器占位 */ .concat(schemas === null || schemas === void 0 ? void 0 : schemas.map(function (_a) { var _b; var uuid = _a.uuid; return (_b = wapperRef.current) === null || _b === void 0 ? void 0 : _b.querySelector("*[".concat(DATA_DROP, "=\"").concat(uuid, "\"]")); })) .filter(Boolean); return unionWith(elements, isEqual); }; var getDropWidget = function (x, y) { var _a; var rects = schemasElement .filter(function (element) { var rect = element.getClientRects().item(0); if (!rect) return; var left = rect.left, right = rect.right, top = rect.top, bottom = rect.bottom; return (left < x) && (x < right) && (top < y) && (y < bottom); }); var element = last(rects); var widget = element === null || element === void 0 ? void 0 : element.getAttribute(DATA_WIDGET); var drop = element === null || element === void 0 ? void 0 : element.getAttribute(DATA_DROP); var drop_wapper = element === null || element === void 0 ? void 0 : element.getAttribute(DATA_DROP_WAPPER); if (drop_wapper && widget) { var padding = window.getComputedStyle(element).getPropertyValue("padding"); var padding_num = padding.split(" ").map(function (pd) { return pd.replace(/px$/g, ""); }).map(Number); if (padding_num.length === 1) { var padding_1 = padding_num[0]; padding_num = [padding_1, padding_1, padding_1, padding_1]; } if (padding_num.length === 2) { var y_1 = padding_num[0], x_1 = padding_num[1]; padding_num = [y_1, x_1, y_1, x_1]; } if (padding_num.length === 3) { var t = padding_num[0], x_2 = padding_num[1], b = padding_num[2]; padding_num = [t, x_2, b, x_2]; } var pt = padding_num[0], pr = padding_num[1], pb = padding_num[2], pl = padding_num[3]; var rect = element === null || element === void 0 ? void 0 : element.getClientRects().item(0); if (!!rect) { var top_1 = rect.top + pt; var right = rect.right - pr; var bottom = rect.bottom - pb; var left = rect.left + pl; if ((left < x) && (x < right) && (top_1 < y) && (y < bottom)) { widget = undefined; } else { drop_wapper = undefined; } } } return _a = {}, _a[DATA_DROP] = drop, _a[DATA_DROP_WAPPER] = drop_wapper, _a[DATA_WIDGET] = widget, _a; }; /**获取鼠标相对于元素的位置 */ var getMouseRelatTargetLocal = function (x, y, target) { var rect = target.getClientRects().item(0); if (!rect) return; var top = rect.top, right = rect.right, bottom = rect.bottom, left = rect.left; var dlt, drb; { /**距离元素左上角距离 */ var dx = x - left; var dy = y - top; dlt = Math.sqrt(dx * dx + dy * dy); } { /**距离元素右下角距离 */ var dx = x - right; var dy = y - bottom; drb = Math.sqrt(dx * dx + dy * dy); } if (dlt < drb) return "leftTop"; return "rightBottom"; }; /**拖拽 */ var onDragOver = function (event) { return __awaiter(void 0, void 0, void 0, function () { var _a, _b, drop, _c, drop_wapper, _d, widget, target; return __generator(this, function (_e) { event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = "move"; _a = getDropWidget(event.clientX, event.clientY), _b = DATA_DROP, drop = _a[_b], _c = DATA_DROP_WAPPER, drop_wapper = _a[_c], _d = DATA_WIDGET, widget = _a[_d]; target = event.target; setHoverAttrs(undefined); setActiveSchemaKey(undefined); /**插槽 */ if (drop) { setHolderToDrop(drop); setHolderToDropWapper(undefined); setHolderToWidgetLocal(undefined); setHolderToWidget(undefined); setHolderToRoot(false); return [2 /*return*/]; } /**插槽容器 */ if (drop_wapper) { setHolderToDrop(undefined); setHolderToDropWapper(drop_wapper); setHolderToWidgetLocal(undefined); setHolderToWidget(undefined); setHolderToRoot(false); return [2 /*return*/]; } /**组件 */ if (widget) { setHolderToDrop(undefined); setHolderToDropWapper(undefined); setHolderToWidgetLocal(getMouseRelatTargetLocal(event.clientX, event.clientY, target)); setHolderToWidget(widget); setHolderToRoot(false); return [2 /*return*/]; } /**根路径 */ setHolderToDrop(undefined); setHolderToDropWapper(undefined); setHolderToWidgetLocal(undefined); setHolderToWidget(undefined); setHolderToRoot(true); return [2 /*return*/]; }); }); }; var onDragEnter = function () { }; /**离开放置区域 */ var onDragLeave = function (event) { event.preventDefault(); event.stopPropagation(); setHolderContextMenuAttr(undefined); setHolderToRoot(false); setHolderToDrop(undefined); setHolderToWidget(undefined); }; /**放置 */ var onDrop = function (event) { return __awaiter(void 0, void 0, void 0, function () { var _a, _b, drop, _c, drop_wapper, _d, widget, ids_1, nexts_1, index, nexts_2, index, current, nexts_3, index, nexts_4, nexts_5, nexts_6, current, index, nexts_7, nexts; return __generator(this, function (_e) { event.preventDefault(); event.stopPropagation(); setHolderContextMenuAttr(undefined); setDragSchemas(undefined); setDragWidget(undefined); setHolderToRoot(false); setHolderToDrop(undefined); setHolderToWidget(undefined); setHolderToDropWapper(undefined); setHolderToWidgetLocal(undefined); _a = getDropWidget(event.clientX, event.clientY), _b = DATA_DROP, drop = _a[_b], _c = DATA_DROP_WAPPER, drop_wapper = _a[_c], _d = DATA_WIDGET, widget = _a[_d]; /**拖拽的是数据 */ if (dragSchemas) { ids_1 = dragSchemas.map(function (_a) { var uuid = _a.uuid; return uuid; }); if (drop) { nexts_1 = cloneSchemas(dragSchemas, drop); remove(schemas, function (schema) { return ids_1.includes(schema.uuid); }); index = findIndex(schemas, drop); schemas.splice.apply(schemas, __spreadArray([index, 0], nexts_1, false)); setSchemas(schemas); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_1)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } if (drop_wapper) { nexts_2 = cloneSchemas(dragSchemas, drop_wapper); index = findIndex(schemas, { uuid: drop }); remove(schemas, function (schema) { return ids_1.includes(schema.uuid); }); schemas.splice.apply(schemas, __spreadArray([index, 0], nexts_2, false)); setSchemas(schemas); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_2)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } if (widget) { current = find(schemas, { uuid: widget }); nexts_3 = cloneSchemas(dragSchemas, current === null || current === void 0 ? void 0 : current.parent); index = findIndex(schemas, { uuid: widget }); if (!current) return [2 /*return*/]; if (holderToWidgetLocal === "rightBottom") index += 1; remove(schemas, function (schema) { return ids_1.includes(schema.uuid); }); schemas.splice.apply(schemas, __spreadArray([index, 0], nexts_3, false)); setSchemas(schemas); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_3)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } nexts_4 = cloneSchemas(dragSchemas); remove(schemas, function (schema) { return ids_1.includes(schema.uuid); }); setSchemas(schemas.concat(nexts_4)); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_4)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } /**拖拽的是组件 */ if (drop) { nexts_5 = SchemaUtil.createSchemas(dragWidget, drop); setSchemas(schemas.concat(nexts_5)); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_5)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } if (drop_wapper) { nexts_6 = SchemaUtil.createSchemas(dragWidget, drop_wapper); setSchemas(schemas.concat(nexts_6)); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_6)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } if (widget) { current = find(schemas, { uuid: widget }); index = findIndex(schemas, { uuid: widget }); if (!current) return [2 /*return*/]; if (holderToWidgetLocal === "rightBottom") index += 1; nexts_7 = SchemaUtil.createSchemas(dragWidget, current.parent); schemas.splice.apply(schemas, __spreadArray([index, 0], nexts_7, false)); setSchemas(schemas); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts_7)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; } nexts = SchemaUtil.createSchemas(dragWidget); setSchemas(schemas.concat(nexts)); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; }); }); }; /**鼠标离开 */ var onMouseLeave = function () { }; /**鼠标移动 */ var onMouseMove = debounce(function (event) { var clientX = event.clientX, clientY = event.clientY; var attrs = getDropWidget(clientX, clientY); setHoverAttrs(attrs); }, 50, { maxWait: 50 }); /**鼠标右键单击事件 */ var onContextMenu = function (event) { return __awaiter(void 0, void 0, void 0, function () { var _a, _b, drop, _c, drop_wapper, _d, widget, local, items, target, onPaster, onPaster, onCopy, onDel, onPaster; return __generator(this, function (_e) { event.preventDefault(); event.stopPropagation(); _a = getDropWidget(event.clientX, event.clientY), _b = DATA_DROP, drop = _a[_b], _c = DATA_DROP_WAPPER, drop_wapper = _a[_c], _d = DATA_WIDGET, widget = _a[_d]; local = [event.clientX, event.clientY]; items = []; target = undefined; if (drop) { onPaster = function () { return readJson().then(function (schema) { return __awaiter(void 0, void 0, void 0, function () { var nexts, next_schemas; return __generator(this, function (_a) { nexts = flattSchemaTree(schema, drop); next_schemas = schemas.concat(nexts); setSchemas(next_schemas); setHolderContextMenuAttr(undefined); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; }); }); }); }; items = [{ label: "粘贴", onClick: onPaster }]; target = drop; } else if (drop_wapper) { onPaster = function () { return readJson().then(function (schema) { return __awaiter(void 0, void 0, void 0, function () { var nexts, next_schemas; return __generator(this, function (_a) { nexts = flattSchemaTree(schema, drop_wapper); next_schemas = schemas.concat(nexts); setSchemas(next_schemas); setHolderContextMenuAttr(undefined); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; }); }); }); }; items = [{ label: "粘贴", onClick: onPaster }]; target = drop_wapper; } else if (widget) { onCopy = function () { var schema = wrappSchemaTree(schemas, widget); writeText(schema) .then(function () { return message.success("\u590D\u5236\u6210\u529F"); }) .catch(function () { return message.error("\u590D\u5236\u5931\u8D25"); }); setHolderContextMenuAttr(undefined); }; onDel = function () { var ids = findSchemaUuidList(schemas, widget); remove(schemas, function (_a) { var uuid = _a.uuid; return __spreadArray([widget], ids, true).includes(uuid); }); setSchemas(schemas); setHolderContextMenuAttr(undefined); }; items = [ { label: "复制", onClick: onCopy }, { label: _jsx("span", __assign({ style: { color: token.colorErrorTextActive } }, { children: "\u5220\u9664" })), onClick: onDel }, ]; target = widget; } else { onPaster = function () { return readJson().then(function (schema) { return __awaiter(void 0, void 0, void 0, function () { var nexts, next_schemas; return __generator(this, function (_a) { nexts = flattSchemaTree(schema, widget); next_schemas = schemas.concat(nexts); setSchemas(next_schemas); setHolderContextMenuAttr(undefined); setTimeout(function () { var _a; return setActiveSchemaKey((_a = first(nexts)) === null || _a === void 0 ? void 0 : _a.uuid); }); return [2 /*return*/]; }); }); }); }; items = [{ label: "粘贴", onClick: onPaster }]; target = undefined; } setHolderContextMenuAttr({ local: local, items: items, target: target }); return [2 /*return*/]; }); }); }; /**点击事件 */ var onClick = function (event) { var clientX = event.clientX, clientY = event.clientY; var _a = getDropWidget(clientX, clientY), _b = DATA_DROP, drop = _a[_b], _c = DATA_DROP_WAPPER, drop_wapper = _a[_c], _d = DATA_WIDGET, widget = _a[_d]; setActiveSchemaKey(widget || drop_wapper || drop); }; var firsts = schemas === null || schemas === void 0 ? void 0 : schemas.filter(function (_a) { var parent = _a.parent; return !parent; }); return (_jsx(Fragment, { children: _jsxs("div", __assign({ className: cx(cls, className), onDragOver: onDragOver, onDragLeave: onDragLeave, onDragEnter: onDragEnter, onDrop: onDrop, onClick: onClick, onMouseLeave: onMouseLeave, onMouseMove: onMouseMove, onContextMenu: onContextMenu, ref: wapperRef }, { children: [_jsx(DeepRenderComponent, { schemas: firsts }), _jsx(HoverHolder, {}), _jsx(ActiveHolder, {}), _jsx(RootHolder, {}), _jsx(WidgetHolder, {}), _jsx(DropWapperHolder, {}), _jsx(HolderContextMenu, {})] })) })); }); export default DesignViews; var templateObject_1;