@magicbe/design
Version:
React + Antd Drag Drop Visual design
436 lines (435 loc) • 24.1 kB
JavaScript
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;