build: change build-scripts to vite
This commit is contained in:
parent
50465d6499
commit
17f736b130
|
@ -4,7 +4,10 @@
|
||||||
"mainEntryPointFilePath": "<projectFolder>/temp/index.d.ts",
|
"mainEntryPointFilePath": "<projectFolder>/temp/index.d.ts",
|
||||||
|
|
||||||
"compiler": {
|
"compiler": {
|
||||||
"tsconfigFilePath": "<projectFolder>/tsconfig.declaration.json"
|
"tsconfigFilePath": "<projectFolder>/tsconfig.declaration.json",
|
||||||
|
"overrideTsconfig": {
|
||||||
|
"baseUrl": "<projectFolder>/temp"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"dtsRollup": {
|
"dtsRollup": {
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
module.exports = require('../../babel.config');
|
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
|
||||||
],
|
|
||||||
"babelPlugins": [
|
|
||||||
["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
const { join } = require('path');
|
|
||||||
const esModules = [].join('|');
|
|
||||||
const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.'));
|
|
||||||
|
|
||||||
const jestConfig = {
|
|
||||||
// transform: {
|
|
||||||
// '^.+\\.[jt]sx?$': 'babel-jest',
|
|
||||||
// // '^.+\\.(ts|tsx)$': 'ts-jest',
|
|
||||||
// // '^.+\\.(js|jsx)$': 'babel-jest',
|
|
||||||
// },
|
|
||||||
// testMatch: ['**/node-children.test.ts'],
|
|
||||||
// testMatch: ['**/plugin-manager.test.ts'],
|
|
||||||
// testMatch: ['**/history/history.test.ts'],
|
|
||||||
// testMatch: ['**/document-model.test.ts'],
|
|
||||||
// testMatch: ['**/prop.test.ts'],
|
|
||||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
|
||||||
// testMatch: ['**/document/node/node.add.test.ts'],
|
|
||||||
// testMatch: ['**/setting-field.test.ts'],
|
|
||||||
// testMatch: ['**/node.test.ts'],
|
|
||||||
// testMatch: ['**/builtin-hotkey.test.ts'],
|
|
||||||
// testMatch: ['**/selection.test.ts'],
|
|
||||||
// testMatch: ['**/plugin/sequencify.test.ts'],
|
|
||||||
// testMatch: ['**/builtin-simulator/utils/parse-metadata.test.ts'],
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
`/node_modules/(?!${esModules})/`,
|
|
||||||
],
|
|
||||||
setupFiles: ['./tests/fixtures/unhandled-rejection.ts'],
|
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
|
||||||
collectCoverage: false,
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src/**/*.ts',
|
|
||||||
'!src/**/*.d.ts',
|
|
||||||
'!src/icons/**',
|
|
||||||
'!src/locale/**',
|
|
||||||
'!src/builtin-simulator/utils/**',
|
|
||||||
'!src/plugin/sequencify.ts',
|
|
||||||
'!src/document/node/exclusive-group.ts',
|
|
||||||
'!src/document/node/props/value-to-source.ts',
|
|
||||||
'!src/builtin-simulator/live-editing/live-editing.ts',
|
|
||||||
'!src/designer/offset-observer.ts',
|
|
||||||
'!src/designer/clipboard.ts',
|
|
||||||
'!src/designer/scroller.ts',
|
|
||||||
'!src/builtin-simulator/host.ts',
|
|
||||||
'!**/node_modules/**',
|
|
||||||
'!**/vendor/**',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 只对本仓库内的 pkg 做 mapping
|
|
||||||
jestConfig.moduleNameMapper = {};
|
|
||||||
jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '<rootDir>/../$1/src';
|
|
||||||
|
|
||||||
module.exports = jestConfig;
|
|
|
@ -2,47 +2,56 @@
|
||||||
"name": "@alilc/lowcode-designer",
|
"name": "@alilc/lowcode-designer",
|
||||||
"version": "2.0.0-beta.0",
|
"version": "2.0.0-beta.0",
|
||||||
"description": "Designer for Ali LowCode Engine",
|
"description": "Designer for Ali LowCode Engine",
|
||||||
"main": "lib/index.js",
|
"type": "module",
|
||||||
"module": "es/index.js",
|
"main": "dist/designer.cjs",
|
||||||
|
"module": "dist/designer.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/designer.js",
|
||||||
|
"require": "./dist/designer.cjs",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib",
|
"dist",
|
||||||
"es"
|
"src",
|
||||||
|
"package.json"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "build-scripts build",
|
"build": "vite build",
|
||||||
"test": "build-scripts test --config build.test.json",
|
"build-dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs",
|
||||||
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
"test": "vitest",
|
||||||
|
"test:cov": ""
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alilc/lowcode-editor-core": "1.3.2",
|
"@alilc/lowcode-editor-core": "workspace:*",
|
||||||
"@alilc/lowcode-types": "1.3.2",
|
"@alilc/lowcode-types": "workspace:*",
|
||||||
"@alilc/lowcode-utils": "1.3.2",
|
"@alilc/lowcode-utils": "workspace:*",
|
||||||
"classnames": "^2.2.6",
|
"@alifd/next": "^1.27.8",
|
||||||
"react": "^16",
|
"classnames": "^2.5.1",
|
||||||
"react-dom": "^16.7.0",
|
"lodash-es": "^4.17.20",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
"ric-shim": "^1.0.1",
|
"ric-shim": "^1.0.1",
|
||||||
"semver": "^7.3.5"
|
"semver": "^7.6.0",
|
||||||
|
"events": "^3.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.29",
|
"@testing-library/react": "^14.2.2",
|
||||||
"@testing-library/react": "^11.2.2",
|
"@types/lodash-es": "^4.14.165",
|
||||||
"@types/classnames": "^2.2.7",
|
"@types/prop-types": "^15.7.12",
|
||||||
"@types/enzyme": "^3.10.12",
|
"@types/react": "^18.2.0",
|
||||||
"@types/enzyme-adapter-react-16": "^1.0.6",
|
"@types/react-dom": "^18.2.0",
|
||||||
"@types/jest": "^26.0.16",
|
"@types/semver": "7.5.8",
|
||||||
"@types/lodash": "^4.14.165",
|
"less": "^4.2.0"
|
||||||
"@types/medium-editor": "^5.0.3",
|
},
|
||||||
"@types/node": "^13.7.1",
|
"peerDependencies": {
|
||||||
"@types/react": "^16",
|
"@alifd/next": "^1.27.8",
|
||||||
"@types/react-dom": "^16",
|
"react": "^18.2.0",
|
||||||
"@types/semver": "7.3.9",
|
"react-dom": "^18.2.0"
|
||||||
"enzyme": "^3.11.0",
|
|
||||||
"enzyme-adapter-react-16": "^1.15.5",
|
|
||||||
"jest": "^26.6.3",
|
|
||||||
"lodash": "^4.17.20",
|
|
||||||
"moment": "^2.29.1",
|
|
||||||
"typescript": "^4.0.3"
|
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|
|
@ -35,9 +35,7 @@ export class BorderDetectingInstance extends PureComponent<{
|
||||||
return (
|
return (
|
||||||
<div className={className} style={style}>
|
<div className={className} style={style}>
|
||||||
<Title title={title} className="lc-borders-title" />
|
<Title title={title} className="lc-borders-title" />
|
||||||
{
|
{isLocked ? <Title title={intl('locked')} className="lc-borders-status" /> : null}
|
||||||
isLocked ? (<Title title={intl('locked')} className="lc-borders-status" />) : null
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +75,10 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||||
const { current } = this;
|
const { current } = this;
|
||||||
|
|
||||||
const canHoverHook = current?.componentMeta.advanced.callbacks?.onHoverHook;
|
const canHoverHook = current?.componentMeta.advanced.callbacks?.onHoverHook;
|
||||||
const canHover = (canHoverHook && typeof canHoverHook === 'function') ? canHoverHook(current.internalToShellNode()) : true;
|
const canHover =
|
||||||
|
canHoverHook && typeof canHoverHook === 'function'
|
||||||
|
? canHoverHook(current.internalToShellNode()!)
|
||||||
|
: true;
|
||||||
|
|
||||||
if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) {
|
if (!canHover || !current || host.viewport.scrolling || host.liveEditing.editing) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -104,7 +105,7 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lockedNode = getClosestNode(current, (n) => {
|
const lockedNode = getClosestNode(current as any, (n) => {
|
||||||
// 假如当前节点就是 locked 状态,要从当前节点的父节点开始查找
|
// 假如当前节点就是 locked 状态,要从当前节点的父节点开始查找
|
||||||
return !!(current?.isLocked ? n.parent?.isLocked : n.isLocked);
|
return !!(current?.isLocked ? n.parent?.isLocked : n.isLocked);
|
||||||
});
|
});
|
||||||
|
@ -118,7 +119,10 @@ export class BorderDetecting extends Component<{ host: BuiltinSimulatorHost }> {
|
||||||
scrollX={this.scrollX}
|
scrollX={this.scrollX}
|
||||||
scrollY={this.scrollY}
|
scrollY={this.scrollY}
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
rect={host.computeComponentInstanceRect(host.getComponentInstances(lockedNode)[0], lockedNode.componentMeta.rootSelector)}
|
rect={host.computeComponentInstanceRect(
|
||||||
|
host.getComponentInstances(lockedNode)![0],
|
||||||
|
lockedNode.componentMeta.rootSelector,
|
||||||
|
)}
|
||||||
isLocked={lockedNode?.getId() !== current.getId()}
|
isLocked={lockedNode?.getId() !== current.getId()}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -89,7 +89,12 @@ export class BoxResizingForNode extends Component<{ host: BuiltinSimulatorHost;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<BoxResizingInstance key={observed.id} dragging={this.dragging} designer={designer} observed={observed} />
|
<BoxResizingInstance
|
||||||
|
key={observed.id}
|
||||||
|
dragging={this.dragging}
|
||||||
|
designer={designer}
|
||||||
|
observed={observed}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -135,41 +140,38 @@ export class BoxResizingInstance extends Component<{
|
||||||
// this.hoveringCapture.setBoundary(this.outline);
|
// this.hoveringCapture.setBoundary(this.outline);
|
||||||
this.willBind();
|
this.willBind();
|
||||||
|
|
||||||
const resize = (e: MouseEvent, direction: string, node: INode, moveX: number, moveY: number) => {
|
const resize = (
|
||||||
|
e: MouseEvent,
|
||||||
|
direction: string,
|
||||||
|
node: INode,
|
||||||
|
moveX: number,
|
||||||
|
moveY: number,
|
||||||
|
) => {
|
||||||
const { advanced } = node.componentMeta;
|
const { advanced } = node.componentMeta;
|
||||||
if (
|
if (advanced.callbacks && typeof advanced.callbacks.onResize === 'function') {
|
||||||
advanced.callbacks &&
|
|
||||||
typeof advanced.callbacks.onResize === 'function'
|
|
||||||
) {
|
|
||||||
(e as any).trigger = direction;
|
(e as any).trigger = direction;
|
||||||
(e as any).deltaX = moveX;
|
(e as any).deltaX = moveX;
|
||||||
(e as any).deltaY = moveY;
|
(e as any).deltaY = moveY;
|
||||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||||
advanced.callbacks.onResize(e, cbNode);
|
advanced.callbacks.onResize(e as any, cbNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const resizeStart = (e: MouseEvent, direction: string, node: INode) => {
|
const resizeStart = (e: MouseEvent, direction: string, node: INode) => {
|
||||||
const { advanced } = node.componentMeta;
|
const { advanced } = node.componentMeta;
|
||||||
if (
|
if (advanced.callbacks && typeof advanced.callbacks.onResizeStart === 'function') {
|
||||||
advanced.callbacks &&
|
|
||||||
typeof advanced.callbacks.onResizeStart === 'function'
|
|
||||||
) {
|
|
||||||
(e as any).trigger = direction;
|
(e as any).trigger = direction;
|
||||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||||
advanced.callbacks.onResizeStart(e, cbNode);
|
advanced.callbacks.onResizeStart(e as any, cbNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const resizeEnd = (e: MouseEvent, direction: string, node: INode) => {
|
const resizeEnd = (e: MouseEvent, direction: string, node: INode) => {
|
||||||
const { advanced } = node.componentMeta;
|
const { advanced } = node.componentMeta;
|
||||||
if (
|
if (advanced.callbacks && typeof advanced.callbacks.onResizeEnd === 'function') {
|
||||||
advanced.callbacks &&
|
|
||||||
typeof advanced.callbacks.onResizeEnd === 'function'
|
|
||||||
) {
|
|
||||||
(e as any).trigger = direction;
|
(e as any).trigger = direction;
|
||||||
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
const cbNode = node?.isNode ? node.internalToShellNode() : node;
|
||||||
advanced.callbacks.onResizeEnd(e, cbNode);
|
advanced.callbacks.onResizeEnd(e as any, cbNode as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
const editor = node.document?.designer.editor;
|
const editor = node.document?.designer.editor;
|
||||||
|
@ -241,14 +243,16 @@ export class BoxResizingInstance extends Component<{
|
||||||
let offsetTop = 0;
|
let offsetTop = 0;
|
||||||
let offsetLeft = 0;
|
let offsetLeft = 0;
|
||||||
if (observed.hasOffset) {
|
if (observed.hasOffset) {
|
||||||
offsetWidth = observed.offsetWidth;
|
offsetWidth = observed.offsetWidth!;
|
||||||
offsetHeight = observed.offsetHeight;
|
offsetHeight = observed.offsetHeight!;
|
||||||
offsetTop = observed.offsetTop;
|
offsetTop = observed.offsetTop;
|
||||||
offsetLeft = observed.offsetLeft;
|
offsetLeft = observed.offsetLeft;
|
||||||
const { node } = observed;
|
const { node } = observed;
|
||||||
const metadata = node.componentMeta.getMetadata();
|
const metadata = node.componentMeta.getMetadata();
|
||||||
if (metadata.configure?.advanced?.getResizingHandlers) {
|
if (metadata.configure?.advanced?.getResizingHandlers) {
|
||||||
triggerVisible = metadata.configure.advanced.getResizingHandlers(node.internalToShellNode());
|
triggerVisible = metadata.configure.advanced.getResizingHandlers(
|
||||||
|
node.internalToShellNode(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triggerVisible = normalizeTriggers(triggerVisible);
|
triggerVisible = normalizeTriggers(triggerVisible);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
Fragment,
|
Fragment,
|
||||||
ReactNodeArray,
|
|
||||||
isValidElement,
|
isValidElement,
|
||||||
cloneElement,
|
cloneElement,
|
||||||
createElement,
|
createElement,
|
||||||
|
@ -54,11 +53,8 @@ export class BorderSelectingInstance extends Component<{
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={className} style={style}>
|
||||||
className={className}
|
{!dragging && !hideComponentAction ? <Toolbar observed={observed} /> : null}
|
||||||
style={style}
|
|
||||||
>
|
|
||||||
{(!dragging && !hideComponentAction) ? <Toolbar observed={observed} /> : null}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -68,7 +64,7 @@ export class BorderSelectingInstance extends Component<{
|
||||||
class Toolbar extends Component<{ observed: OffsetObserver }> {
|
class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||||
render() {
|
render() {
|
||||||
const { observed } = this.props;
|
const { observed } = this.props;
|
||||||
const { height, width } = observed.viewport;
|
const { height, width } = observed.viewport!;
|
||||||
const BAR_HEIGHT = 20;
|
const BAR_HEIGHT = 20;
|
||||||
const MARGIN = 1;
|
const MARGIN = 1;
|
||||||
const BORDER = 2;
|
const BORDER = 2;
|
||||||
|
@ -81,7 +77,7 @@ class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||||
top: -SPACE_HEIGHT,
|
top: -SPACE_HEIGHT,
|
||||||
height: BAR_HEIGHT,
|
height: BAR_HEIGHT,
|
||||||
};
|
};
|
||||||
} else if (observed.bottom + SPACE_HEIGHT < height) {
|
} else if (observed.bottom! + SPACE_HEIGHT < height) {
|
||||||
style = {
|
style = {
|
||||||
bottom: -SPACE_HEIGHT,
|
bottom: -SPACE_HEIGHT,
|
||||||
height: BAR_HEIGHT,
|
height: BAR_HEIGHT,
|
||||||
|
@ -93,21 +89,24 @@ class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// 计算 toolbar 的左/右位置
|
// 计算 toolbar 的左/右位置
|
||||||
if (SPACE_MINIMUM_WIDTH > observed.left + observed.width) {
|
if (SPACE_MINIMUM_WIDTH > observed.left + observed.width!) {
|
||||||
style.left = Math.max(-BORDER, observed.left - width - BORDER);
|
style.left = Math.max(-BORDER, observed.left - width - BORDER);
|
||||||
} else {
|
} else {
|
||||||
style.right = Math.max(-BORDER, observed.right - width - BORDER);
|
style.right = Math.max(-BORDER, observed.right! - width - BORDER);
|
||||||
style.justifyContent = 'flex-start';
|
style.justifyContent = 'flex-start';
|
||||||
}
|
}
|
||||||
const { node } = observed;
|
const { node } = observed;
|
||||||
const actions: ReactNodeArray = [];
|
const actions: ReactNode[] = [];
|
||||||
node.componentMeta.availableActions.forEach((action) => {
|
node.componentMeta.availableActions.forEach((action) => {
|
||||||
const { important = true, condition, content, name } = action;
|
const { important = true, condition, content, name } = action;
|
||||||
if (node.isSlot() && (name === 'copy' || name === 'remove')) {
|
if (node.isSlot() && (name === 'copy' || name === 'remove')) {
|
||||||
// FIXME: need this?
|
// FIXME: need this?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (important && (typeof condition === 'function' ? condition(node) !== false : condition !== false)) {
|
if (
|
||||||
|
important &&
|
||||||
|
(typeof condition === 'function' ? condition(node) !== false : condition !== false)
|
||||||
|
) {
|
||||||
actions.push(createAction(content, name, node));
|
actions.push(createAction(content, name, node));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -120,7 +119,11 @@ class Toolbar extends Component<{ observed: OffsetObserver }> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActionContentObject, key: string, node: INode) {
|
function createAction(
|
||||||
|
content: ReactNode | ComponentType<any> | IPublicTypeActionContentObject,
|
||||||
|
key: string,
|
||||||
|
node: INode,
|
||||||
|
) {
|
||||||
if (isValidElement<{ key: string; node: INode }>(content)) {
|
if (isValidElement<{ key: string; node: INode }>(content)) {
|
||||||
return cloneElement(content, { key, node });
|
return cloneElement(content, { key, node });
|
||||||
}
|
}
|
||||||
|
@ -148,7 +151,7 @@ function createAction(content: ReactNode | ComponentType<any> | IPublicTypeActio
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{icon && createIcon(icon, { key, node: node.internalToShellNode() })}
|
{icon && createIcon(icon, { key, node: node.internalToShellNode() })}
|
||||||
<Tip>{title}</Tip>
|
<Tip>{title as any}</Tip>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -187,7 +190,13 @@ export class BorderSelectingForNode extends Component<{ host: ISimulatorHost; no
|
||||||
if (!observed) {
|
if (!observed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <BorderSelectingInstance key={observed.id} dragging={this.dragging} observed={observed} />;
|
return (
|
||||||
|
<BorderSelectingInstance
|
||||||
|
key={observed.id}
|
||||||
|
dragging={this.dragging}
|
||||||
|
observed={observed}
|
||||||
|
/>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
|
|
@ -52,7 +52,7 @@ export default class DragResizeEngine {
|
||||||
if (!sourceDocument || sourceDocument === document) {
|
if (!sourceDocument || sourceDocument === document) {
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
const srcSim = masterSensors.find(sim => sim.contentDocument === sourceDocument);
|
const srcSim = masterSensors.find((sim) => sim.contentDocument === sourceDocument);
|
||||||
if (srcSim) {
|
if (srcSim) {
|
||||||
return srcSim.viewport.toGlobalPoint(e);
|
return srcSim.viewport.toGlobalPoint(e);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ export default class DragResizeEngine {
|
||||||
|
|
||||||
const over = (e: MouseEvent) => {
|
const over = (e: MouseEvent) => {
|
||||||
const handleEvents = makeEventsHandler(e, masterSensors);
|
const handleEvents = makeEventsHandler(e, masterSensors);
|
||||||
handleEvents(doc => {
|
handleEvents((doc) => {
|
||||||
doc.removeEventListener('mousemove', move, true);
|
doc.removeEventListener('mousemove', move, true);
|
||||||
doc.removeEventListener('mouseup', over, true);
|
doc.removeEventListener('mouseup', over, true);
|
||||||
});
|
});
|
||||||
|
@ -77,7 +77,7 @@ export default class DragResizeEngine {
|
||||||
node = boost(e);
|
node = boost(e);
|
||||||
startEvent = createResizeEvent(e);
|
startEvent = createResizeEvent(e);
|
||||||
const handleEvents = makeEventsHandler(e, masterSensors);
|
const handleEvents = makeEventsHandler(e, masterSensors);
|
||||||
handleEvents(doc => {
|
handleEvents((doc) => {
|
||||||
doc.addEventListener('mousemove', move, true);
|
doc.addEventListener('mousemove', move, true);
|
||||||
doc.addEventListener('mouseup', over, true);
|
doc.addEventListener('mouseup', over, true);
|
||||||
});
|
});
|
||||||
|
@ -87,9 +87,9 @@ export default class DragResizeEngine {
|
||||||
this.designer.detecting.enable = false;
|
this.designer.detecting.enable = false;
|
||||||
cursor.addState('ew-resize');
|
cursor.addState('ew-resize');
|
||||||
};
|
};
|
||||||
shell.addEventListener('mousedown', mousedown);
|
shell.addEventListener('mousedown', mousedown as any);
|
||||||
return () => {
|
return () => {
|
||||||
shell.removeEventListener('mousedown', mousedown);
|
shell.removeEventListener('mousedown', mousedown as any);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ export default class DragResizeEngine {
|
||||||
|
|
||||||
private getMasterSensors(): ISimulatorHost[] {
|
private getMasterSensors(): ISimulatorHost[] {
|
||||||
return this.designer.project.documents
|
return this.designer.project.documents
|
||||||
.map(doc => {
|
.map((doc) => {
|
||||||
if (doc.active && doc.simulator?.sensorAvailable) {
|
if (doc.active && doc.simulator?.sensorAvailable) {
|
||||||
return doc.simulator;
|
return doc.simulator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import { Component } from 'react';
|
import { Component } from 'react';
|
||||||
import { observer } from '@alilc/lowcode-editor-core';
|
import { observer } from '@alilc/lowcode-editor-core';
|
||||||
import { BuiltinSimulatorHost } from '../host';
|
import { BuiltinSimulatorHost } from '../host';
|
||||||
import {
|
import { DropLocation, isVertical } from '../../designer';
|
||||||
DropLocation,
|
|
||||||
isVertical,
|
|
||||||
} from '../../designer';
|
|
||||||
import { ISimulatorHost } from '../../simulator';
|
import { ISimulatorHost } from '../../simulator';
|
||||||
import { INode } from '../../document';
|
import { INode } from '../../document';
|
||||||
import './insertion.less';
|
import './insertion.less';
|
||||||
import { IPublicTypeNodeData, IPublicTypeNodeSchema, IPublicTypeLocationChildrenDetail, IPublicTypeRect } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypeNodeData,
|
||||||
|
IPublicTypeLocationChildrenDetail,
|
||||||
|
IPublicTypeRect,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
import { isLocationChildrenDetail } from '@alilc/lowcode-utils';
|
import { isLocationChildrenDetail } from '@alilc/lowcode-utils';
|
||||||
|
|
||||||
interface InsertionData {
|
interface InsertionData {
|
||||||
|
@ -23,7 +24,11 @@ interface InsertionData {
|
||||||
/**
|
/**
|
||||||
* 处理拖拽子节点(INode)情况
|
* 处理拖拽子节点(INode)情况
|
||||||
*/
|
*/
|
||||||
function processChildrenDetail(sim: ISimulatorHost, container: INode, detail: IPublicTypeLocationChildrenDetail): InsertionData {
|
function processChildrenDetail(
|
||||||
|
sim: ISimulatorHost,
|
||||||
|
container: INode,
|
||||||
|
detail: IPublicTypeLocationChildrenDetail,
|
||||||
|
): InsertionData {
|
||||||
let edge = detail.edge || null;
|
let edge = detail.edge || null;
|
||||||
|
|
||||||
if (!edge) {
|
if (!edge) {
|
||||||
|
@ -40,7 +45,7 @@ function processChildrenDetail(sim: ISimulatorHost, container: INode, detail: IP
|
||||||
|
|
||||||
if (detail.near) {
|
if (detail.near) {
|
||||||
const { node, pos, rect, align } = detail.near;
|
const { node, pos, rect, align } = detail.near;
|
||||||
ret.nearRect = rect || sim.computeRect(node);
|
ret.nearRect = rect || sim.computeRect(node as any);
|
||||||
ret.nearNode = node;
|
ret.nearNode = node;
|
||||||
if (pos === 'replace') {
|
if (pos === 'replace') {
|
||||||
// FIXME: ret.nearRect mybe null
|
// FIXME: ret.nearRect mybe null
|
||||||
|
@ -65,10 +70,10 @@ function processChildrenDetail(sim: ISimulatorHost, container: INode, detail: IP
|
||||||
ret.insertType = 'cover';
|
ret.insertType = 'cover';
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
let nearNode = container.children.get(index);
|
let nearNode = container.children?.get(index);
|
||||||
if (!nearNode) {
|
if (!nearNode) {
|
||||||
// index = 0, eg. nochild,
|
// index = 0, eg. nochild,
|
||||||
nearNode = container.children.get(index > 0 ? index - 1 : 0);
|
nearNode = container.children?.get(index > 0 ? index - 1 : 0);
|
||||||
if (!nearNode) {
|
if (!nearNode) {
|
||||||
ret.insertType = 'cover';
|
ret.insertType = 'cover';
|
||||||
ret.coverRect = edge;
|
ret.coverRect = edge;
|
||||||
|
@ -95,7 +100,7 @@ function processChildrenDetail(sim: ISimulatorHost, container: INode, detail: IP
|
||||||
* 将 detail 信息转换为页面"坐标"信息
|
* 将 detail 信息转换为页面"坐标"信息
|
||||||
*/
|
*/
|
||||||
function processDetail({ target, detail, document }: DropLocation): InsertionData {
|
function processDetail({ target, detail, document }: DropLocation): InsertionData {
|
||||||
const sim = document.simulator;
|
const sim = document!.simulator;
|
||||||
if (!sim) {
|
if (!sim) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -126,7 +131,7 @@ export class InsertionView extends Component<{ host: BuiltinSimulatorHost }> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { scale, scrollX, scrollY } = host.viewport;
|
const { scale, scrollX, scrollY } = host.viewport;
|
||||||
const { edge, insertType, coverRect, nearRect, vertical, nearNode } = processDetail(loc);
|
const { edge, insertType, coverRect, nearRect, vertical, nearNode } = processDetail(loc as any);
|
||||||
|
|
||||||
if (!edge) {
|
if (!edge) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -159,7 +164,7 @@ export class InsertionView extends Component<{ host: BuiltinSimulatorHost }> {
|
||||||
y = ((insertType === 'before' ? nearRect.top : nearRect.bottom) + scrollY) * scale;
|
y = ((insertType === 'before' ? nearRect.top : nearRect.bottom) + scrollY) * scale;
|
||||||
style.width = nearRect.width * scale;
|
style.width = nearRect.width * scale;
|
||||||
}
|
}
|
||||||
if (y === 0 && (nearNode as IPublicTypeNodeSchema)?.componentMeta?.isTopFixed) {
|
if (y === 0 && (nearNode as any)?.componentMeta?.isTopFixed) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,7 @@ import {
|
||||||
IEventBus,
|
IEventBus,
|
||||||
} from '@alilc/lowcode-editor-core';
|
} from '@alilc/lowcode-editor-core';
|
||||||
|
|
||||||
import {
|
import { ISimulatorHost, Component, DropContainer } from '../simulator';
|
||||||
ISimulatorHost,
|
|
||||||
Component,
|
|
||||||
DropContainer,
|
|
||||||
} from '../simulator';
|
|
||||||
import Viewport from './viewport';
|
import Viewport from './viewport';
|
||||||
import { createSimulator } from './create-simulator';
|
import { createSimulator } from './create-simulator';
|
||||||
import { Node, INode, contains, isRootNode, isLowCodeComponent } from '../document';
|
import { Node, INode, contains, isRootNode, isLowCodeComponent } from '../document';
|
||||||
|
@ -71,7 +67,7 @@ import { LiveEditing } from './live-editing/live-editing';
|
||||||
import { IProject, Project } from '../project';
|
import { IProject, Project } from '../project';
|
||||||
import { IScroller } from '../designer/scroller';
|
import { IScroller } from '../designer/scroller';
|
||||||
import { isElementNode, isDOMNodeVisible } from '../utils/misc';
|
import { isElementNode, isDOMNodeVisible } from '../utils/misc';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
const logger = new Logger({ level: 'warn', bizName: 'designer' });
|
const logger = new Logger({ level: 'warn', bizName: 'designer' });
|
||||||
|
|
||||||
|
@ -352,24 +348,30 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
*/
|
*/
|
||||||
connect(
|
connect(
|
||||||
renderer: BuiltinSimulatorRenderer,
|
renderer: BuiltinSimulatorRenderer,
|
||||||
effect: (reaction: IReactionPublic) => void, options?: IReactionOptions,
|
effect: (reaction: IReactionPublic) => void,
|
||||||
|
options?: IReactionOptions<any, boolean>,
|
||||||
) {
|
) {
|
||||||
this._renderer = renderer;
|
this._renderer = renderer;
|
||||||
return autorun(effect, options);
|
return autorun(effect, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
reaction(expression: (reaction: IReactionPublic) => unknown, effect: (value: unknown, prev: unknown, reaction: IReactionPublic) => void,
|
reaction(
|
||||||
opts?: IReactionOptions | undefined): IReactionDisposer {
|
expression: (reaction: IReactionPublic) => unknown,
|
||||||
|
effect: (value: unknown, prev: unknown, reaction: IReactionPublic) => void,
|
||||||
|
opts?: IReactionOptions<any, boolean> | undefined,
|
||||||
|
): IReactionDisposer {
|
||||||
return reaction(expression, effect, opts);
|
return reaction(expression, effect, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
autorun(effect: (reaction: IReactionPublic) => void, options?: IReactionOptions): IReactionDisposer {
|
autorun(
|
||||||
|
effect: (reaction: IReactionPublic) => void,
|
||||||
|
options?: IReactionOptions<any, boolean>,
|
||||||
|
): IReactionDisposer {
|
||||||
return autorun(effect, options);
|
return autorun(effect, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
purge(): void {
|
purge(): void {
|
||||||
// todo
|
// todo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mountViewport(viewport: HTMLElement | null) {
|
mountViewport(viewport: HTMLElement | null) {
|
||||||
|
@ -450,11 +452,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
|
|
||||||
const vendors = [
|
const vendors = [
|
||||||
// required & use once
|
// required & use once
|
||||||
assetBundle(
|
assetBundle(this.get('environment') || defaultEnvironment, AssetLevel.Environment),
|
||||||
this.get('environment') ||
|
|
||||||
defaultEnvironment,
|
|
||||||
AssetLevel.Environment,
|
|
||||||
),
|
|
||||||
// required & use once
|
// required & use once
|
||||||
assetBundle(this.get('extraEnvironment'), AssetLevel.Environment),
|
assetBundle(this.get('extraEnvironment'), AssetLevel.Environment),
|
||||||
|
|
||||||
|
@ -463,11 +461,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
// required & TODO: think of update
|
// required & TODO: think of update
|
||||||
assetBundle(this.theme, AssetLevel.Theme),
|
assetBundle(this.theme, AssetLevel.Theme),
|
||||||
// required & use once
|
// required & use once
|
||||||
assetBundle(
|
assetBundle(this.get('simulatorUrl') || defaultSimulatorUrl, AssetLevel.Runtime),
|
||||||
this.get('simulatorUrl') ||
|
|
||||||
defaultSimulatorUrl,
|
|
||||||
AssetLevel.Runtime,
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// wait 准备 iframe 内容、依赖库注入
|
// wait 准备 iframe 内容、依赖库注入
|
||||||
|
@ -555,8 +549,8 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// FIXME: dirty fix remove label-for fro liveEditing
|
// FIXME: dirty fix remove label-for fro liveEditing
|
||||||
downEvent.target?.removeAttribute('for');
|
(downEvent.target as any)?.removeAttribute('for');
|
||||||
const nodeInst = this.getNodeInstanceFromElement(downEvent.target);
|
const nodeInst = this.getNodeInstanceFromElement(downEvent.target as any);
|
||||||
const { focusNode } = documentModel;
|
const { focusNode } = documentModel;
|
||||||
const node = getClosestClickableNode(nodeInst?.node || focusNode, downEvent);
|
const node = getClosestClickableNode(nodeInst?.node || focusNode, downEvent);
|
||||||
// 如果找不到可点击的节点,直接返回
|
// 如果找不到可点击的节点,直接返回
|
||||||
|
@ -572,7 +566,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
const isRGLNode = rglNode?.isRGLContainer;
|
const isRGLNode = rglNode?.isRGLContainer;
|
||||||
if (isRGLNode) {
|
if (isRGLNode) {
|
||||||
// 如果拖拽的是磁铁块的右下角 handle,则直接跳过
|
// 如果拖拽的是磁铁块的右下角 handle,则直接跳过
|
||||||
if (downEvent.target?.classList.contains('react-resizable-handle')) return;
|
if ((downEvent.target as any)?.classList.contains('react-resizable-handle')) return;
|
||||||
// 禁止多选
|
// 禁止多选
|
||||||
isMulti = false;
|
isMulti = false;
|
||||||
designer.dragon.emitter.emit('rgl.switch', {
|
designer.dragon.emitter.emit('rgl.switch', {
|
||||||
|
@ -649,7 +643,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
{
|
{
|
||||||
type: IPublicEnumDragObjectType.Node,
|
type: IPublicEnumDragObjectType.Node,
|
||||||
nodes,
|
nodes,
|
||||||
},
|
} as any,
|
||||||
downEvent,
|
downEvent,
|
||||||
isRGLNode ? rglNode : undefined,
|
isRGLNode ? rglNode : undefined,
|
||||||
);
|
);
|
||||||
|
@ -697,10 +691,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
'.next-calendar-table',
|
'.next-calendar-table',
|
||||||
'.editor-container', // 富文本组件
|
'.editor-container', // 富文本组件
|
||||||
];
|
];
|
||||||
const ignoreSelectors = customizeIgnoreSelectors?.(defaultIgnoreSelectors, e) || defaultIgnoreSelectors;
|
const ignoreSelectors =
|
||||||
|
customizeIgnoreSelectors?.(defaultIgnoreSelectors, e) || defaultIgnoreSelectors;
|
||||||
const ignoreSelectorsString = ignoreSelectors.join(',');
|
const ignoreSelectorsString = ignoreSelectors.join(',');
|
||||||
// 提供了 customizeIgnoreSelectors 的情况下,忽略 isFormEvent() 判断
|
// 提供了 customizeIgnoreSelectors 的情况下,忽略 isFormEvent() 判断
|
||||||
if ((!customizeIgnoreSelectors && isFormEvent(e)) || target?.closest(ignoreSelectorsString)) {
|
if (
|
||||||
|
(!customizeIgnoreSelectors && isFormEvent(e)) ||
|
||||||
|
(target as any)?.closest(ignoreSelectorsString)
|
||||||
|
) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
@ -918,7 +916,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
/**
|
/**
|
||||||
* @see ISimulator
|
* @see ISimulator
|
||||||
*/
|
*/
|
||||||
getComponentInstances(node: INode, context?: IPublicTypeNodeInstance): IPublicTypeComponentInstance[] | null {
|
getComponentInstances(
|
||||||
|
node: INode,
|
||||||
|
context?: IPublicTypeNodeInstance,
|
||||||
|
): IPublicTypeComponentInstance[] | null {
|
||||||
const docId = node.document?.id;
|
const docId = node.document?.id;
|
||||||
if (!docId) {
|
if (!docId) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -966,7 +967,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
/**
|
/**
|
||||||
* @see ISimulator
|
* @see ISimulator
|
||||||
*/
|
*/
|
||||||
computeComponentInstanceRect(instance: IPublicTypeComponentInstance, selector?: string): IPublicTypeRect | null {
|
computeComponentInstanceRect(
|
||||||
|
instance: IPublicTypeComponentInstance,
|
||||||
|
selector?: string,
|
||||||
|
): IPublicTypeRect | null {
|
||||||
const renderer = this.renderer!;
|
const renderer = this.renderer!;
|
||||||
const elements = this.findDOMNodes(instance, selector);
|
const elements = this.findDOMNodes(instance, selector);
|
||||||
if (!elements) {
|
if (!elements) {
|
||||||
|
@ -1032,7 +1036,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
/**
|
/**
|
||||||
* @see ISimulator
|
* @see ISimulator
|
||||||
*/
|
*/
|
||||||
findDOMNodes(instance: IPublicTypeComponentInstance, selector?: string): Array<Element | Text> | null {
|
findDOMNodes(
|
||||||
|
instance: IPublicTypeComponentInstance,
|
||||||
|
selector?: string,
|
||||||
|
): Array<Element | Text> | null {
|
||||||
const elements = this._renderer?.findDOMNodes(instance);
|
const elements = this._renderer?.findDOMNodes(instance);
|
||||||
if (!elements) {
|
if (!elements) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1051,7 +1058,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
/**
|
/**
|
||||||
* 通过 DOM 节点获取节点,依赖 simulator 的接口
|
* 通过 DOM 节点获取节点,依赖 simulator 的接口
|
||||||
*/
|
*/
|
||||||
getNodeInstanceFromElement(target: Element | null): IPublicTypeNodeInstance<IPublicTypeComponentInstance, INode> | null {
|
getNodeInstanceFromElement(
|
||||||
|
target: Element | null,
|
||||||
|
): IPublicTypeNodeInstance<IPublicTypeComponentInstance, INode> | null {
|
||||||
if (!target) {
|
if (!target) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1191,9 +1200,12 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
|
|
||||||
const nodes = dragObject?.nodes;
|
const nodes = dragObject?.nodes;
|
||||||
|
|
||||||
const operationalNodes = nodes?.filter((node) => {
|
const operationalNodes = nodes?.filter((node: any) => {
|
||||||
const onMoveHook = node.componentMeta?.advanced.callbacks?.onMoveHook;
|
const onMoveHook = node.componentMeta?.advanced.callbacks?.onMoveHook;
|
||||||
const canMove = onMoveHook && typeof onMoveHook === 'function' ? onMoveHook(node.internalToShellNode()) : true;
|
const canMove =
|
||||||
|
onMoveHook && typeof onMoveHook === 'function'
|
||||||
|
? onMoveHook(node.internalToShellNode())
|
||||||
|
: true;
|
||||||
|
|
||||||
let parentContainerNode: INode | null = null;
|
let parentContainerNode: INode | null = null;
|
||||||
let parentNode = node.parent;
|
let parentNode = node.parent;
|
||||||
|
@ -1207,9 +1219,16 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
parentNode = parentNode.parent;
|
parentNode = parentNode.parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChildMoveHook = parentContainerNode?.componentMeta?.advanced.callbacks?.onChildMoveHook;
|
const onChildMoveHook =
|
||||||
|
parentContainerNode?.componentMeta?.advanced.callbacks?.onChildMoveHook;
|
||||||
|
|
||||||
const childrenCanMove = onChildMoveHook && parentContainerNode && typeof onChildMoveHook === 'function' ? onChildMoveHook(node.internalToShellNode(), parentContainerNode.internalToShellNode()) : true;
|
const childrenCanMove =
|
||||||
|
onChildMoveHook && parentContainerNode && typeof onChildMoveHook === 'function'
|
||||||
|
? onChildMoveHook(
|
||||||
|
node!.internalToShellNode(),
|
||||||
|
(parentContainerNode as any).internalToShellNode(),
|
||||||
|
)
|
||||||
|
: true;
|
||||||
|
|
||||||
return canMove && childrenCanMove;
|
return canMove && childrenCanMove;
|
||||||
});
|
});
|
||||||
|
@ -1225,16 +1244,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const dropContainer = this.getDropContainer(e);
|
const dropContainer = this.getDropContainer(e);
|
||||||
const lockedNode = getClosestNode(dropContainer?.container, (node) => node.isLocked);
|
const lockedNode = getClosestNode(dropContainer?.container as any, (node) => node.isLocked);
|
||||||
if (lockedNode) return null;
|
if (lockedNode) return null;
|
||||||
if (
|
if (!dropContainer) {
|
||||||
!dropContainer
|
|
||||||
) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLocationData(dropContainer)) {
|
if (isLocationData(dropContainer)) {
|
||||||
return this.designer.createLocation(dropContainer);
|
return this.designer.createLocation(dropContainer as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { container, instance: containerInstance } = dropContainer;
|
const { container, instance: containerInstance } = dropContainer;
|
||||||
|
@ -1267,7 +1284,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
e.dragObject &&
|
e.dragObject &&
|
||||||
e.dragObject.nodes &&
|
e.dragObject.nodes &&
|
||||||
e.dragObject.nodes.length &&
|
e.dragObject.nodes.length &&
|
||||||
e.dragObject.nodes[0].componentMeta.isModal &&
|
e.dragObject.nodes[0]?.componentMeta?.isModal &&
|
||||||
document.focusNode
|
document.focusNode
|
||||||
) {
|
) {
|
||||||
return this.designer.createLocation({
|
return this.designer.createLocation({
|
||||||
|
@ -1296,8 +1313,9 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
const inst = instances
|
const inst = instances
|
||||||
? instances.length > 1
|
? instances.length > 1
|
||||||
? instances.find(
|
? instances.find(
|
||||||
(_inst) => this.getClosestNodeInstance(_inst, container.id)?.instance === containerInstance,
|
(_inst) =>
|
||||||
)
|
this.getClosestNodeInstance(_inst, container.id)?.instance === containerInstance,
|
||||||
|
)
|
||||||
: instances[0]
|
: instances[0]
|
||||||
: null;
|
: null;
|
||||||
const rect = inst
|
const rect = inst
|
||||||
|
@ -1420,7 +1438,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
// get common parent, avoid drop container contains by dragObject
|
// get common parent, avoid drop container contains by dragObject
|
||||||
const drillDownExcludes = new Set<INode>();
|
const drillDownExcludes = new Set<INode>();
|
||||||
if (isDragNodeObject(dragObject)) {
|
if (isDragNodeObject(dragObject)) {
|
||||||
const { nodes } = dragObject;
|
const { nodes } = dragObject as any;
|
||||||
let i = nodes.length;
|
let i = nodes.length;
|
||||||
let p: any = container;
|
let p: any = container;
|
||||||
while (i-- > 0) {
|
while (i-- > 0) {
|
||||||
|
@ -1495,14 +1513,14 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
const { dragObject } = e;
|
const { dragObject } = e;
|
||||||
const document = this.currentDocument!;
|
const document = this.currentDocument!;
|
||||||
const { focusNode } = document;
|
const { focusNode } = document;
|
||||||
if (isRootNode(container) || container.contains(focusNode)) {
|
if (isRootNode(container) || container.contains(focusNode!)) {
|
||||||
return document.checkNesting(focusNode!, dragObject as any);
|
return document.checkNesting(focusNode!, dragObject as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
const meta = (container as Node).componentMeta;
|
const meta = (container as Node).componentMeta;
|
||||||
|
|
||||||
// FIXME: get containerInstance for accept logic use
|
// FIXME: get containerInstance for accept logic use
|
||||||
const acceptable: boolean = this.isAcceptable(container);
|
const acceptable: boolean = this.isAcceptable();
|
||||||
if (!meta.isContainer && !acceptable) {
|
if (!meta.isContainer && !acceptable) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1514,10 +1532,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost<BuiltinSimulatorProp
|
||||||
/**
|
/**
|
||||||
* 查找邻近容器
|
* 查找邻近容器
|
||||||
*/
|
*/
|
||||||
getNearByContainer(
|
getNearByContainer({ container, instance }: DropContainer, drillDownExcludes: Set<INode>) {
|
||||||
{ container, instance }: DropContainer,
|
|
||||||
drillDownExcludes: Set<INode>,
|
|
||||||
) {
|
|
||||||
const { children } = container;
|
const { children } = container;
|
||||||
if (!children || children.isEmpty()) {
|
if (!children || children.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -59,21 +59,23 @@ export class LiveEditing {
|
||||||
const editor = node.document?.designer.editor;
|
const editor = node.document?.designer.editor;
|
||||||
const npm = node?.componentMeta?.npm;
|
const npm = node?.componentMeta?.npm;
|
||||||
const selected =
|
const selected =
|
||||||
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') || node?.componentMeta?.componentName || '';
|
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
||||||
|
node?.componentMeta?.componentName ||
|
||||||
|
'';
|
||||||
editor?.eventBus.emit('designer.builtinSimulator.liveEditing', {
|
editor?.eventBus.emit('designer.builtinSimulator.liveEditing', {
|
||||||
selected,
|
selected,
|
||||||
});
|
});
|
||||||
|
|
||||||
let setterPropElement = getSetterPropElement(targetElement, rootElement);
|
let setterPropElement = getSetterPropElement(targetElement, rootElement);
|
||||||
let propTarget = setterPropElement?.dataset.setterProp;
|
let propTarget = setterPropElement?.dataset.setterProp;
|
||||||
let matched: (IPublicTypePluginConfig & { propElement?: HTMLElement }) | undefined | null;
|
let matched: (IPublicTypePluginConfig & { propElement?: HTMLElement }) | undefined | null | any;
|
||||||
if (liveTextEditing) {
|
if (liveTextEditing) {
|
||||||
if (propTarget) {
|
if (propTarget) {
|
||||||
// 已埋点命中 data-setter-prop="proptarget", 从 liveTextEditing 读取配置(mode|onSaveContent)
|
// 已埋点命中 data-setter-prop="proptarget", 从 liveTextEditing 读取配置(mode|onSaveContent)
|
||||||
matched = liveTextEditing.find(config => config.propTarget == propTarget);
|
matched = liveTextEditing.find((config) => config.propTarget == propTarget);
|
||||||
} else {
|
} else {
|
||||||
// 执行 embedTextEditing selector 规则,获得第一个节点 是否 contains e.target,若匹配,读取配置
|
// 执行 embedTextEditing selector 规则,获得第一个节点 是否 contains e.target,若匹配,读取配置
|
||||||
matched = liveTextEditing.find(config => {
|
matched = liveTextEditing.find((config) => {
|
||||||
if (!config.selector) {
|
if (!config.selector) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +91,8 @@ export class LiveEditing {
|
||||||
});
|
});
|
||||||
if (matched) {
|
if (matched) {
|
||||||
propTarget = matched.propTarget;
|
propTarget = matched.propTarget;
|
||||||
setterPropElement = matched.propElement || queryPropElement(rootElement, targetElement, matched.selector);
|
setterPropElement =
|
||||||
|
matched.propElement || queryPropElement(rootElement, targetElement, matched.selector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,9 +120,15 @@ export class LiveEditing {
|
||||||
// 4. 监听 blur 事件
|
// 4. 监听 blur 事件
|
||||||
// 5. 设置编辑锁定:disable hover | disable select | disable canvas drag
|
// 5. 设置编辑锁定:disable hover | disable select | disable canvas drag
|
||||||
|
|
||||||
const onSaveContent = matched?.onSaveContent || saveHandlers.find(item => item.condition(prop))?.onSaveContent || defaultSaveContent;
|
const onSaveContent =
|
||||||
|
matched?.onSaveContent ||
|
||||||
|
saveHandlers.find((item) => item.condition(prop as any))?.onSaveContent ||
|
||||||
|
defaultSaveContent;
|
||||||
|
|
||||||
setterPropElement.setAttribute('contenteditable', matched?.mode && matched.mode !== 'plaintext' ? 'true' : 'plaintext-only');
|
setterPropElement.setAttribute(
|
||||||
|
'contenteditable',
|
||||||
|
matched?.mode && matched.mode !== 'plaintext' ? 'true' : 'plaintext-only',
|
||||||
|
);
|
||||||
setterPropElement.classList.add('engine-live-editing');
|
setterPropElement.classList.add('engine-live-editing');
|
||||||
// be sure
|
// be sure
|
||||||
setterPropElement.focus();
|
setterPropElement.focus();
|
||||||
|
@ -134,7 +143,7 @@ export class LiveEditing {
|
||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
break;
|
break;
|
||||||
// TODO: check is richtext?
|
// TODO: check is richtext?
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
break;
|
break;
|
||||||
case 'Tab':
|
case 'Tab':
|
||||||
|
@ -157,7 +166,7 @@ export class LiveEditing {
|
||||||
setterPropElement!.removeEventListener('keydown', keydown, true);
|
setterPropElement!.removeEventListener('keydown', keydown, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
this._editing = prop;
|
this._editing = prop as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: process enter | esc events & joint the FocusTracker
|
// TODO: process enter | esc events & joint the FocusTracker
|
||||||
|
@ -186,9 +195,11 @@ export class LiveEditing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SpecificRule = (target: EditingTarget) => (IPublicTypeLiveTextEditingConfig & {
|
export type SpecificRule = (target: EditingTarget) =>
|
||||||
propElement?: HTMLElement;
|
| (IPublicTypeLiveTextEditingConfig & {
|
||||||
}) | null;
|
propElement?: HTMLElement;
|
||||||
|
})
|
||||||
|
| null;
|
||||||
|
|
||||||
export interface SaveHandler {
|
export interface SaveHandler {
|
||||||
condition: (prop: Prop) => boolean;
|
condition: (prop: Prop) => boolean;
|
||||||
|
@ -223,7 +234,9 @@ function queryPropElement(rootElement: HTMLElement, targetElement: HTMLElement,
|
||||||
}
|
}
|
||||||
if (!propElement.contains(targetElement)) {
|
if (!propElement.contains(targetElement)) {
|
||||||
// try selectorAll
|
// try selectorAll
|
||||||
propElement = Array.from(rootElement.querySelectorAll(selector)).find(item => item.contains(targetElement)) as HTMLElement;
|
propElement = Array.from(rootElement.querySelectorAll(selector)).find((item) =>
|
||||||
|
item.contains(targetElement),
|
||||||
|
) as HTMLElement;
|
||||||
if (!propElement) {
|
if (!propElement) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,9 @@ import { Overlay } from '@alifd/next';
|
||||||
import React, { MouseEvent } from 'react';
|
import React, { MouseEvent } from 'react';
|
||||||
import { Title, observer } from '@alilc/lowcode-editor-core';
|
import { Title, observer } from '@alilc/lowcode-editor-core';
|
||||||
import { canClickNode } from '@alilc/lowcode-utils';
|
import { canClickNode } from '@alilc/lowcode-utils';
|
||||||
|
import { INode } from '../../document';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
import { INode } from '@alilc/lowcode-designer';
|
|
||||||
|
|
||||||
const { Popup } = Overlay;
|
const { Popup } = Overlay;
|
||||||
|
|
||||||
export interface IProps {
|
export interface IProps {
|
||||||
|
@ -80,17 +79,21 @@ export default class InstanceNodeSelector extends React.Component<IProps, IState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onMouseOver = (node: INode) => (_: any, flag = true) => {
|
onMouseOver =
|
||||||
if (node && typeof node.hover === 'function') {
|
(node: INode) =>
|
||||||
node.hover(flag);
|
(_: any, flag = true) => {
|
||||||
}
|
if (node && typeof node.hover === 'function') {
|
||||||
};
|
node.hover(flag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
onMouseOut = (node: INode) => (_: any, flag = false) => {
|
onMouseOut =
|
||||||
if (node && typeof node.hover === 'function') {
|
(node: INode) =>
|
||||||
node.hover(flag);
|
(_: any, flag = false) => {
|
||||||
}
|
if (node && typeof node.hover === 'function') {
|
||||||
};
|
node.hover(flag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
renderNodes = () => {
|
renderNodes = () => {
|
||||||
const nodes = this.state.parentNodes;
|
const nodes = this.state.parentNodes;
|
||||||
|
|
|
@ -10,12 +10,12 @@ export const getClosestClickableNode = (
|
||||||
currentNode: INode | undefined | null,
|
currentNode: INode | undefined | null,
|
||||||
event: MouseEvent,
|
event: MouseEvent,
|
||||||
) => {
|
) => {
|
||||||
let node = currentNode;
|
let node = currentNode as any;
|
||||||
while (node) {
|
while (node) {
|
||||||
// 判断当前节点是否可点击
|
// 判断当前节点是否可点击
|
||||||
let canClick = canClickNode(node, event);
|
let canClick = canClickNode(node, event as any);
|
||||||
// eslint-disable-next-line no-loop-func
|
// eslint-disable-next-line no-loop-func
|
||||||
const lockedNode = getClosestNode(node!, (n) => {
|
const lockedNode: any = getClosestNode(node, (n) => {
|
||||||
// 假如当前节点就是 locked 状态,要从当前节点的父节点开始查找
|
// 假如当前节点就是 locked 状态,要从当前节点的父节点开始查找
|
||||||
return !!(node?.isLocked ? n.parent?.isLocked : n.isLocked);
|
return !!(node?.isLocked ? n.parent?.isLocked : n.isLocked);
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,11 +18,7 @@ import { deprecate, isRegExp, isTitleConfig, isNode } from '@alilc/lowcode-utils
|
||||||
import { computed, createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core';
|
import { computed, createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core';
|
||||||
import { Node, INode } from './document';
|
import { Node, INode } from './document';
|
||||||
import { Designer } from './designer';
|
import { Designer } from './designer';
|
||||||
import {
|
import { IconContainer, IconPage, IconComponent } from './icons';
|
||||||
IconContainer,
|
|
||||||
IconPage,
|
|
||||||
IconComponent,
|
|
||||||
} from './icons';
|
|
||||||
|
|
||||||
export function ensureAList(list?: string | string[]): string[] | null {
|
export function ensureAList(list?: string | string[]): string[] | null {
|
||||||
if (!list) {
|
if (!list) {
|
||||||
|
@ -138,7 +134,7 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
private _isTopFixed?: boolean;
|
private _isTopFixed?: boolean;
|
||||||
|
|
||||||
get isTopFixed(): boolean {
|
get isTopFixed(): boolean {
|
||||||
return !!(this._isTopFixed);
|
return !!this._isTopFixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parentWhitelist?: IPublicTypeNestingFilter | null;
|
private parentWhitelist?: IPublicTypeNestingFilter | null;
|
||||||
|
@ -155,7 +151,7 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
if (isTitleConfig(this._title)) {
|
if (isTitleConfig(this._title)) {
|
||||||
return (this._title?.label as any) || this.componentName;
|
return (this._title?.label as any) || this.componentName;
|
||||||
}
|
}
|
||||||
return this._title || this.componentName;
|
return (this._title as any) || this.componentName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get icon() {
|
@computed get icon() {
|
||||||
|
@ -184,7 +180,10 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
*/
|
*/
|
||||||
prototype?: any;
|
prototype?: any;
|
||||||
|
|
||||||
constructor(readonly designer: Designer, metadata: IPublicTypeComponentMetadata) {
|
constructor(
|
||||||
|
readonly designer: Designer,
|
||||||
|
metadata: IPublicTypeComponentMetadata,
|
||||||
|
) {
|
||||||
this.parseMetadata(metadata);
|
this.parseMetadata(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,8 +286,8 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
}
|
}
|
||||||
|
|
||||||
private transformMetadata(
|
private transformMetadata(
|
||||||
metadta: IPublicTypeComponentMetadata,
|
metadta: IPublicTypeComponentMetadata,
|
||||||
): IPublicTypeTransformedComponentMetadata {
|
): IPublicTypeTransformedComponentMetadata {
|
||||||
const registeredTransducers = this.designer.componentActions.getRegisteredMetadataTransducers();
|
const registeredTransducers = this.designer.componentActions.getRegisteredMetadataTransducers();
|
||||||
const result = registeredTransducers.reduce((prevMetadata, current) => {
|
const result = registeredTransducers.reduce((prevMetadata, current) => {
|
||||||
return current(prevMetadata);
|
return current(prevMetadata);
|
||||||
|
@ -351,7 +350,10 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkNestingDown(my: INode, target: INode | IPublicTypeNodeSchema | IPublicTypeNodeSchema[]): boolean {
|
checkNestingDown(
|
||||||
|
my: INode,
|
||||||
|
target: INode | IPublicTypeNodeSchema | IPublicTypeNodeSchema[],
|
||||||
|
): boolean {
|
||||||
// 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器
|
// 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器
|
||||||
if (this.childWhitelist) {
|
if (this.childWhitelist) {
|
||||||
const _target: any = !Array.isArray(target) ? [target] : target;
|
const _target: any = !Array.isArray(target) ? [target] : target;
|
||||||
|
@ -372,14 +374,15 @@ export class ComponentMeta implements IComponentMeta {
|
||||||
this.emitter.removeListener('metadata_change', fn);
|
this.emitter.removeListener('metadata_change', fn);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isComponentMeta(obj: any): obj is ComponentMeta {
|
export function isComponentMeta(obj: any): obj is ComponentMeta {
|
||||||
return obj && obj.isComponentMeta;
|
return obj && obj.isComponentMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
function preprocessMetadata(metadata: IPublicTypeComponentMetadata): IPublicTypeTransformedComponentMetadata {
|
function preprocessMetadata(
|
||||||
|
metadata: IPublicTypeComponentMetadata,
|
||||||
|
): IPublicTypeTransformedComponentMetadata {
|
||||||
if (metadata.configure) {
|
if (metadata.configure) {
|
||||||
if (Array.isArray(metadata.configure)) {
|
if (Array.isArray(metadata.configure)) {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
import { IPublicTypeContextMenuAction, IPublicEnumContextMenuType, IPublicTypeContextMenuItem, IPublicApiMaterial, IPublicModelPluginContext } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypeContextMenuAction,
|
||||||
|
IPublicEnumContextMenuType,
|
||||||
|
IPublicTypeContextMenuItem,
|
||||||
|
IPublicApiMaterial,
|
||||||
|
IPublicModelPluginContext,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
import { IDesigner, INode } from './designer';
|
import { IDesigner, INode } from './designer';
|
||||||
import { createContextMenu, parseContextMenuAsReactNode, parseContextMenuProperties, uniqueId } from '@alilc/lowcode-utils';
|
import {
|
||||||
|
createContextMenu,
|
||||||
|
parseContextMenuAsReactNode,
|
||||||
|
parseContextMenuProperties,
|
||||||
|
uniqueId,
|
||||||
|
} from '@alilc/lowcode-utils';
|
||||||
import { Menu } from '@alifd/next';
|
import { Menu } from '@alifd/next';
|
||||||
import { engineConfig } from '@alilc/lowcode-editor-core';
|
import { engineConfig } from '@alilc/lowcode-editor-core';
|
||||||
import './context-menu-actions.scss';
|
import './context-menu-actions.scss';
|
||||||
|
@ -22,16 +33,14 @@ export class GlobalContextMenuActions {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.enableContextMenu = enable;
|
this.enableContextMenu = enable;
|
||||||
this.dispose.forEach(d => d());
|
this.dispose.forEach((d) => d());
|
||||||
if (enable) {
|
if (enable) {
|
||||||
this.initEvent();
|
this.initEvent();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenu = (
|
handleContextMenu = (event: MouseEvent) => {
|
||||||
event: MouseEvent,
|
|
||||||
) => {
|
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
@ -46,7 +55,9 @@ export class GlobalContextMenuActions {
|
||||||
const destroy = () => {
|
const destroy = () => {
|
||||||
destroyFn?.();
|
destroyFn?.();
|
||||||
};
|
};
|
||||||
const pluginContext: IPublicModelPluginContext = contextMenu.designer.editor.get('pluginContext') as IPublicModelPluginContext;
|
const pluginContext: IPublicModelPluginContext = contextMenu.designer.editor.get(
|
||||||
|
'pluginContext',
|
||||||
|
) as IPublicModelPluginContext;
|
||||||
|
|
||||||
const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
|
const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
|
||||||
nodes: [],
|
nodes: [],
|
||||||
|
@ -69,7 +80,7 @@ export class GlobalContextMenuActions {
|
||||||
|
|
||||||
const target = event.target;
|
const target = event.target;
|
||||||
|
|
||||||
const { top, left } = target?.getBoundingClientRect();
|
const { top, left } = (target as any)?.getBoundingClientRect();
|
||||||
|
|
||||||
const menuInstance = Menu.create({
|
const menuInstance = Menu.create({
|
||||||
target: event.target,
|
target: event.target,
|
||||||
|
@ -113,7 +124,7 @@ export class ContextMenuActions {
|
||||||
|
|
||||||
enableContextMenu: boolean;
|
enableContextMenu: boolean;
|
||||||
|
|
||||||
id: string = uniqueId('contextMenu');;
|
id: string = uniqueId('contextMenu');
|
||||||
|
|
||||||
constructor(designer: IDesigner) {
|
constructor(designer: IDesigner) {
|
||||||
this.designer = designer;
|
this.designer = designer;
|
||||||
|
@ -124,7 +135,7 @@ export class ContextMenuActions {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.enableContextMenu = enable;
|
this.enableContextMenu = enable;
|
||||||
this.dispose.forEach(d => d());
|
this.dispose.forEach((d) => d());
|
||||||
if (enable) {
|
if (enable) {
|
||||||
this.initEvent();
|
this.initEvent();
|
||||||
}
|
}
|
||||||
|
@ -133,10 +144,7 @@ export class ContextMenuActions {
|
||||||
globalContextMenuActions.registerContextMenuActions(this);
|
globalContextMenuActions.registerContextMenuActions(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenu = (
|
handleContextMenu = (nodes: INode[], event: MouseEvent) => {
|
||||||
nodes: INode[],
|
|
||||||
event: MouseEvent,
|
|
||||||
) => {
|
|
||||||
const designer = this.designer;
|
const designer = this.designer;
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -152,10 +160,12 @@ export class ContextMenuActions {
|
||||||
destroyFn?.();
|
destroyFn?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
const pluginContext: IPublicModelPluginContext = this.designer.editor.get('pluginContext') as IPublicModelPluginContext;
|
const pluginContext: IPublicModelPluginContext = this.designer.editor.get(
|
||||||
|
'pluginContext',
|
||||||
|
) as IPublicModelPluginContext;
|
||||||
|
|
||||||
const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
|
const menus: IPublicTypeContextMenuItem[] = parseContextMenuProperties(actions, {
|
||||||
nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!),
|
nodes: nodes.map((d) => designer.shellModelFactory.createNode(d)!),
|
||||||
destroy,
|
destroy,
|
||||||
event,
|
event,
|
||||||
pluginContext,
|
pluginContext,
|
||||||
|
@ -169,7 +179,7 @@ export class ContextMenuActions {
|
||||||
|
|
||||||
const menuNode = parseContextMenuAsReactNode(layoutMenu, {
|
const menuNode = parseContextMenuAsReactNode(layoutMenu, {
|
||||||
destroy,
|
destroy,
|
||||||
nodes: nodes.map(d => designer.shellModelFactory.createNode(d)!),
|
nodes: nodes.map((d) => designer.shellModelFactory.createNode(d)!),
|
||||||
pluginContext,
|
pluginContext,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -182,26 +192,25 @@ export class ContextMenuActions {
|
||||||
initEvent() {
|
initEvent() {
|
||||||
const designer = this.designer;
|
const designer = this.designer;
|
||||||
this.dispose.push(
|
this.dispose.push(
|
||||||
designer.editor.eventBus.on('designer.builtinSimulator.contextmenu', ({
|
designer.editor.eventBus.on(
|
||||||
node,
|
'designer.builtinSimulator.contextmenu',
|
||||||
originalEvent,
|
({ node, originalEvent }: { node: INode; originalEvent: MouseEvent }) => {
|
||||||
}: {
|
originalEvent.stopPropagation();
|
||||||
node: INode;
|
originalEvent.preventDefault();
|
||||||
originalEvent: MouseEvent;
|
// 如果右键的节点不在 当前选中的节点中,选中该节点
|
||||||
}) => {
|
if (!designer.currentSelection?.has(node.id)) {
|
||||||
originalEvent.stopPropagation();
|
designer.currentSelection?.select(node.id);
|
||||||
originalEvent.preventDefault();
|
}
|
||||||
// 如果右键的节点不在 当前选中的节点中,选中该节点
|
const nodes = designer.currentSelection?.getNodes() ?? [];
|
||||||
if (!designer.currentSelection?.has(node.id)) {
|
this.handleContextMenu(nodes, originalEvent);
|
||||||
designer.currentSelection?.select(node.id);
|
},
|
||||||
}
|
),
|
||||||
const nodes = designer.currentSelection?.getNodes();
|
|
||||||
this.handleContextMenu(nodes, originalEvent);
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
addMenuAction: IPublicApiMaterial['addContextMenuOption'] = (action: IPublicTypeContextMenuAction) => {
|
addMenuAction: IPublicApiMaterial['addContextMenuOption'] = (
|
||||||
|
action: IPublicTypeContextMenuAction,
|
||||||
|
) => {
|
||||||
this.actions.push({
|
this.actions.push({
|
||||||
type: IPublicEnumContextMenuType.MENU_ITEM,
|
type: IPublicEnumContextMenuType.MENU_ITEM,
|
||||||
...action,
|
...action,
|
||||||
|
@ -215,9 +224,11 @@ export class ContextMenuActions {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout'] = (fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]) => {
|
adjustMenuLayout: IPublicApiMaterial['adjustContextMenuLayout'] = (
|
||||||
|
fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[],
|
||||||
|
) => {
|
||||||
adjustMenuLayoutFn = fn;
|
adjustMenuLayoutFn = fn;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IContextMenuActions extends ContextMenuActions {}
|
export interface IContextMenuActions extends ContextMenuActions {}
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
import { INode } from '../document/node/node';
|
import { INode } from '../document/node/node';
|
||||||
import { obx, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import { obx, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||||
import {
|
import { IPublicTypeActiveTarget, IPublicModelActiveTracker } from '@alilc/lowcode-types';
|
||||||
IPublicTypeActiveTarget,
|
|
||||||
IPublicModelActiveTracker,
|
|
||||||
} from '@alilc/lowcode-types';
|
|
||||||
import { isNode } from '@alilc/lowcode-utils';
|
import { isNode } from '@alilc/lowcode-utils';
|
||||||
|
|
||||||
export interface IActiveTracker extends Omit< IPublicModelActiveTracker, 'track' | 'onChange' > {
|
export interface IActiveTracker extends Omit<IPublicModelActiveTracker, 'track' | 'onChange'> {
|
||||||
_target: ActiveTarget | INode;
|
_target?: ActiveTarget | INode;
|
||||||
|
|
||||||
track(originalTarget: ActiveTarget | INode): void;
|
track(originalTarget: ActiveTarget | INode): void;
|
||||||
|
|
||||||
onChange(fn: (target: ActiveTarget) => void): () => void;
|
onChange(fn: (target: ActiveTarget) => void): () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ActiveTarget extends Omit< IPublicTypeActiveTarget, 'node' > {
|
export interface ActiveTarget extends Omit<IPublicTypeActiveTarget, 'node'> {
|
||||||
node: INode;
|
node: INode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
export class ActiveTracker implements IActiveTracker {
|
export class ActiveTracker implements IActiveTracker {
|
||||||
@obx.ref private _target?: ActiveTarget | INode;
|
@obx.ref private _target?: ActiveTarget | INode;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,11 @@ import { Designer } from '../designer';
|
||||||
import { isDragNodeObject } from '../dragon';
|
import { isDragNodeObject } from '../dragon';
|
||||||
import { isSimulatorHost } from '../../simulator';
|
import { isSimulatorHost } from '../../simulator';
|
||||||
import './ghost.less';
|
import './ghost.less';
|
||||||
import { IPublicTypeI18nData, IPublicTypeNodeSchema, IPublicModelDragObject } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypeI18nData,
|
||||||
|
IPublicTypeNodeSchema,
|
||||||
|
IPublicModelDragObject,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
|
|
||||||
type offBinding = () => any;
|
type offBinding = () => any;
|
||||||
|
|
||||||
|
@ -26,15 +30,15 @@ export default class DragGhost extends Component<{ designer: Designer }> {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
this.dispose = [
|
this.dispose = [
|
||||||
this.dragon.onDragstart(e => {
|
this.dragon.onDragstart((e) => {
|
||||||
if (e.originalEvent.type.slice(0, 4) === 'drag') {
|
if (e.originalEvent.type.slice(0, 4) === 'drag') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.titles = this.getTitles(e.dragObject);
|
this.titles = this.getTitles(e.dragObject!) as any;
|
||||||
this.x = e.globalX;
|
this.x = e.globalX;
|
||||||
this.y = e.globalY;
|
this.y = e.globalY;
|
||||||
}),
|
}),
|
||||||
this.dragon.onDrag(e => {
|
this.dragon.onDrag((e) => {
|
||||||
this.x = e.globalX;
|
this.x = e.globalX;
|
||||||
this.y = e.globalY;
|
this.y = e.globalY;
|
||||||
if (isSimulatorHost(e.sensor)) {
|
if (isSimulatorHost(e.sensor)) {
|
||||||
|
@ -56,17 +60,20 @@ export default class DragGhost extends Component<{ designer: Designer }> {
|
||||||
|
|
||||||
getTitles(dragObject: IPublicModelDragObject) {
|
getTitles(dragObject: IPublicModelDragObject) {
|
||||||
if (isDragNodeObject(dragObject)) {
|
if (isDragNodeObject(dragObject)) {
|
||||||
return dragObject.nodes.map((node) => node.title);
|
return dragObject.nodes.map((node) => node?.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dataList = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
const dataList = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data!];
|
||||||
|
|
||||||
return dataList.map((item: IPublicTypeNodeSchema, i) => (this.props.designer.getComponentMeta(item.componentName).title));
|
return dataList.map(
|
||||||
|
(item: IPublicTypeNodeSchema) =>
|
||||||
|
this.props.designer.getComponentMeta(item.componentName).title,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
if (this.dispose) {
|
if (this.dispose) {
|
||||||
this.dispose.forEach(off => off());
|
this.dispose.forEach((off) => off());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,11 @@ export function isDragNodeDataObject(obj: any): obj is IPublicTypeDragNodeDataOb
|
||||||
* @deprecated use same function in @alilc/lowcode-utils
|
* @deprecated use same function in @alilc/lowcode-utils
|
||||||
*/
|
*/
|
||||||
export function isDragAnyObject(obj: any): obj is IPublicTypeDragAnyObject {
|
export function isDragAnyObject(obj: any): obj is IPublicTypeDragAnyObject {
|
||||||
return obj && obj.type !== IPublicEnumDragObjectType.NodeData && obj.type !== IPublicEnumDragObjectType.Node;
|
return (
|
||||||
|
obj &&
|
||||||
|
obj.type !== IPublicEnumDragObjectType.NodeData &&
|
||||||
|
obj.type !== IPublicEnumDragObjectType.Node
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isLocateEvent(e: any): e is ILocateEvent {
|
export function isLocateEvent(e: any): e is ILocateEvent {
|
||||||
|
@ -88,7 +92,7 @@ function getSourceSensor(dragObject: IPublicModelDragObject): ISimulatorHost | n
|
||||||
if (!isDragNodeObject(dragObject)) {
|
if (!isDragNodeObject(dragObject)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return dragObject.nodes[0]?.document?.simulator || null;
|
return (dragObject.nodes[0]?.document as any)?.simulator || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDragEvent(e: any): e is DragEvent {
|
function isDragEvent(e: any): e is DragEvent {
|
||||||
|
@ -98,10 +102,7 @@ function isDragEvent(e: any): e is DragEvent {
|
||||||
/**
|
/**
|
||||||
* Drag-on 拖拽引擎
|
* Drag-on 拖拽引擎
|
||||||
*/
|
*/
|
||||||
export class Dragon implements IPublicModelDragon<
|
export class Dragon implements IPublicModelDragon<INode, ILocateEvent> {
|
||||||
INode,
|
|
||||||
ILocateEvent
|
|
||||||
> {
|
|
||||||
private sensors: IPublicModelSensor[] = [];
|
private sensors: IPublicModelSensor[] = [];
|
||||||
|
|
||||||
private nodeInstPointerEvents: boolean;
|
private nodeInstPointerEvents: boolean;
|
||||||
|
@ -139,6 +140,7 @@ export class Dragon implements IPublicModelDragon<
|
||||||
* @param shell container element
|
* @param shell container element
|
||||||
* @param boost boost got a drag object
|
* @param boost boost got a drag object
|
||||||
*/
|
*/
|
||||||
|
// @ts-ignore
|
||||||
from(shell: Element, boost: (e: MouseEvent) => IPublicModelDragObject | null) {
|
from(shell: Element, boost: (e: MouseEvent) => IPublicModelDragObject | null) {
|
||||||
const mousedown = (e: MouseEvent) => {
|
const mousedown = (e: MouseEvent) => {
|
||||||
// ESC or RightClick
|
// ESC or RightClick
|
||||||
|
@ -166,13 +168,20 @@ export class Dragon implements IPublicModelDragon<
|
||||||
* @param dragObject 拖拽对象
|
* @param dragObject 拖拽对象
|
||||||
* @param boostEvent 拖拽初始时事件
|
* @param boostEvent 拖拽初始时事件
|
||||||
*/
|
*/
|
||||||
boost(dragObject: IPublicModelDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: INode | IPublicModelNode) {
|
boost(
|
||||||
|
dragObject: IPublicModelDragObject,
|
||||||
|
boostEvent: MouseEvent | DragEvent,
|
||||||
|
fromRglNode?: INode | IPublicModelNode,
|
||||||
|
) {
|
||||||
const { designer } = this;
|
const { designer } = this;
|
||||||
const masterSensors = this.getMasterSensors();
|
const masterSensors = this.getMasterSensors();
|
||||||
const handleEvents = makeEventsHandler(boostEvent, masterSensors);
|
const handleEvents = makeEventsHandler(boostEvent, masterSensors);
|
||||||
const newBie = !isDragNodeObject(dragObject);
|
const newBie = !isDragNodeObject(dragObject);
|
||||||
const forceCopyState =
|
const forceCopyState =
|
||||||
isDragNodeObject(dragObject) && dragObject.nodes.some((node: Node | IPublicModelNode) => (typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot));
|
isDragNodeObject(dragObject) &&
|
||||||
|
dragObject.nodes.some((node: Node | IPublicModelNode) =>
|
||||||
|
typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot,
|
||||||
|
);
|
||||||
const isBoostFromDragAPI = isDragEvent(boostEvent);
|
const isBoostFromDragAPI = isDragEvent(boostEvent);
|
||||||
let lastSensor: IPublicModelSensor | undefined;
|
let lastSensor: IPublicModelSensor | undefined;
|
||||||
|
|
||||||
|
@ -238,14 +247,14 @@ export class Dragon implements IPublicModelDragon<
|
||||||
}
|
}
|
||||||
lastArrive = e;
|
lastArrive = e;
|
||||||
|
|
||||||
const { isRGL, rglNode } = getRGL(e);
|
const { isRGL, rglNode } = getRGL(e) as any;
|
||||||
const locateEvent = createLocateEvent(e);
|
const locateEvent = createLocateEvent(e);
|
||||||
const sensor = chooseSensor(locateEvent);
|
const sensor = chooseSensor(locateEvent);
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (isRGL) {
|
if (isRGL) {
|
||||||
// 禁止被拖拽元素的阻断
|
// 禁止被拖拽元素的阻断
|
||||||
const nodeInst = dragObject.nodes[0].getDOMNode();
|
const nodeInst = dragObject?.nodes?.[0]?.getDOMNode();
|
||||||
if (nodeInst && nodeInst.style) {
|
if (nodeInst && nodeInst.style) {
|
||||||
this.nodeInstPointerEvents = true;
|
this.nodeInstPointerEvents = true;
|
||||||
nodeInst.style.pointerEvents = 'none';
|
nodeInst.style.pointerEvents = 'none';
|
||||||
|
@ -263,7 +272,7 @@ export class Dragon implements IPublicModelDragon<
|
||||||
this.emitter.emit('rgl.add.placeholder', {
|
this.emitter.emit('rgl.add.placeholder', {
|
||||||
rglNode,
|
rglNode,
|
||||||
fromRglNode,
|
fromRglNode,
|
||||||
node: locateEvent.dragObject?.nodes[0],
|
node: locateEvent.dragObject?.nodes?.[0],
|
||||||
event: e,
|
event: e,
|
||||||
});
|
});
|
||||||
designer.clearLocation();
|
designer.clearLocation();
|
||||||
|
@ -337,7 +346,7 @@ export class Dragon implements IPublicModelDragon<
|
||||||
const over = (e?: any) => {
|
const over = (e?: any) => {
|
||||||
// 禁止被拖拽元素的阻断
|
// 禁止被拖拽元素的阻断
|
||||||
if (this.nodeInstPointerEvents) {
|
if (this.nodeInstPointerEvents) {
|
||||||
const nodeInst = dragObject.nodes[0].getDOMNode();
|
const nodeInst = dragObject?.nodes?.[0]?.getDOMNode();
|
||||||
if (nodeInst && nodeInst.style) {
|
if (nodeInst && nodeInst.style) {
|
||||||
nodeInst.style.pointerEvents = '';
|
nodeInst.style.pointerEvents = '';
|
||||||
}
|
}
|
||||||
|
@ -346,18 +355,18 @@ export class Dragon implements IPublicModelDragon<
|
||||||
|
|
||||||
// 发送drop事件
|
// 发送drop事件
|
||||||
if (e) {
|
if (e) {
|
||||||
const { isRGL, rglNode } = getRGL(e);
|
const { isRGL, rglNode } = getRGL(e) as any;
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (isRGL && this._canDrop && this._dragging) {
|
if (isRGL && this._canDrop && this._dragging) {
|
||||||
const tarNode = dragObject.nodes[0];
|
const tarNode = dragObject?.nodes?.[0];
|
||||||
if (rglNode.id !== tarNode.id) {
|
if (rglNode.id !== tarNode?.id) {
|
||||||
// 避免死循环
|
// 避免死循环
|
||||||
this.emitter.emit('rgl.drop', {
|
this.emitter.emit('rgl.drop', {
|
||||||
rglNode,
|
rglNode,
|
||||||
node: tarNode,
|
node: tarNode,
|
||||||
});
|
});
|
||||||
const selection = designer.project.currentDocument?.selection;
|
const selection = designer.project.currentDocument?.selection;
|
||||||
selection?.select(tarNode.id);
|
selection?.select(tarNode!.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,7 +438,7 @@ export class Dragon implements IPublicModelDragon<
|
||||||
if (!sourceDocument || sourceDocument === document) {
|
if (!sourceDocument || sourceDocument === document) {
|
||||||
evt.globalX = e.clientX;
|
evt.globalX = e.clientX;
|
||||||
evt.globalY = e.clientY;
|
evt.globalY = e.clientY;
|
||||||
} else /* istanbul ignore next */ {
|
} /* istanbul ignore next */ else {
|
||||||
// event from simulator sandbox
|
// event from simulator sandbox
|
||||||
let srcSim: ISimulatorHost | undefined;
|
let srcSim: ISimulatorHost | undefined;
|
||||||
const lastSim = lastSensor && isSimulatorHost(lastSensor) ? lastSensor : null;
|
const lastSim = lastSensor && isSimulatorHost(lastSensor) ? lastSensor : null;
|
||||||
|
@ -463,7 +472,9 @@ export class Dragon implements IPublicModelDragon<
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
const chooseSensor = (e: ILocateEvent) => {
|
const chooseSensor = (e: ILocateEvent) => {
|
||||||
// this.sensors will change on dragstart
|
// this.sensors will change on dragstart
|
||||||
const sensors: IPublicModelSensor[] = this.sensors.concat(masterSensors as IPublicModelSensor[]);
|
const sensors: IPublicModelSensor[] = this.sensors.concat(
|
||||||
|
masterSensors as IPublicModelSensor[],
|
||||||
|
);
|
||||||
let sensor =
|
let sensor =
|
||||||
e.sensor && e.sensor.isEnter(e)
|
e.sensor && e.sensor.isEnter(e)
|
||||||
? e.sensor
|
? e.sensor
|
||||||
|
@ -475,7 +486,7 @@ export class Dragon implements IPublicModelDragon<
|
||||||
} else if (e.sensor) {
|
} else if (e.sensor) {
|
||||||
sensor = e.sensor;
|
sensor = e.sensor;
|
||||||
} else if (sourceSensor) {
|
} else if (sourceSensor) {
|
||||||
sensor = sourceSensor;
|
sensor = sourceSensor as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sensor !== lastSensor) {
|
if (sensor !== lastSensor) {
|
||||||
|
@ -634,4 +645,4 @@ export class Dragon implements IPublicModelDragon<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDragon extends Dragon { }
|
export interface IDragon extends Dragon {}
|
||||||
|
|
|
@ -60,7 +60,10 @@ export function isChildInline(child: Element | Text, win?: Window) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const style = (win || getWindow(child)).getComputedStyle(child);
|
const style = (win || getWindow(child)).getComputedStyle(child);
|
||||||
return /^inline/.test(style.getPropertyValue('display')) || /^(left|right)$/.test(style.getPropertyValue('float'));
|
return (
|
||||||
|
/^inline/.test(style.getPropertyValue('display')) ||
|
||||||
|
/^(left|right)$/.test(style.getPropertyValue('float'))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRectTarget(rect: IPublicTypeRect | null) {
|
export function getRectTarget(rect: IPublicTypeRect | null) {
|
||||||
|
@ -99,7 +102,6 @@ export function getWindow(elem: Element | Document): Window {
|
||||||
return (isDocument(elem) ? elem : elem.ownerDocument!).defaultView!;
|
return (isDocument(elem) ? elem : elem.ownerDocument!).defaultView!;
|
||||||
}
|
}
|
||||||
export interface IDropLocation extends Omit<IPublicModelDropLocation, 'target' | 'clone'> {
|
export interface IDropLocation extends Omit<IPublicModelDropLocation, 'target' | 'clone'> {
|
||||||
|
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
|
|
||||||
get target(): INode;
|
get target(): INode;
|
||||||
|
@ -126,7 +128,7 @@ export class DropLocation implements IDropLocation {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.detail = detail;
|
this.detail = detail;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.event = event;
|
this.event = event as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(event: ILocateEvent): IDropLocation {
|
clone(event: ILocateEvent): IDropLocation {
|
||||||
|
|
|
@ -75,14 +75,14 @@ export class OffsetObserver {
|
||||||
|
|
||||||
@computed get offsetHeight() {
|
@computed get offsetHeight() {
|
||||||
if (!this.viewport?.scrolling || this.lastOffsetHeight == null) {
|
if (!this.viewport?.scrolling || this.lastOffsetHeight == null) {
|
||||||
this.lastOffsetHeight = this.isRoot ? (this.viewport?.height || 0) : this.height;
|
this.lastOffsetHeight = this.isRoot ? this.viewport?.height || 0 : this.height;
|
||||||
}
|
}
|
||||||
return this.lastOffsetHeight;
|
return this.lastOffsetHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get offsetWidth() {
|
@computed get offsetWidth() {
|
||||||
if (!(this.viewport?.scrolling || 0) || this.lastOffsetWidth == null) {
|
if (!(this.viewport?.scrolling || 0) || this.lastOffsetWidth == null) {
|
||||||
this.lastOffsetWidth = this.isRoot ? (this.viewport?.width || 0) : this.width;
|
this.lastOffsetWidth = this.isRoot ? this.viewport?.width || 0 : this.width;
|
||||||
}
|
}
|
||||||
return this.lastOffsetWidth;
|
return this.lastOffsetWidth;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,17 +10,19 @@ import {
|
||||||
IPublicModelSettingField,
|
IPublicModelSettingField,
|
||||||
IBaseModelSettingField,
|
IBaseModelSettingField,
|
||||||
} from '@alilc/lowcode-types';
|
} from '@alilc/lowcode-types';
|
||||||
import type {
|
import type { IPublicTypeSetValueOptions } from '@alilc/lowcode-types';
|
||||||
IPublicTypeSetValueOptions,
|
|
||||||
} from '@alilc/lowcode-types';
|
|
||||||
import { Transducer } from './utils';
|
import { Transducer } from './utils';
|
||||||
import { ISettingPropEntry, SettingPropEntry } from './setting-prop-entry';
|
import { ISettingPropEntry, SettingPropEntry } from './setting-prop-entry';
|
||||||
import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core';
|
import { computed, obx, makeObservable, action, untracked, intl } from '@alilc/lowcode-editor-core';
|
||||||
import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils';
|
import { cloneDeep, isCustomView, isDynamicSetter, isJSExpression } from '@alilc/lowcode-utils';
|
||||||
import { ISettingTopEntry } from './setting-top-entry';
|
import { ISettingTopEntry } from './setting-top-entry';
|
||||||
import { IComponentMeta, INode } from '@alilc/lowcode-designer';
|
import { IComponentMeta } from '../../component-meta';
|
||||||
|
import { INode } from '../../document';
|
||||||
|
|
||||||
function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, config: IPublicTypeFieldConfig) {
|
function getSettingFieldCollectorKey(
|
||||||
|
parent: ISettingTopEntry | ISettingField,
|
||||||
|
config: IPublicTypeFieldConfig,
|
||||||
|
) {
|
||||||
let cur = parent;
|
let cur = parent;
|
||||||
const path = [config.name];
|
const path = [config.name];
|
||||||
while (cur !== parent.top) {
|
while (cur !== parent.top) {
|
||||||
|
@ -32,12 +34,13 @@ function getSettingFieldCollectorKey(parent: ISettingTopEntry | ISettingField, c
|
||||||
return path.join('.');
|
return path.join('.');
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISettingField extends ISettingPropEntry, Omit<IBaseModelSettingField<
|
// @ts-ignore
|
||||||
ISettingTopEntry,
|
export interface ISettingField
|
||||||
ISettingField,
|
extends ISettingPropEntry,
|
||||||
IComponentMeta,
|
Omit<
|
||||||
INode
|
IBaseModelSettingField<ISettingTopEntry, ISettingField, IComponentMeta, INode>,
|
||||||
>, 'setValue' | 'key' | 'node'> {
|
'setValue' | 'key' | 'node'
|
||||||
|
> {
|
||||||
readonly isSettingField: true;
|
readonly isSettingField: true;
|
||||||
|
|
||||||
readonly isRequired: boolean;
|
readonly isRequired: boolean;
|
||||||
|
@ -96,7 +99,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
|
||||||
// ==== dynamic properties ====
|
// ==== dynamic properties ====
|
||||||
private _title?: IPublicTypeTitleContent;
|
private _title?: IPublicTypeTitleContent;
|
||||||
|
|
||||||
get title() {
|
get title(): any {
|
||||||
return (
|
return (
|
||||||
this._title || (typeof this.name === 'number' ? `${intl('Item')} ${this.name}` : this.name)
|
this._title || (typeof this.name === 'number' ? `${intl('Item')} ${this.name}` : this.name)
|
||||||
);
|
);
|
||||||
|
@ -132,11 +135,11 @@ export class SettingField extends SettingPropEntry implements ISettingField {
|
||||||
this.initItems(items, settingFieldCollector);
|
this.initItems(items, settingFieldCollector);
|
||||||
}
|
}
|
||||||
if (this.type !== 'group' && settingFieldCollector && config.name) {
|
if (this.type !== 'group' && settingFieldCollector && config.name) {
|
||||||
settingFieldCollector(getSettingFieldCollectorKey(parent, config), this);
|
settingFieldCollector(getSettingFieldCollectorKey(parent, config), this as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
// compatiable old config
|
// compatiable old config
|
||||||
this.transducer = new Transducer(this, { setter });
|
this.transducer = new Transducer(this as any, { setter });
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed get setter(): IPublicTypeSetterType | null {
|
@computed get setter(): IPublicTypeSetterType | null {
|
||||||
|
@ -179,8 +182,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
|
||||||
if (isCustomView(item)) {
|
if (isCustomView(item)) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return new SettingField(this, item, settingFieldCollector);
|
return new SettingField(this as any, item, settingFieldCollector);
|
||||||
});
|
}) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
private disposeItems() {
|
private disposeItems() {
|
||||||
|
@ -190,8 +193,8 @@ export class SettingField extends SettingPropEntry implements ISettingField {
|
||||||
|
|
||||||
// 创建子配置项,通常用于 object/array 类型数据
|
// 创建子配置项,通常用于 object/array 类型数据
|
||||||
createField(config: IPublicTypeFieldConfig): ISettingField {
|
createField(config: IPublicTypeFieldConfig): ISettingField {
|
||||||
this.settingFieldCollector?.(getSettingFieldCollectorKey(this.parent, config), this);
|
this.settingFieldCollector?.(getSettingFieldCollectorKey(this.parent, config), this as any);
|
||||||
return new SettingField(this, config, this.settingFieldCollector);
|
return new SettingField(this as any, config, this.settingFieldCollector) as ISettingField;
|
||||||
}
|
}
|
||||||
|
|
||||||
purge() {
|
purge() {
|
||||||
|
@ -307,7 +310,7 @@ export class SettingField extends SettingPropEntry implements ISettingField {
|
||||||
}
|
}
|
||||||
|
|
||||||
onEffect(action: () => void): IPublicTypeDisposable {
|
onEffect(action: () => void): IPublicTypeDisposable {
|
||||||
return this.designer!.autorun(action, true);
|
return this.designer!.autorun(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
internalToShellField() {
|
internalToShellField() {
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
import { obx, computed, makeObservable, runInAction, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import {
|
||||||
import { GlobalEvent, IPublicApiSetters, IPublicModelEditor, IPublicModelSettingField, IPublicTypeFieldExtraProps, IPublicTypeSetValueOptions } from '@alilc/lowcode-types';
|
obx,
|
||||||
|
computed,
|
||||||
|
makeObservable,
|
||||||
|
runInAction,
|
||||||
|
IEventBus,
|
||||||
|
createModuleEventBus,
|
||||||
|
} from '@alilc/lowcode-editor-core';
|
||||||
|
import {
|
||||||
|
GlobalEvent,
|
||||||
|
IPublicApiSetters,
|
||||||
|
IPublicModelEditor,
|
||||||
|
IPublicModelSettingField,
|
||||||
|
IPublicTypeFieldExtraProps,
|
||||||
|
IPublicTypeSetValueOptions,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
import { uniqueId, isJSExpression } from '@alilc/lowcode-utils';
|
import { uniqueId, isJSExpression } from '@alilc/lowcode-utils';
|
||||||
import { ISettingEntry } from './setting-entry-type';
|
import { ISettingEntry } from './setting-entry-type';
|
||||||
import { INode } from '../../document';
|
import { INode } from '../../document';
|
||||||
|
@ -33,7 +47,12 @@ export interface ISettingPropEntry extends ISettingEntry {
|
||||||
|
|
||||||
remove(): void;
|
remove(): void;
|
||||||
|
|
||||||
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: IPublicTypeSetValueOptions): void;
|
setValue(
|
||||||
|
val: any,
|
||||||
|
isHotValue?: boolean,
|
||||||
|
force?: boolean,
|
||||||
|
extraOptions?: IPublicTypeSetValueOptions,
|
||||||
|
): void;
|
||||||
|
|
||||||
internalToShellField(): IPublicModelSettingField;
|
internalToShellField(): IPublicModelSettingField;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +102,11 @@ export class SettingPropEntry implements ISettingPropEntry {
|
||||||
|
|
||||||
extraProps: IPublicTypeFieldExtraProps = {};
|
extraProps: IPublicTypeFieldExtraProps = {};
|
||||||
|
|
||||||
constructor(readonly parent: ISettingTopEntry | ISettingField, name: string | number | undefined, type?: 'field' | 'group') {
|
constructor(
|
||||||
|
readonly parent: ISettingTopEntry | ISettingField,
|
||||||
|
name: string | number | undefined,
|
||||||
|
type?: 'field' | 'group',
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
const c = typeof name === 'string' ? name.slice(0, 1) : '';
|
const c = typeof name === 'string' ? name.slice(0, 1) : '';
|
||||||
|
@ -206,7 +229,12 @@ export class SettingPropEntry implements ISettingPropEntry {
|
||||||
/**
|
/**
|
||||||
* 设置当前属性值
|
* 设置当前属性值
|
||||||
*/
|
*/
|
||||||
setValue(val: any, isHotValue?: boolean, force?: boolean, extraOptions?: IPublicTypeSetValueOptions) {
|
setValue(
|
||||||
|
val: any,
|
||||||
|
isHotValue?: boolean,
|
||||||
|
force?: boolean,
|
||||||
|
extraOptions?: IPublicTypeSetValueOptions,
|
||||||
|
) {
|
||||||
const oldValue = this.getValue();
|
const oldValue = this.getValue();
|
||||||
if (this.type === 'field') {
|
if (this.type === 'field') {
|
||||||
this.name?.toString() && this.parent.setPropValue(this.name, val);
|
this.name?.toString() && this.parent.setPropValue(this.name, val);
|
||||||
|
@ -329,7 +357,7 @@ export class SettingPropEntry implements ISettingPropEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyValueChange(oldValue: any, newValue: any) {
|
notifyValueChange(oldValue: any, newValue: any) {
|
||||||
this.editor.eventBus.emit(GlobalEvent.Node.Prop.Change, {
|
this.editor.eventBus.emit(GlobalEvent.Node.Prop.InnerChange, {
|
||||||
node: this.getNode(),
|
node: this.getNode(),
|
||||||
prop: this,
|
prop: this,
|
||||||
oldValue,
|
oldValue,
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
import { IPublicTypeCustomView, IPublicModelEditor, IPublicModelSettingTopEntry, IPublicApiSetters } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypeCustomView,
|
||||||
|
IPublicModelEditor,
|
||||||
|
IPublicModelSettingTopEntry,
|
||||||
|
IPublicApiSetters,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
import { isCustomView } from '@alilc/lowcode-utils';
|
import { isCustomView } from '@alilc/lowcode-utils';
|
||||||
import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import { computed, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
||||||
import { ISettingEntry } from './setting-entry-type';
|
import { ISettingEntry } from './setting-entry-type';
|
||||||
|
@ -14,10 +19,9 @@ function generateSessionId(nodes: INode[]) {
|
||||||
.join(',');
|
.join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISettingTopEntry extends ISettingEntry, IPublicModelSettingTopEntry<
|
export interface ISettingTopEntry
|
||||||
INode,
|
extends ISettingEntry,
|
||||||
ISettingField
|
IPublicModelSettingTopEntry<INode, ISettingField> {
|
||||||
> {
|
|
||||||
readonly top: ISettingTopEntry;
|
readonly top: ISettingTopEntry;
|
||||||
|
|
||||||
readonly parent: ISettingTopEntry;
|
readonly parent: ISettingTopEntry;
|
||||||
|
@ -48,16 +52,16 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
|
|
||||||
readonly path = [];
|
readonly path = [];
|
||||||
|
|
||||||
readonly top = this;
|
readonly top = this as ISettingTopEntry;
|
||||||
|
|
||||||
readonly parent = this;
|
readonly parent = this as ISettingTopEntry;
|
||||||
|
|
||||||
get componentMeta() {
|
get componentMeta() {
|
||||||
return this._componentMeta;
|
return this._componentMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
get items() {
|
get items() {
|
||||||
return this._items;
|
return this._items as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,7 +99,10 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
|
|
||||||
disposeFunctions: any[] = [];
|
disposeFunctions: any[] = [];
|
||||||
|
|
||||||
constructor(readonly editor: IPublicModelEditor, readonly nodes: INode[]) {
|
constructor(
|
||||||
|
readonly editor: IPublicModelEditor,
|
||||||
|
readonly nodes: INode[],
|
||||||
|
) {
|
||||||
if (!Array.isArray(nodes) || nodes.length < 1) {
|
if (!Array.isArray(nodes) || nodes.length < 1) {
|
||||||
throw new ReferenceError('nodes should not be empty');
|
throw new ReferenceError('nodes should not be empty');
|
||||||
}
|
}
|
||||||
|
@ -145,7 +152,7 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
if (isCustomView(item)) {
|
if (isCustomView(item)) {
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
return new SettingField(this, item as any, settingFieldCollector);
|
return new SettingField(this as ISettingTopEntry, item as any, settingFieldCollector);
|
||||||
});
|
});
|
||||||
this._settingFieldMap = settingFieldMap;
|
this._settingFieldMap = settingFieldMap;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +184,10 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
*/
|
*/
|
||||||
get(propName: string | number): ISettingField | null {
|
get(propName: string | number): ISettingField | null {
|
||||||
if (!propName) return null;
|
if (!propName) return null;
|
||||||
return this._settingFieldMap[propName] || (new SettingField(this, { name: propName }));
|
return (
|
||||||
|
this._settingFieldMap[propName] ||
|
||||||
|
new SettingField(this as ISettingTopEntry, { name: propName })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,7 +254,7 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
this.disposeItems();
|
this.disposeItems();
|
||||||
this._settingFieldMap = {};
|
this._settingFieldMap = {};
|
||||||
this.emitter.removeAllListeners();
|
this.emitter.removeAllListeners();
|
||||||
this.disposeFunctions.forEach(f => f());
|
this.disposeFunctions.forEach((f) => f());
|
||||||
this.disposeFunctions = [];
|
this.disposeFunctions = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,21 +263,15 @@ export class SettingTopEntry implements ISettingTopEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== copy some Node api =====
|
// ==== copy some Node api =====
|
||||||
getStatus() {
|
getStatus() {}
|
||||||
|
|
||||||
}
|
setStatus() {}
|
||||||
|
|
||||||
setStatus() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getChildren() {
|
getChildren() {
|
||||||
// this.nodes.map()
|
// this.nodes.map()
|
||||||
}
|
}
|
||||||
|
|
||||||
getDOMNode() {
|
getDOMNode() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getId() {
|
getId() {
|
||||||
return this.id;
|
return this.id;
|
||||||
|
|
|
@ -4,11 +4,11 @@ import { IPublicTypeFieldConfig, IPublicTypeSetterConfig } from '@alilc/lowcode-
|
||||||
import { isSetterConfig, isDynamicSetter } from '@alilc/lowcode-utils';
|
import { isSetterConfig, isDynamicSetter } from '@alilc/lowcode-utils';
|
||||||
import { ISettingField } from './setting-field';
|
import { ISettingField } from './setting-field';
|
||||||
|
|
||||||
function getHotterFromSetter(setter) {
|
function getHotterFromSetter(setter: any) {
|
||||||
return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line
|
return (setter && (setter.Hotter || (setter.type && setter.type.Hotter))) || []; // eslint-disable-line
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransducerFromSetter(setter) {
|
function getTransducerFromSetter(setter: any) {
|
||||||
return (
|
return (
|
||||||
(setter &&
|
(setter &&
|
||||||
(setter.transducer ||
|
(setter.transducer ||
|
||||||
|
@ -18,15 +18,15 @@ function getTransducerFromSetter(setter) {
|
||||||
); // eslint-disable-line
|
); // eslint-disable-line
|
||||||
}
|
}
|
||||||
|
|
||||||
function combineTransducer(transducer, arr, context) {
|
function combineTransducer(transducer: any, arr: any, context: any) {
|
||||||
if (!transducer && Array.isArray(arr)) {
|
if (!transducer && Array.isArray(arr)) {
|
||||||
const [toHot, toNative] = arr;
|
const [toHot, toNative] = arr;
|
||||||
transducer = { toHot, toNative };
|
transducer = { toHot, toNative };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line
|
toHot: ((transducer && transducer.toHot) || ((x: any) => x)).bind(context), // eslint-disable-line
|
||||||
toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line
|
toNative: ((transducer && transducer.toNative) || ((x: any) => x)).bind(context), // eslint-disable-line
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +43,9 @@ export class Transducer {
|
||||||
// 3. IPublicTypeSetterConfig[]
|
// 3. IPublicTypeSetterConfig[]
|
||||||
if (Array.isArray(setter)) {
|
if (Array.isArray(setter)) {
|
||||||
setter = setter[0];
|
setter = setter[0];
|
||||||
} else if (isValidElement(setter) && setter.type.displayName === 'MixedSetter') {
|
} else if (isValidElement(setter) && (setter.type as any).displayName === 'MixedSetter') {
|
||||||
setter = setter.props?.setters?.[0];
|
setter = (setter.props as any)?.setters?.[0];
|
||||||
} else if (typeof setter === 'object' && setter.componentName === 'MixedSetter') {
|
} else if (typeof setter === 'object' && (setter as any).componentName === 'MixedSetter') {
|
||||||
setter = Array.isArray(setter?.props?.setters) && setter.props.setters[0];
|
setter = Array.isArray(setter?.props?.setters) && setter.props.setters[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,18 +71,24 @@ export class Transducer {
|
||||||
if (isDynamicSetter(setter) && isDynamic) {
|
if (isDynamicSetter(setter) && isDynamic) {
|
||||||
try {
|
try {
|
||||||
setter = setter.call(context.internalToShellField(), context.internalToShellField());
|
setter = setter.call(context.internalToShellField(), context.internalToShellField());
|
||||||
} catch (e) { console.error(e); }
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setterTransducer = combineTransducer(getTransducerFromSetter(setter), getHotterFromSetter(setter), context);
|
this.setterTransducer = combineTransducer(
|
||||||
|
getTransducerFromSetter(setter),
|
||||||
|
getHotterFromSetter(setter),
|
||||||
|
context,
|
||||||
|
);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
toHot(data) {
|
toHot(data: any) {
|
||||||
return this.setterTransducer.toHot(data);
|
return this.setterTransducer.toHot(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
toNative(data) {
|
toNative(data: any) {
|
||||||
return this.setterTransducer.toNative(data);
|
return this.setterTransducer.toNative(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,8 @@ import {
|
||||||
IPublicTypeOnChangeOptions,
|
IPublicTypeOnChangeOptions,
|
||||||
IPublicTypeDisposable,
|
IPublicTypeDisposable,
|
||||||
} from '@alilc/lowcode-types';
|
} from '@alilc/lowcode-types';
|
||||||
import type {
|
import type { IPublicTypeRootSchema } from '@alilc/lowcode-types';
|
||||||
IPublicTypeRootSchema,
|
import type { IDropLocation } from '../designer/location';
|
||||||
} from '@alilc/lowcode-types';
|
|
||||||
import type {
|
|
||||||
IDropLocation,
|
|
||||||
} from '@alilc/lowcode-designer';
|
|
||||||
import {
|
import {
|
||||||
uniqueId,
|
uniqueId,
|
||||||
isPlainObject,
|
isPlainObject,
|
||||||
|
@ -50,36 +46,40 @@ import { EDITOR_EVENT } from '../types';
|
||||||
|
|
||||||
export type GetDataType<T, NodeType> = T extends undefined
|
export type GetDataType<T, NodeType> = T extends undefined
|
||||||
? NodeType extends {
|
? NodeType extends {
|
||||||
schema: infer R;
|
schema: infer R;
|
||||||
}
|
}
|
||||||
? R
|
? R
|
||||||
: any
|
: any
|
||||||
: T;
|
: T;
|
||||||
|
|
||||||
export class DocumentModel implements Omit<IPublicModelDocumentModel<
|
export class DocumentModel
|
||||||
ISelection,
|
implements
|
||||||
IHistory,
|
Omit<
|
||||||
INode,
|
IPublicModelDocumentModel<
|
||||||
IDropLocation,
|
ISelection,
|
||||||
IModalNodesManager,
|
IHistory,
|
||||||
IProject
|
INode,
|
||||||
>,
|
IDropLocation,
|
||||||
'detecting' |
|
IModalNodesManager,
|
||||||
'checkNesting' |
|
IProject
|
||||||
'getNodeById' |
|
>,
|
||||||
// 以下属性在内部的 document 中不存在
|
| 'detecting'
|
||||||
'exportSchema' |
|
| 'checkNesting'
|
||||||
'importSchema' |
|
| 'getNodeById'
|
||||||
'onAddNode' |
|
// 以下属性在内部的 document 中不存在
|
||||||
'onRemoveNode' |
|
| 'exportSchema'
|
||||||
'onChangeDetecting' |
|
| 'importSchema'
|
||||||
'onChangeSelection' |
|
| 'onAddNode'
|
||||||
'onChangeNodeProp' |
|
| 'onRemoveNode'
|
||||||
'onImportSchema' |
|
| 'onChangeDetecting'
|
||||||
'isDetectingNode' |
|
| 'onChangeSelection'
|
||||||
'onFocusNodeChanged' |
|
| 'onChangeNodeProp'
|
||||||
'onDropLocationChanged'
|
| 'onImportSchema'
|
||||||
> {
|
| 'isDetectingNode'
|
||||||
|
| 'onFocusNodeChanged'
|
||||||
|
| 'onDropLocationChanged'
|
||||||
|
>
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* 根节点 类型有:Page/Component/Block
|
* 根节点 类型有:Page/Component/Block
|
||||||
*/
|
*/
|
||||||
|
@ -179,10 +179,10 @@ IProject
|
||||||
set dropLocation(loc: IDropLocation | null) {
|
set dropLocation(loc: IDropLocation | null) {
|
||||||
this._dropLocation = loc;
|
this._dropLocation = loc;
|
||||||
// pub event
|
// pub event
|
||||||
this.designer.editor.eventBus.emit(
|
this.designer.editor.eventBus.emit('document.dropLocation.changed', {
|
||||||
'document.dropLocation.changed',
|
document: this,
|
||||||
{ document: this, location: loc },
|
location: loc,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,7 +282,9 @@ IProject
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeNodeChildren(fn: (info: IPublicTypeOnChangeOptions<INode>) => void): IPublicTypeDisposable {
|
onChangeNodeChildren(
|
||||||
|
fn: (info: IPublicTypeOnChangeOptions<INode>) => void,
|
||||||
|
): IPublicTypeDisposable {
|
||||||
this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_CHILDREN_CHANGE, fn);
|
this.designer.editor?.eventBus.on(EDITOR_EVENT.NODE_CHILDREN_CHANGE, fn);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
|
@ -401,14 +403,24 @@ IProject
|
||||||
/**
|
/**
|
||||||
* 插入一个节点
|
* 插入一个节点
|
||||||
*/
|
*/
|
||||||
insertNode(parent: INode, thing: INode | IPublicTypeNodeData, at?: number | null, copy?: boolean): INode | null {
|
insertNode(
|
||||||
|
parent: INode,
|
||||||
|
thing: INode | IPublicTypeNodeData,
|
||||||
|
at?: number | null,
|
||||||
|
copy?: boolean,
|
||||||
|
): INode | null {
|
||||||
return insertChild(parent, thing, at, copy);
|
return insertChild(parent, thing, at, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 插入多个节点
|
* 插入多个节点
|
||||||
*/
|
*/
|
||||||
insertNodes(parent: INode, thing: INode[] | IPublicTypeNodeData[], at?: number | null, copy?: boolean) {
|
insertNodes(
|
||||||
|
parent: INode,
|
||||||
|
thing: INode[] | IPublicTypeNodeData[],
|
||||||
|
at?: number | null,
|
||||||
|
copy?: boolean,
|
||||||
|
) {
|
||||||
return insertChildren(parent, thing, at, copy);
|
return insertChildren(parent, thing, at, copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +485,7 @@ IProject
|
||||||
const drillDownNodeId = this._drillDownNode?.id;
|
const drillDownNodeId = this._drillDownNode?.id;
|
||||||
runWithGlobalEventOff(() => {
|
runWithGlobalEventOff(() => {
|
||||||
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
// TODO: 暂时用饱和式删除,原因是 Slot 节点并不是树节点,无法正常递归删除
|
||||||
this.nodes.forEach(node => {
|
this.nodes.forEach((node) => {
|
||||||
if (node.isRoot()) return;
|
if (node.isRoot()) return;
|
||||||
this.internalRemoveAndPurgeNode(node, true);
|
this.internalRemoveAndPurgeNode(node, true);
|
||||||
});
|
});
|
||||||
|
@ -486,14 +498,20 @@ IProject
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Serilize): IPublicTypeRootSchema | undefined {
|
export(
|
||||||
|
stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Serilize,
|
||||||
|
): IPublicTypeRootSchema | undefined {
|
||||||
stage = compatStage(stage);
|
stage = compatStage(stage);
|
||||||
// 置顶只作用于 Page 的第一级子节点,目前还用不到里层的置顶;如果后面有需要可以考虑将这段写到 node-children 中的 export
|
// 置顶只作用于 Page 的第一级子节点,目前还用不到里层的置顶;如果后面有需要可以考虑将这段写到 node-children 中的 export
|
||||||
const currentSchema = this.rootNode?.export<IPublicTypeRootSchema>(stage);
|
const currentSchema = this.rootNode?.export<IPublicTypeRootSchema>(stage);
|
||||||
if (Array.isArray(currentSchema?.children) && currentSchema?.children?.length && currentSchema?.children?.length > 0) {
|
if (
|
||||||
|
Array.isArray(currentSchema?.children) &&
|
||||||
|
currentSchema?.children?.length &&
|
||||||
|
currentSchema?.children?.length > 0
|
||||||
|
) {
|
||||||
const FixedTopNodeIndex = currentSchema?.children
|
const FixedTopNodeIndex = currentSchema?.children
|
||||||
.filter(i => isPlainObject(i))
|
.filter((i) => isPlainObject(i))
|
||||||
.findIndex((i => (i as IPublicTypeNodeSchema).props?.__isTopFixed__));
|
.findIndex((i) => (i as IPublicTypeNodeSchema).props?.__isTopFixed__);
|
||||||
if (FixedTopNodeIndex > 0) {
|
if (FixedTopNodeIndex > 0) {
|
||||||
const FixedTopNode = currentSchema?.children.splice(FixedTopNodeIndex, 1);
|
const FixedTopNode = currentSchema?.children.splice(FixedTopNodeIndex, 1);
|
||||||
currentSchema?.children.unshift(FixedTopNode[0]);
|
currentSchema?.children.unshift(FixedTopNode[0]);
|
||||||
|
@ -598,7 +616,11 @@ IProject
|
||||||
|
|
||||||
checkNesting(
|
checkNesting(
|
||||||
dropTarget: INode,
|
dropTarget: INode,
|
||||||
dragObject: IPublicTypeDragNodeObject | IPublicTypeNodeSchema | INode | IPublicTypeDragNodeDataObject,
|
dragObject:
|
||||||
|
| IPublicTypeDragNodeObject
|
||||||
|
| IPublicTypeNodeSchema
|
||||||
|
| INode
|
||||||
|
| IPublicTypeDragNodeDataObject,
|
||||||
): boolean {
|
): boolean {
|
||||||
let items: Array<INode | IPublicTypeNodeSchema>;
|
let items: Array<INode | IPublicTypeNodeSchema>;
|
||||||
if (isDragNodeDataObject(dragObject)) {
|
if (isDragNodeDataObject(dragObject)) {
|
||||||
|
@ -611,7 +633,9 @@ IProject
|
||||||
console.warn('the dragObject is not in the correct type, dragObject:', dragObject);
|
console.warn('the dragObject is not in the correct type, dragObject:', dragObject);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return items.every((item) => this.checkNestingDown(dropTarget, item) && this.checkNestingUp(dropTarget, item));
|
return items.every(
|
||||||
|
(item) => this.checkNestingDown(dropTarget, item) && this.checkNestingUp(dropTarget, item),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -619,7 +643,10 @@ IProject
|
||||||
* Will be deleted in version 2.0.0.
|
* Will be deleted in version 2.0.0.
|
||||||
* Use checkNesting method instead.
|
* Use checkNesting method instead.
|
||||||
*/
|
*/
|
||||||
checkDropTarget(dropTarget: INode, dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject): boolean {
|
checkDropTarget(
|
||||||
|
dropTarget: INode,
|
||||||
|
dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject,
|
||||||
|
): boolean {
|
||||||
let items: Array<INode | IPublicTypeNodeSchema>;
|
let items: Array<INode | IPublicTypeNodeSchema>;
|
||||||
if (isDragNodeDataObject(dragObject)) {
|
if (isDragNodeDataObject(dragObject)) {
|
||||||
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
items = Array.isArray(dragObject.data) ? dragObject.data : [dragObject.data];
|
||||||
|
@ -686,7 +713,7 @@ IProject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
exportAddonData() {
|
exportAddonData() {
|
||||||
const addons: {
|
const addons: {
|
||||||
|
@ -722,10 +749,7 @@ IProject
|
||||||
}
|
}
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
acceptRootNodeVisitor(
|
acceptRootNodeVisitor(visitorName = 'default', visitorFn: (node: IRootNode) => any) {
|
||||||
visitorName = 'default',
|
|
||||||
visitorFn: (node: IRootNode) => any,
|
|
||||||
) {
|
|
||||||
let visitorResult = {};
|
let visitorResult = {};
|
||||||
if (!visitorName) {
|
if (!visitorName) {
|
||||||
/* eslint-disable-next-line no-console */
|
/* eslint-disable-next-line no-console */
|
||||||
|
@ -753,7 +777,7 @@ IProject
|
||||||
// 组件去重
|
// 组件去重
|
||||||
const exsitingMap: { [componentName: string]: boolean } = {};
|
const exsitingMap: { [componentName: string]: boolean } = {};
|
||||||
for (const node of this._nodesMap.values()) {
|
for (const node of this._nodesMap.values()) {
|
||||||
const { componentName } = node || {};
|
const componentName: string = node.componentName;
|
||||||
if (componentName === 'Slot') continue;
|
if (componentName === 'Slot') continue;
|
||||||
if (!exsitingMap[componentName]) {
|
if (!exsitingMap[componentName]) {
|
||||||
exsitingMap[componentName] = true;
|
exsitingMap[componentName] = true;
|
||||||
|
@ -855,4 +879,4 @@ export function isPageSchema(obj: any): obj is IPublicTypePageSchema {
|
||||||
return obj?.componentName === 'Page';
|
return obj?.componentName === 'Page';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDocumentModel extends DocumentModel {}
|
export interface IDocumentModel extends DocumentModel {}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { BuiltinSimulatorHostView } from '../builtin-simulator';
|
||||||
export class DocumentView extends Component<{ document: IDocumentModel }> {
|
export class DocumentView extends Component<{ document: IDocumentModel }> {
|
||||||
render() {
|
render() {
|
||||||
const { document } = this.props;
|
const { document } = this.props;
|
||||||
const { simulatorProps } = document;
|
const { simulatorProps } = document as any;
|
||||||
const Simulator = document.designer.simulatorComponent || BuiltinSimulatorHostView;
|
const Simulator = document.designer.simulatorComponent || BuiltinSimulatorHostView;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import { obx, computed, autorun, makeObservable, runInAction, wrapWithEventSwitch, action, createModuleEventBus, IEventBus } from '@alilc/lowcode-editor-core';
|
import {
|
||||||
|
obx,
|
||||||
|
computed,
|
||||||
|
autorun,
|
||||||
|
makeObservable,
|
||||||
|
runInAction,
|
||||||
|
wrapWithEventSwitch,
|
||||||
|
action,
|
||||||
|
createModuleEventBus,
|
||||||
|
IEventBus,
|
||||||
|
} from '@alilc/lowcode-editor-core';
|
||||||
import {
|
import {
|
||||||
IPublicTypeNodeSchema,
|
IPublicTypeNodeSchema,
|
||||||
IPublicTypePropsMap,
|
IPublicTypePropsMap,
|
||||||
|
@ -18,7 +28,7 @@ import {
|
||||||
IBaseModelNode,
|
IBaseModelNode,
|
||||||
} from '@alilc/lowcode-types';
|
} from '@alilc/lowcode-types';
|
||||||
import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils';
|
import { compatStage, isDOMText, isJSExpression, isNode, isNodeSchema } from '@alilc/lowcode-utils';
|
||||||
import { ISettingTopEntry } from '@alilc/lowcode-designer';
|
import { ISettingTopEntry } from '../../designer/setting/setting-top-entry';
|
||||||
import { Props, getConvertedExtraKey, IProps } from './props/props';
|
import { Props, getConvertedExtraKey, IProps } from './props/props';
|
||||||
import type { IDocumentModel } from '../document-model';
|
import type { IDocumentModel } from '../document-model';
|
||||||
import { NodeChildren, INodeChildren } from './node-children';
|
import { NodeChildren, INodeChildren } from './node-children';
|
||||||
|
@ -86,34 +96,38 @@ export interface IBaseNode extends Node {}
|
||||||
* isLocked
|
* isLocked
|
||||||
* hidden
|
* hidden
|
||||||
*/
|
*/
|
||||||
export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema> implements Omit<IBaseModelNode<
|
export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
IDocumentModel,
|
implements
|
||||||
IBaseNode,
|
Omit<
|
||||||
INodeChildren,
|
IBaseModelNode<
|
||||||
IComponentMeta,
|
IDocumentModel,
|
||||||
ISettingTopEntry,
|
IBaseNode,
|
||||||
IProps,
|
INodeChildren,
|
||||||
IProp,
|
IComponentMeta,
|
||||||
IExclusiveGroup
|
ISettingTopEntry,
|
||||||
>,
|
IProps,
|
||||||
'isRoot' |
|
IProp,
|
||||||
'isPage' |
|
IExclusiveGroup
|
||||||
'isComponent' |
|
>,
|
||||||
'isModal' |
|
| 'isRoot'
|
||||||
'isSlot' |
|
| 'isPage'
|
||||||
'isParental' |
|
| 'isComponent'
|
||||||
'isLeaf' |
|
| 'isModal'
|
||||||
'settingEntry' |
|
| 'isSlot'
|
||||||
// 在内部的 node 模型中不存在
|
| 'isParental'
|
||||||
'getExtraPropValue' |
|
| 'isLeaf'
|
||||||
'setExtraPropValue' |
|
| 'settingEntry'
|
||||||
'exportSchema' |
|
// 在内部的 node 模型中不存在
|
||||||
'visible' |
|
| 'getExtraPropValue'
|
||||||
'importSchema' |
|
| 'setExtraPropValue'
|
||||||
// 内外实现有差异
|
| 'exportSchema'
|
||||||
'isContainer' |
|
| 'visible'
|
||||||
'isEmpty'
|
| 'importSchema'
|
||||||
> {
|
// 内外实现有差异
|
||||||
|
| 'isContainer'
|
||||||
|
| 'isEmpty'
|
||||||
|
>
|
||||||
|
{
|
||||||
private emitter: IEventBus;
|
private emitter: IEventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -269,7 +283,10 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
pseudo: false,
|
pseudo: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(readonly document: IDocumentModel, nodeSchema: Schema) {
|
constructor(
|
||||||
|
readonly document: IDocumentModel,
|
||||||
|
nodeSchema: Schema,
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
const { componentName, id, children, props, ...extras } = nodeSchema;
|
const { componentName, id, children, props, ...extras } = nodeSchema;
|
||||||
this.id = document.nextId(id);
|
this.id = document.nextId(id);
|
||||||
|
@ -282,10 +299,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
this.props = new Props(this, props, extras);
|
this.props = new Props(this, props, extras);
|
||||||
this._children = new NodeChildren(this as INode, this.initialChildren(children));
|
this._children = new NodeChildren(this as INode, this.initialChildren(children));
|
||||||
this._children.internalInitParent();
|
this._children.internalInitParent();
|
||||||
this.props.merge(
|
this.props.merge(this.upgradeProps(this.initProps(props || {})), this.upgradeProps(extras));
|
||||||
this.upgradeProps(this.initProps(props || {})),
|
|
||||||
this.upgradeProps(extras),
|
|
||||||
);
|
|
||||||
this.setupAutoruns();
|
this.setupAutoruns();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,12 +324,18 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
*/
|
*/
|
||||||
@action
|
@action
|
||||||
private initBuiltinProps() {
|
private initBuiltinProps() {
|
||||||
this.props.has(getConvertedExtraKey('hidden')) || this.props.add(false, getConvertedExtraKey('hidden'));
|
this.props.has(getConvertedExtraKey('hidden')) ||
|
||||||
this.props.has(getConvertedExtraKey('title')) || this.props.add('', getConvertedExtraKey('title'));
|
this.props.add(false, getConvertedExtraKey('hidden'));
|
||||||
this.props.has(getConvertedExtraKey('isLocked')) || this.props.add(false, getConvertedExtraKey('isLocked'));
|
this.props.has(getConvertedExtraKey('title')) ||
|
||||||
this.props.has(getConvertedExtraKey('condition')) || this.props.add(true, getConvertedExtraKey('condition'));
|
this.props.add('', getConvertedExtraKey('title'));
|
||||||
this.props.has(getConvertedExtraKey('conditionGroup')) || this.props.add('', getConvertedExtraKey('conditionGroup'));
|
this.props.has(getConvertedExtraKey('isLocked')) ||
|
||||||
this.props.has(getConvertedExtraKey('loop')) || this.props.add(undefined, getConvertedExtraKey('loop'));
|
this.props.add(false, getConvertedExtraKey('isLocked'));
|
||||||
|
this.props.has(getConvertedExtraKey('condition')) ||
|
||||||
|
this.props.add(true, getConvertedExtraKey('condition'));
|
||||||
|
this.props.has(getConvertedExtraKey('conditionGroup')) ||
|
||||||
|
this.props.add('', getConvertedExtraKey('conditionGroup'));
|
||||||
|
this.props.has(getConvertedExtraKey('loop')) ||
|
||||||
|
this.props.add(undefined, getConvertedExtraKey('loop'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -340,7 +360,9 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private initialChildren(children: IPublicTypeNodeData | IPublicTypeNodeData[] | undefined): IPublicTypeNodeData[] {
|
private initialChildren(
|
||||||
|
children: IPublicTypeNodeData | IPublicTypeNodeData[] | undefined,
|
||||||
|
): IPublicTypeNodeData[] {
|
||||||
const { initialChildren } = this.componentMeta.advanced;
|
const { initialChildren } = this.componentMeta.advanced;
|
||||||
|
|
||||||
if (children == null) {
|
if (children == null) {
|
||||||
|
@ -527,9 +549,13 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
}
|
}
|
||||||
if (this.isSlot()) {
|
if (this.isSlot()) {
|
||||||
this.parent.removeSlot(this);
|
this.parent.removeSlot(this);
|
||||||
this.parent.children?.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
this.parent.children?.internalDelete(this, purge, useMutator, {
|
||||||
|
suppressRemoveEvent: true,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
this.parent.children?.internalDelete(this, purge, useMutator, { suppressRemoveEvent: true });
|
this.parent.children?.internalDelete(this, purge, useMutator, {
|
||||||
|
suppressRemoveEvent: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -550,7 +576,8 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
|
|
||||||
canSelect(): boolean {
|
canSelect(): boolean {
|
||||||
const onSelectHook = this.componentMeta?.advanced?.callbacks?.onSelectHook;
|
const onSelectHook = this.componentMeta?.advanced?.callbacks?.onSelectHook;
|
||||||
const canSelect = typeof onSelectHook === 'function' ? onSelectHook(this.internalToShellNode()!) : true;
|
const canSelect =
|
||||||
|
typeof onSelectHook === 'function' ? onSelectHook(this.internalToShellNode()!) : true;
|
||||||
return canSelect;
|
return canSelect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +872,10 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
/**
|
/**
|
||||||
* 导出 schema
|
* 导出 schema
|
||||||
*/
|
*/
|
||||||
export<T = IPublicTypeNodeSchema>(stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save, options: any = {}): T {
|
export<T = IPublicTypeNodeSchema>(
|
||||||
|
stage: IPublicEnumTransformStage = IPublicEnumTransformStage.Save,
|
||||||
|
options: any = {},
|
||||||
|
): T {
|
||||||
stage = compatStage(stage);
|
stage = compatStage(stage);
|
||||||
const baseSchema: any = {
|
const baseSchema: any = {
|
||||||
componentName: this.componentName,
|
componentName: this.componentName,
|
||||||
|
@ -999,12 +1029,11 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
*/
|
*/
|
||||||
canPerformAction(actionName: string): boolean {
|
canPerformAction(actionName: string): boolean {
|
||||||
const availableActions =
|
const availableActions =
|
||||||
this.componentMeta?.availableActions?.filter((action: IPublicTypeComponentAction) => {
|
this.componentMeta?.availableActions
|
||||||
const { condition } = action;
|
?.filter((action: IPublicTypeComponentAction) => {
|
||||||
return typeof condition === 'function' ?
|
const { condition } = action;
|
||||||
condition(this) !== false :
|
return typeof condition === 'function' ? condition(this) !== false : condition !== false;
|
||||||
condition !== false;
|
})
|
||||||
})
|
|
||||||
.map((action: IPublicTypeComponentAction) => action.name) || [];
|
.map((action: IPublicTypeComponentAction) => action.name) || [];
|
||||||
|
|
||||||
return availableActions.indexOf(actionName) >= 0;
|
return availableActions.indexOf(actionName) >= 0;
|
||||||
|
@ -1061,7 +1090,9 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
return this.props;
|
return this.props;
|
||||||
}
|
}
|
||||||
|
|
||||||
onChildrenChange(fn: (param?: { type: string; node: INode }) => void): IPublicTypeDisposable | undefined {
|
onChildrenChange(
|
||||||
|
fn: (param?: { type: string; node: INode }) => void,
|
||||||
|
): IPublicTypeDisposable | undefined {
|
||||||
const wrappedFunc = wrapWithEventSwitch(fn);
|
const wrappedFunc = wrapWithEventSwitch(fn);
|
||||||
return this.children?.onChange(wrappedFunc);
|
return this.children?.onChange(wrappedFunc);
|
||||||
}
|
}
|
||||||
|
@ -1131,7 +1162,7 @@ export class Node<Schema extends IPublicTypeNodeSchema = IPublicTypeNodeSchema>
|
||||||
const isContainerNode = this.isContainer();
|
const isContainerNode = this.isContainer();
|
||||||
const isEmptyNode = this.isEmpty();
|
const isEmptyNode = this.isEmpty();
|
||||||
const isRGLContainerNode = this.isRGLContainer;
|
const isRGLContainerNode = this.isRGLContainer;
|
||||||
const isRGLNode = (this.getParent()?.isRGLContainer) as boolean;
|
const isRGLNode = this.getParent()?.isRGLContainer as boolean;
|
||||||
const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode));
|
const isRGL = isRGLContainerNode || (isRGLNode && (!isContainerNode || !isEmptyNode));
|
||||||
let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null;
|
let rglNode = isRGLContainerNode ? this : isRGL ? this?.getParent() : null;
|
||||||
return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode };
|
return { isContainerNode, isEmptyNode, isRGLContainerNode, isRGLNode, isRGL, rglNode };
|
||||||
|
@ -1294,7 +1325,13 @@ export interface ISlotNode extends Node<IPublicTypeSlotSchema> {}
|
||||||
export interface IPageNode extends Node<IPublicTypePageSchema> {}
|
export interface IPageNode extends Node<IPublicTypePageSchema> {}
|
||||||
export interface IComponentNode extends Node<IPublicTypeComponentSchema> {}
|
export interface IComponentNode extends Node<IPublicTypeComponentSchema> {}
|
||||||
export interface IRootNode extends Node<IPublicTypePageSchema | IPublicTypeComponentSchema> {}
|
export interface IRootNode extends Node<IPublicTypePageSchema | IPublicTypeComponentSchema> {}
|
||||||
export interface INode extends Node<IPublicTypePageSchema | IPublicTypeSlotSchema | IPublicTypeComponentSchema | IPublicTypeNodeSchema> {}
|
export interface INode
|
||||||
|
extends Node<
|
||||||
|
| IPublicTypePageSchema
|
||||||
|
| IPublicTypeSlotSchema
|
||||||
|
| IPublicTypeComponentSchema
|
||||||
|
| IPublicTypeNodeSchema
|
||||||
|
> {}
|
||||||
|
|
||||||
export function isRootNode(node: INode): node is IRootNode {
|
export function isRootNode(node: INode): node is IRootNode {
|
||||||
return node && node.isRootNode;
|
return node && node.isRootNode;
|
||||||
|
|
|
@ -48,7 +48,7 @@ export class Selection implements ISelection {
|
||||||
selectAll(ids: string[]) {
|
selectAll(ids: string[]) {
|
||||||
const selectIds: string[] = [];
|
const selectIds: string[] = [];
|
||||||
|
|
||||||
ids.forEach(d => {
|
ids.forEach((d) => {
|
||||||
const node = this.doc.getNode(d);
|
const node = this.doc.getNode(d);
|
||||||
|
|
||||||
if (node?.canSelect()) {
|
if (node?.canSelect()) {
|
||||||
|
@ -125,7 +125,7 @@ export class Selection implements ISelection {
|
||||||
containsNode(node: INode, excludeRoot = false) {
|
containsNode(node: INode, excludeRoot = false) {
|
||||||
for (const id of this._selected) {
|
for (const id of this._selected) {
|
||||||
const parent = this.doc.getNode(id);
|
const parent = this.doc.getNode(id);
|
||||||
if (excludeRoot && parent?.contains(this.doc.focusNode)) {
|
if (excludeRoot && parent?.contains(this.doc.focusNode!)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (parent?.contains(node)) {
|
if (parent?.contains(node)) {
|
||||||
|
@ -157,7 +157,7 @@ export class Selection implements ISelection {
|
||||||
for (const id of this._selected) {
|
for (const id of this._selected) {
|
||||||
const node = this.doc.getNode(id);
|
const node = this.doc.getNode(id);
|
||||||
// 排除根节点
|
// 排除根节点
|
||||||
if (!node || (!includeRoot && node.contains(this.doc.focusNode))) {
|
if (!node || (!includeRoot && node.contains(this.doc.focusNode!))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let i = nodes.length;
|
let i = nodes.length;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
declare module 'ric-shim';
|
|
@ -23,7 +23,25 @@ import {
|
||||||
const logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' });
|
const logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' });
|
||||||
|
|
||||||
// 保留的事件前缀
|
// 保留的事件前缀
|
||||||
const RESERVED_EVENT_PREFIX = ['designer', 'editor', 'skeleton', 'renderer', 'render', 'utils', 'plugin', 'engine', 'editor-core', 'engine-core', 'plugins', 'event', 'events', 'log', 'logger', 'ctx', 'context'];
|
const RESERVED_EVENT_PREFIX = [
|
||||||
|
'designer',
|
||||||
|
'editor',
|
||||||
|
'skeleton',
|
||||||
|
'renderer',
|
||||||
|
'render',
|
||||||
|
'utils',
|
||||||
|
'plugin',
|
||||||
|
'engine',
|
||||||
|
'editor-core',
|
||||||
|
'engine-core',
|
||||||
|
'plugins',
|
||||||
|
'event',
|
||||||
|
'events',
|
||||||
|
'log',
|
||||||
|
'logger',
|
||||||
|
'ctx',
|
||||||
|
'context',
|
||||||
|
];
|
||||||
|
|
||||||
export class LowCodePluginManager implements ILowCodePluginManager {
|
export class LowCodePluginManager implements ILowCodePluginManager {
|
||||||
private plugins: ILowCodePluginRuntime[] = [];
|
private plugins: ILowCodePluginRuntime[] = [];
|
||||||
|
@ -35,7 +53,10 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||||
|
|
||||||
contextApiAssembler: ILowCodePluginContextApiAssembler;
|
contextApiAssembler: ILowCodePluginContextApiAssembler;
|
||||||
|
|
||||||
constructor(contextApiAssembler: ILowCodePluginContextApiAssembler, readonly viewName = 'global') {
|
constructor(
|
||||||
|
contextApiAssembler: ILowCodePluginContextApiAssembler,
|
||||||
|
readonly viewName = 'global',
|
||||||
|
) {
|
||||||
this.contextApiAssembler = contextApiAssembler;
|
this.contextApiAssembler = contextApiAssembler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,24 +100,30 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||||
const isReservedPrefix = RESERVED_EVENT_PREFIX.find((item) => item === eventPrefix);
|
const isReservedPrefix = RESERVED_EVENT_PREFIX.find((item) => item === eventPrefix);
|
||||||
if (isReservedPrefix) {
|
if (isReservedPrefix) {
|
||||||
meta.eventPrefix = undefined;
|
meta.eventPrefix = undefined;
|
||||||
logger.warn(`plugin ${pluginName} is trying to use ${eventPrefix} as event prefix, which is a reserved event prefix, please use another one`);
|
logger.warn(
|
||||||
|
`plugin ${pluginName} is trying to use ${eventPrefix} as event prefix, which is a reserved event prefix, please use another one`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const ctx = this._getLowCodePluginContext({ pluginName, meta });
|
const ctx = this._getLowCodePluginContext({ pluginName, meta });
|
||||||
const customFilterValidOptions = engineConfig.get('customPluginFilterOptions', filterValidOptions);
|
const customFilterValidOptions = engineConfig.get(
|
||||||
|
'customPluginFilterOptions',
|
||||||
|
filterValidOptions,
|
||||||
|
);
|
||||||
const pluginTransducer = engineConfig.get('customPluginTransducer', null);
|
const pluginTransducer = engineConfig.get('customPluginTransducer', null);
|
||||||
const newPluginModel = pluginTransducer ? await pluginTransducer(pluginModel, ctx, options) : pluginModel;
|
const newPluginModel = pluginTransducer
|
||||||
const newOptions = customFilterValidOptions(options, newPluginModel.meta?.preferenceDeclaration);
|
? await pluginTransducer(pluginModel, ctx, options)
|
||||||
|
: pluginModel;
|
||||||
|
const newOptions = customFilterValidOptions(
|
||||||
|
options,
|
||||||
|
newPluginModel.meta?.preferenceDeclaration,
|
||||||
|
);
|
||||||
const config = newPluginModel(ctx, newOptions);
|
const config = newPluginModel(ctx, newOptions);
|
||||||
// compat the legacy way to declare pluginName
|
// compat the legacy way to declare pluginName
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
pluginName = pluginName || config.name;
|
pluginName = pluginName || config.name;
|
||||||
invariant(
|
invariant(pluginName, 'pluginConfigCreator.pluginName required', config);
|
||||||
pluginName,
|
|
||||||
'pluginConfigCreator.pluginName required',
|
|
||||||
config,
|
|
||||||
);
|
|
||||||
|
|
||||||
ctx.setPreference(pluginName, preferenceDeclaration);
|
ctx.setPreference(pluginName, preferenceDeclaration!);
|
||||||
|
|
||||||
const allowOverride = registerOptions?.override === true;
|
const allowOverride = registerOptions?.override === true;
|
||||||
|
|
||||||
|
@ -119,7 +146,9 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||||
|
|
||||||
const engineVersionExp = engines && engines.lowcodeEngine;
|
const engineVersionExp = engines && engines.lowcodeEngine;
|
||||||
if (engineVersionExp && !this.isEngineVersionMatched(engineVersionExp)) {
|
if (engineVersionExp && !this.isEngineVersionMatched(engineVersionExp)) {
|
||||||
throw new Error(`plugin ${pluginName} skipped, engine check failed, current engine version is ${engineConfig.get('ENGINE_VERSION')}, meta.engines.lowcodeEngine is ${engineVersionExp}`);
|
throw new Error(
|
||||||
|
`plugin ${pluginName} skipped, engine check failed, current engine version is ${engineConfig.get('ENGINE_VERSION')}, meta.engines.lowcodeEngine is ${engineVersionExp}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const plugin = new LowCodePluginRuntime(pluginName, this, config, meta);
|
const plugin = new LowCodePluginRuntime(pluginName, this, config, meta);
|
||||||
|
@ -188,7 +217,9 @@ export class LowCodePluginManager implements ILowCodePluginManager {
|
||||||
return this.pluginsMap.size;
|
return this.pluginsMap.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
getPluginPreference(pluginName: string): Record<string, IPublicTypePreferenceValueType> | null | undefined {
|
getPluginPreference(
|
||||||
|
pluginName: string,
|
||||||
|
): Record<string, IPublicTypePreferenceValueType> | null | undefined {
|
||||||
if (!this.pluginPreference) {
|
if (!this.pluginPreference) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { isPlainObject } from 'lodash';
|
import { isPlainObject } from 'lodash-es';
|
||||||
import { IPublicTypePluginRegisterOptions, IPublicTypePluginDeclaration } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypePluginRegisterOptions,
|
||||||
|
IPublicTypePluginDeclaration,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
|
|
||||||
export function isValidPreferenceKey(
|
export function isValidPreferenceKey(
|
||||||
key: string,
|
key: string,
|
||||||
|
@ -17,10 +20,7 @@ export function isLowCodeRegisterOptions(opts: any): opts is IPublicTypePluginRe
|
||||||
return opts && ('autoInit' in opts || 'override' in opts);
|
return opts && ('autoInit' in opts || 'override' in opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function filterValidOptions(
|
export function filterValidOptions(opts: any, preferenceDeclaration: IPublicTypePluginDeclaration) {
|
||||||
opts: any,
|
|
||||||
preferenceDeclaration: IPublicTypePluginDeclaration,
|
|
||||||
) {
|
|
||||||
if (!opts || !isPlainObject(opts)) return opts;
|
if (!opts || !isPlainObject(opts)) return opts;
|
||||||
const filteredOpts = {} as any;
|
const filteredOpts = {} as any;
|
||||||
Object.keys(opts).forEach((key) => {
|
Object.keys(opts).forEach((key) => {
|
||||||
|
@ -32,4 +32,4 @@ export function filterValidOptions(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return filteredOpts;
|
return filteredOpts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export function sequence({
|
||||||
}
|
}
|
||||||
const node = tasks[name];
|
const node = tasks[name];
|
||||||
if (!node) {
|
if (!node) {
|
||||||
missing.push([parentName, name].filter((d => !!d)).join('.'));
|
missing.push([parentName, name].filter((d) => !!d).join('.'));
|
||||||
} else if (nest.indexOf(name) > -1) {
|
} else if (nest.indexOf(name) > -1) {
|
||||||
nest.push(name);
|
nest.push(name);
|
||||||
recursive.push(nest.slice(0));
|
recursive.push(nest.slice(0));
|
||||||
|
@ -64,7 +64,7 @@ export default function (tasks: ITaks, names: string[]) {
|
||||||
missing,
|
missing,
|
||||||
recursive,
|
recursive,
|
||||||
nest: [],
|
nest: [],
|
||||||
});
|
} as any);
|
||||||
|
|
||||||
if (missing.length || recursive.length) {
|
if (missing.length || recursive.length) {
|
||||||
results = []; // results are incomplete at best, completely wrong at worst, remove them to avoid confusion
|
results = []; // results are incomplete at best, completely wrong at worst, remove them to avoid confusion
|
||||||
|
|
|
@ -1,19 +1,7 @@
|
||||||
import React from 'react';
|
|
||||||
import set from 'lodash/set';
|
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
import { Editor } from '@alilc/lowcode-editor-core';
|
|
||||||
import { Project } from '../../src/project/project';
|
|
||||||
import { Node } from '../../src/document/node/node';
|
|
||||||
import TestRenderer from 'react-test-renderer';
|
|
||||||
import { configure, render, mount } from 'enzyme';
|
|
||||||
import Adapter from 'enzyme-adapter-react-16';
|
|
||||||
import { Designer } from '../../src/designer/designer';
|
|
||||||
import formSchema from '../fixtures/schema/form';
|
|
||||||
import { getMockRenderer } from '../utils';
|
import { getMockRenderer } from '../utils';
|
||||||
import { isSimulatorRenderer } from '../../src/builtin-simulator/renderer';
|
import { isSimulatorRenderer } from '../../src/builtin-simulator/renderer';
|
||||||
|
|
||||||
|
|
||||||
describe('renderer 测试', () => {
|
describe('renderer 测试', () => {
|
||||||
it('renderer', () => {
|
it('renderer', () => {
|
||||||
expect(isSimulatorRenderer(getMockRenderer())).toBeTruthy();
|
expect(isSimulatorRenderer(getMockRenderer())).toBeTruthy();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import set from 'lodash/set';
|
import { set, cloneDeep } from 'lodash-es';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
|
||||||
import '../../fixtures/window';
|
import '../../fixtures/window';
|
||||||
import { Project, IProject } from '../../../src/project/project';
|
import { Project, IProject } from '../../../src/project/project';
|
||||||
import { Node, INode } from '../../../src/document/node/node';
|
import { Node, INode } from '../../../src/document/node/node';
|
||||||
|
@ -22,7 +21,9 @@ jest.mock('../../../src/designer/designer', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
transformProps(props) { return props; },
|
transformProps(props) {
|
||||||
|
return props;
|
||||||
|
},
|
||||||
createSettingEntry: mockCreateSettingEntry,
|
createSettingEntry: mockCreateSettingEntry,
|
||||||
postEvent() {},
|
postEvent() {},
|
||||||
};
|
};
|
||||||
|
@ -40,9 +41,7 @@ describe('schema 生成节点模型测试', () => {
|
||||||
let project: IProject;
|
let project: IProject;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
project = new Project(designer, {
|
project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
});
|
});
|
||||||
|
@ -56,8 +55,10 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const expectedNodeCnt = ids.length;
|
const expectedNodeCnt = ids.length;
|
||||||
expect(nodesMap?.size).toBe(expectedNodeCnt);
|
expect(nodesMap?.size).toBe(expectedNodeCnt);
|
||||||
ids.forEach(id => {
|
ids.forEach((id) => {
|
||||||
expect(nodesMap?.get(id)?.componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
expect(nodesMap?.get(id)?.componentName).toBe(
|
||||||
|
getNodeFromSchemaById(formSchema, id).componentName,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const pageNode = currentDocument?.getNode('page');
|
const pageNode = currentDocument?.getNode('page');
|
||||||
|
@ -66,7 +67,7 @@ describe('schema 生成节点模型测试', () => {
|
||||||
|
|
||||||
const exportSchema = currentDocument?.export(1);
|
const exportSchema = currentDocument?.export(1);
|
||||||
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
||||||
nodesMap.forEach(node => {
|
nodesMap.forEach((node) => {
|
||||||
// 触发 getter
|
// 触发 getter
|
||||||
node.settingEntry;
|
node.settingEntry;
|
||||||
});
|
});
|
||||||
|
@ -245,16 +246,14 @@ describe('schema 生成节点模型测试', () => {
|
||||||
expect(pageNode?.isPage()).toBe(true);
|
expect(pageNode?.isPage()).toBe(true);
|
||||||
expect(pageNode?.isComponent()).toBe(false);
|
expect(pageNode?.isComponent()).toBe(false);
|
||||||
expect(pageNode?.isSlot()).toBe(false);
|
expect(pageNode?.isSlot()).toBe(false);
|
||||||
expect(pageNode?.title).toBe('hey, i\' a page!');
|
expect(pageNode?.title).toBe("hey, i' a page!");
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('节点新增(insertNode)', () => {
|
describe('节点新增(insertNode)', () => {
|
||||||
let project: Project;
|
let project: Project;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
project = new Project(designer, {
|
project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
});
|
});
|
||||||
|
@ -292,14 +291,19 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const nodesMap = currentDocument?.nodesMap;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap?.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
formNode && currentDocument?.insertNode(formNode, {
|
formNode &&
|
||||||
componentName: 'TextInput',
|
currentDocument?.insertNode(
|
||||||
id: 'nodeschema-id1',
|
formNode,
|
||||||
props: {
|
{
|
||||||
propA: 'haha',
|
componentName: 'TextInput',
|
||||||
propB: 3,
|
id: 'nodeschema-id1',
|
||||||
},
|
props: {
|
||||||
}, 0);
|
propA: 'haha',
|
||||||
|
propB: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
);
|
||||||
expect(nodesMap?.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode?.children?.length).toBe(4);
|
expect(formNode?.children?.length).toBe(4);
|
||||||
const insertedNode = formNode?.children?.get(0);
|
const insertedNode = formNode?.children?.get(0);
|
||||||
|
@ -318,14 +322,19 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const nodesMap = currentDocument?.nodesMap;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap?.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
formNode && currentDocument?.insertNode(formNode, {
|
formNode &&
|
||||||
componentName: 'TextInput',
|
currentDocument?.insertNode(
|
||||||
id: 'nodeschema-id1',
|
formNode,
|
||||||
props: {
|
{
|
||||||
propA: 'haha',
|
componentName: 'TextInput',
|
||||||
propB: 3,
|
id: 'nodeschema-id1',
|
||||||
},
|
props: {
|
||||||
}, 1);
|
propA: 'haha',
|
||||||
|
propB: 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
1,
|
||||||
|
);
|
||||||
expect(nodesMap?.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
expect(formNode?.children?.length).toBe(4);
|
expect(formNode?.children?.length).toBe(4);
|
||||||
const insertedNode = formNode?.children?.get(1);
|
const insertedNode = formNode?.children?.get(1);
|
||||||
|
@ -380,14 +389,15 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const nodesMap = currentDocument?.nodesMap;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap?.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
formNode && currentDocument?.insertNode(formNode, {
|
formNode &&
|
||||||
componentName: 'TextInput',
|
currentDocument?.insertNode(formNode, {
|
||||||
id: 'nodeschema-id1',
|
componentName: 'TextInput',
|
||||||
props: {
|
id: 'nodeschema-id1',
|
||||||
propA: 'haha',
|
props: {
|
||||||
propB: 3,
|
propA: 'haha',
|
||||||
},
|
propB: 3,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
||||||
expect(nodesMap?.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
});
|
});
|
||||||
|
@ -398,14 +408,15 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const nodesMap = currentDocument?.nodesMap;
|
const nodesMap = currentDocument?.nodesMap;
|
||||||
const formNode = nodesMap?.get('form');
|
const formNode = nodesMap?.get('form');
|
||||||
formNode && currentDocument?.insertNode(formNode, {
|
formNode &&
|
||||||
componentName: 'TextInput',
|
currentDocument?.insertNode(formNode, {
|
||||||
id: 'nodeschema-id1',
|
componentName: 'TextInput',
|
||||||
props: {
|
id: 'nodeschema-id1',
|
||||||
propA: 'haha',
|
props: {
|
||||||
propB: 3,
|
propA: 'haha',
|
||||||
},
|
propB: 3,
|
||||||
});
|
},
|
||||||
|
});
|
||||||
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
expect(nodesMap?.get('nodeschema-id1')?.componentName).toBe('TextInput');
|
||||||
expect(nodesMap?.size).toBe(ids.length + 1);
|
expect(nodesMap?.size).toBe(ids.length + 1);
|
||||||
});
|
});
|
||||||
|
@ -463,9 +474,7 @@ describe('schema 生成节点模型测试', () => {
|
||||||
let project: Project;
|
let project: Project;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
project = new Project(designer, {
|
project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
});
|
});
|
||||||
|
@ -477,22 +486,26 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const formNode = nodesMap?.get('form') as Node;
|
const formNode = nodesMap?.get('form') as Node;
|
||||||
const formNode2 = currentDocument?.getNode('form');
|
const formNode2 = currentDocument?.getNode('form');
|
||||||
expect(formNode).toEqual(formNode2);
|
expect(formNode).toEqual(formNode2);
|
||||||
currentDocument?.insertNodes(formNode, [
|
currentDocument?.insertNodes(
|
||||||
{
|
formNode,
|
||||||
componentName: 'TextInput',
|
[
|
||||||
props: {
|
{
|
||||||
propA: 'haha2',
|
componentName: 'TextInput',
|
||||||
propB: 3,
|
props: {
|
||||||
|
propA: 'haha2',
|
||||||
|
propB: 3,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
{
|
componentName: 'TextInput2',
|
||||||
componentName: 'TextInput2',
|
props: {
|
||||||
props: {
|
propA: 'haha',
|
||||||
propA: 'haha',
|
propB: 3,
|
||||||
propB: 3,
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
], 1);
|
1,
|
||||||
|
);
|
||||||
expect(nodesMap?.size).toBe(ids.length + 2);
|
expect(nodesMap?.size).toBe(ids.length + 2);
|
||||||
expect(formNode.children?.length).toBe(5);
|
expect(formNode.children?.length).toBe(5);
|
||||||
const insertedNode1 = formNode.children?.get(1);
|
const insertedNode1 = formNode.children?.get(1);
|
||||||
|
@ -552,11 +565,13 @@ describe('schema 生成节点模型测试', () => {
|
||||||
|
|
||||||
describe('block ❌ | component ❌ | slot ✅', () => {
|
describe('block ❌ | component ❌ | slot ✅', () => {
|
||||||
it('基本的 slot 创建', () => {
|
it('基本的 slot 创建', () => {
|
||||||
const formSchemaWithSlot = set(cloneDeep(formSchema), 'children[0].children[0].props.title.type', 'JSSlot');
|
const formSchemaWithSlot = set(
|
||||||
|
cloneDeep(formSchema),
|
||||||
|
'children[0].children[0].props.title.type',
|
||||||
|
'JSSlot',
|
||||||
|
);
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchemaWithSlot],
|
||||||
formSchemaWithSlot,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import set from 'lodash/set';
|
import { set, cloneDeep } from 'lodash-es';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
|
||||||
import '../../fixtures/window';
|
import '../../fixtures/window';
|
||||||
import { Project } from '../../../src/project/project';
|
import { Project } from '../../../src/project/project';
|
||||||
import { Designer } from '../../../src/designer/designer';
|
import { Designer } from '../../../src/designer/designer';
|
||||||
|
@ -21,7 +20,9 @@ jest.mock('../../../src/designer/designer', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
transformProps(props) { return props; },
|
transformProps(props) {
|
||||||
|
return props;
|
||||||
|
},
|
||||||
createSettingEntry: mockCreateSettingEntry,
|
createSettingEntry: mockCreateSettingEntry,
|
||||||
postEvent() {},
|
postEvent() {},
|
||||||
};
|
};
|
||||||
|
@ -37,9 +38,7 @@ beforeAll(() => {
|
||||||
describe('节点模型删除测试', () => {
|
describe('节点模型删除测试', () => {
|
||||||
it('删除叶子节点', () => {
|
it('删除叶子节点', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -62,12 +61,13 @@ describe('节点模型删除测试', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('删除叶子节点,带有 slot', () => {
|
it('删除叶子节点,带有 slot', () => {
|
||||||
const formSchemaWithSlot = set(cloneDeep(formSchema),
|
const formSchemaWithSlot = set(
|
||||||
'children[1].children[0].children[2].children[1].props.greeting.type', 'JSSlot');
|
cloneDeep(formSchema),
|
||||||
|
'children[1].children[0].children[2].children[1].props.greeting.type',
|
||||||
|
'JSSlot',
|
||||||
|
);
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchemaWithSlot],
|
||||||
formSchemaWithSlot,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -84,9 +84,7 @@ describe('节点模型删除测试', () => {
|
||||||
|
|
||||||
it('删除分支节点', () => {
|
it('删除分支节点', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -102,12 +100,13 @@ describe('节点模型删除测试', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('删除分支节点,带有 slot', () => {
|
it('删除分支节点,带有 slot', () => {
|
||||||
const formSchemaWithSlot = set(cloneDeep(formSchema),
|
const formSchemaWithSlot = set(
|
||||||
'children[1].children[0].children[2].children[1].props.greeting.type', 'JSSlot');
|
cloneDeep(formSchema),
|
||||||
|
'children[1].children[0].children[2].children[1].props.greeting.type',
|
||||||
|
'JSSlot',
|
||||||
|
);
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchemaWithSlot],
|
||||||
formSchemaWithSlot,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
import set from 'lodash/set';
|
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../src/project/project';
|
||||||
import { Node } from '../../src/document/node/node';
|
|
||||||
import { Designer } from '../../src/designer/designer';
|
import { Designer } from '../../src/designer/designer';
|
||||||
import formSchema from '../fixtures/schema/form';
|
import formSchema from '../fixtures/schema/form';
|
||||||
import { getIdsFromSchema, getNodeFromSchemaById } from '../utils';
|
|
||||||
|
|
||||||
const mockCreateSettingEntry = jest.fn();
|
const mockCreateSettingEntry = jest.fn();
|
||||||
jest.mock('../../src/designer/designer', () => {
|
jest.mock('../../src/designer/designer', () => {
|
||||||
|
@ -22,7 +18,9 @@ jest.mock('../../src/designer/designer', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
transformProps(props) { return props; },
|
transformProps(props) {
|
||||||
|
return props;
|
||||||
|
},
|
||||||
createSettingEntry: mockCreateSettingEntry,
|
createSettingEntry: mockCreateSettingEntry,
|
||||||
postEvent() {},
|
postEvent() {},
|
||||||
};
|
};
|
||||||
|
@ -38,9 +36,7 @@ beforeAll(() => {
|
||||||
describe('选择区测试', () => {
|
describe('选择区测试', () => {
|
||||||
it('常规方法', () => {
|
it('常规方法', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -92,9 +88,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('add 方法', () => {
|
it('add 方法', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -124,9 +118,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('selectAll 包含不存在的 id', () => {
|
it('selectAll 包含不存在的 id', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -140,9 +132,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('dispose 方法 - 选中的节点没有被删除的', () => {
|
it('dispose 方法 - 选中的节点没有被删除的', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -160,9 +150,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('containsNode 方法', () => {
|
it('containsNode 方法', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -190,9 +178,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('containsNode 方法 - excludeRoot: true', () => {
|
it('containsNode 方法 - excludeRoot: true', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -213,9 +199,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('containsNode 方法 - excludeRoot: true', () => {
|
it('containsNode 方法 - excludeRoot: true', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -239,9 +223,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('getNodes', () => {
|
it('getNodes', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
|
@ -255,9 +237,7 @@ describe('选择区测试', () => {
|
||||||
|
|
||||||
it('getTopNodes - BeforeOrAfter', () => {
|
it('getTopNodes - BeforeOrAfter', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
|
@ -269,9 +249,7 @@ describe('选择区测试', () => {
|
||||||
});
|
});
|
||||||
it('getTopNodes', () => {
|
it('getTopNodes', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import set from 'lodash/set';
|
import { set, cloneDeep } from 'lodash-es';
|
||||||
import cloneDeep from 'lodash/cloneDeep';
|
|
||||||
import '../fixtures/window';
|
import '../fixtures/window';
|
||||||
import { Editor } from '@alilc/lowcode-editor-core';
|
import { Editor } from '@alilc/lowcode-editor-core';
|
||||||
import { Project } from '../../src/project/project';
|
import { Project } from '../../src/project/project';
|
||||||
|
@ -22,7 +21,9 @@ jest.mock('../../src/designer/designer', () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
transformProps(props) { return props; },
|
transformProps(props) {
|
||||||
|
return props;
|
||||||
|
},
|
||||||
createSettingEntry: mockCreateSettingEntry,
|
createSettingEntry: mockCreateSettingEntry,
|
||||||
postEvent() {},
|
postEvent() {},
|
||||||
};
|
};
|
||||||
|
@ -44,9 +45,7 @@ describe('schema 生成节点模型测试', () => {
|
||||||
|
|
||||||
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -55,13 +54,15 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const expectedNodeCnt = ids.length;
|
const expectedNodeCnt = ids.length;
|
||||||
expect(nodesMap.size).toBe(expectedNodeCnt);
|
expect(nodesMap.size).toBe(expectedNodeCnt);
|
||||||
ids.forEach(id => {
|
ids.forEach((id) => {
|
||||||
expect(nodesMap.get(id).componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
expect(nodesMap.get(id).componentName).toBe(
|
||||||
|
getNodeFromSchemaById(formSchema, id).componentName,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const exportSchema = currentDocument?.export(1);
|
const exportSchema = currentDocument?.export(1);
|
||||||
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
||||||
nodesMap.forEach(node => {
|
nodesMap.forEach((node) => {
|
||||||
// 触发 getter
|
// 触发 getter
|
||||||
node.settingEntry;
|
node.settingEntry;
|
||||||
});
|
});
|
||||||
|
@ -70,9 +71,7 @@ describe('schema 生成节点模型测试', () => {
|
||||||
|
|
||||||
it('onSimulatorReady works', () => {
|
it('onSimulatorReady works', () => {
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchema],
|
||||||
formSchema,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -103,23 +102,26 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const project = new Project(designer);
|
const project = new Project(designer);
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
// trigger autoOpen case
|
// trigger autoOpen case
|
||||||
project.load({
|
project.load(
|
||||||
componentsTree: [
|
{
|
||||||
formSchema,
|
componentsTree: [formSchema],
|
||||||
],
|
},
|
||||||
}, true);
|
true,
|
||||||
|
);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
const { nodesMap } = currentDocument;
|
const { nodesMap } = currentDocument;
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const expectedNodeCnt = ids.length;
|
const expectedNodeCnt = ids.length;
|
||||||
expect(nodesMap.size).toBe(expectedNodeCnt);
|
expect(nodesMap.size).toBe(expectedNodeCnt);
|
||||||
ids.forEach(id => {
|
ids.forEach((id) => {
|
||||||
expect(nodesMap.get(id).componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
expect(nodesMap.get(id).componentName).toBe(
|
||||||
|
getNodeFromSchemaById(formSchema, id).componentName,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const exportSchema = currentDocument?.export(1);
|
const exportSchema = currentDocument?.export(1);
|
||||||
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
||||||
nodesMap.forEach(node => {
|
nodesMap.forEach((node) => {
|
||||||
// 触发 getter
|
// 触发 getter
|
||||||
node.settingEntry;
|
node.settingEntry;
|
||||||
});
|
});
|
||||||
|
@ -129,31 +131,34 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const project = new Project(designer);
|
const project = new Project(designer);
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
// trigger autoOpen case
|
// trigger autoOpen case
|
||||||
project.load({
|
project.load(
|
||||||
componentsTree: [
|
{
|
||||||
{
|
componentsTree: [
|
||||||
...formSchema,
|
{
|
||||||
fileName: 'demoFile1',
|
...formSchema,
|
||||||
|
fileName: 'demoFile1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...formSchema,
|
||||||
|
fileName: 'demoFile2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
config: {
|
||||||
|
layout: {
|
||||||
|
props: {
|
||||||
|
tabBar: {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
path: '/demoFile2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
...formSchema,
|
true,
|
||||||
fileName: 'demoFile2',
|
);
|
||||||
}
|
|
||||||
],
|
|
||||||
config: {
|
|
||||||
layout: {
|
|
||||||
props: {
|
|
||||||
tabBar: {
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
path: '/demoFile2',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
expect(currentDocument.fileName).toBe('demoFile2');
|
expect(currentDocument.fileName).toBe('demoFile2');
|
||||||
});
|
});
|
||||||
|
@ -162,23 +167,25 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const project = new Project(designer);
|
const project = new Project(designer);
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
// trigger autoOpen case
|
// trigger autoOpen case
|
||||||
project.load({
|
project.load(
|
||||||
componentsTree: [
|
{
|
||||||
{
|
componentsTree: [
|
||||||
...formSchema,
|
{
|
||||||
fileName: 'demoFile1',
|
...formSchema,
|
||||||
},
|
fileName: 'demoFile1',
|
||||||
{
|
},
|
||||||
...formSchema,
|
{
|
||||||
fileName: 'demoFile2',
|
...formSchema,
|
||||||
}
|
fileName: 'demoFile2',
|
||||||
],
|
},
|
||||||
}, 'demoFile2');
|
],
|
||||||
|
},
|
||||||
|
'demoFile2',
|
||||||
|
);
|
||||||
const { currentDocument } = project;
|
const { currentDocument } = project;
|
||||||
expect(currentDocument.fileName).toBe('demoFile2');
|
expect(currentDocument.fileName).toBe('demoFile2');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('setSchema works', () => {
|
it('setSchema works', () => {
|
||||||
const project = new Project(designer);
|
const project = new Project(designer);
|
||||||
project.open();
|
project.open();
|
||||||
|
@ -204,13 +211,15 @@ describe('schema 生成节点模型测试', () => {
|
||||||
const ids = getIdsFromSchema(formSchema);
|
const ids = getIdsFromSchema(formSchema);
|
||||||
const expectedNodeCnt = ids.length;
|
const expectedNodeCnt = ids.length;
|
||||||
expect(nodesMap.size).toBe(expectedNodeCnt);
|
expect(nodesMap.size).toBe(expectedNodeCnt);
|
||||||
ids.forEach(id => {
|
ids.forEach((id) => {
|
||||||
expect(nodesMap.get(id).componentName).toBe(getNodeFromSchemaById(formSchema, id).componentName);
|
expect(nodesMap.get(id).componentName).toBe(
|
||||||
|
getNodeFromSchemaById(formSchema, id).componentName,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const exportSchema = currentDocument?.export(1);
|
const exportSchema = currentDocument?.export(1);
|
||||||
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
expect(getIdsFromSchema(exportSchema).length).toBe(expectedNodeCnt);
|
||||||
nodesMap.forEach(node => {
|
nodesMap.forEach((node) => {
|
||||||
// 触发 getter
|
// 触发 getter
|
||||||
node.settingEntry;
|
node.settingEntry;
|
||||||
});
|
});
|
||||||
|
@ -271,11 +280,13 @@ describe('schema 生成节点模型测试', () => {
|
||||||
|
|
||||||
describe('block ❌ | component ❌ | slot ✅', () => {
|
describe('block ❌ | component ❌ | slot ✅', () => {
|
||||||
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
it('基本的节点模型初始化,模型导出,初始化传入 schema', () => {
|
||||||
const formSchemaWithSlot = set(cloneDeep(formSchema), 'children[0].children[0].props.title.type', 'JSSlot');
|
const formSchemaWithSlot = set(
|
||||||
|
cloneDeep(formSchema),
|
||||||
|
'children[0].children[0].props.title.type',
|
||||||
|
'JSSlot',
|
||||||
|
);
|
||||||
const project = new Project(designer, {
|
const project = new Project(designer, {
|
||||||
componentsTree: [
|
componentsTree: [formSchemaWithSlot],
|
||||||
formSchemaWithSlot,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
project.open();
|
project.open();
|
||||||
expect(project).toBeTruthy();
|
expect(project).toBeTruthy();
|
||||||
|
@ -290,7 +301,5 @@ describe('schema 生成节点模型测试', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe.skip('多 document 测试', () => {
|
describe.skip('多 document 测试', () => {});
|
||||||
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import lodashSet from 'lodash/set';
|
import { set as lodashSet } from 'lodash-es';
|
||||||
|
|
||||||
export function set(obj: any, path: any, val: any) {
|
export function set(obj: any, path: any, val: any) {
|
||||||
if (typeof path === 'string' && path.startsWith('prototype')) {
|
if (typeof path === 'string' && path.startsWith('prototype')) {
|
||||||
|
@ -17,7 +17,7 @@ export function set(obj: any, path: any, val: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function delay(ms) {
|
export function delay(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function delayObxTick() {
|
export function delayObxTick() {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "temp",
|
||||||
|
"stripInternal": true,
|
||||||
|
"paths": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,7 @@
|
||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "lib",
|
"outDir": "dist"
|
||||||
"types": ["node","jest"]
|
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src"]
|
||||||
"./src/",
|
|
||||||
"./tests/"
|
|
||||||
],
|
|
||||||
"exclude": ["**/lib", "**/es", "node_modules"]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { devDependencies, peerDependencies } from './package.json';
|
||||||
|
|
||||||
|
const externals = [...Object.keys(peerDependencies), ...Object.keys(devDependencies)];
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
// Could also be a dictionary or array of multiple entry points
|
||||||
|
entry: resolve(import.meta.dirname, 'src/index.ts'),
|
||||||
|
name: 'LowCodeDesigner',
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
// the proper extensions will be added
|
||||||
|
fileName: 'designer',
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: externals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
|
@ -3,18 +3,30 @@
|
||||||
"version": "2.0.0-beta.0",
|
"version": "2.0.0-beta.0",
|
||||||
"description": "Core Api for Ali lowCode engine",
|
"description": "Core Api for Ali lowCode engine",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "dist/index.js",
|
|
||||||
"module": "dist/index.js",
|
|
||||||
"types": "dist/index.d.ts",
|
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"main": "dist/editorCore.js",
|
||||||
|
"module": "dist/editorCore.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/editorCore.js",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sideEffects": [
|
||||||
|
"*.css",
|
||||||
|
"*.less"
|
||||||
|
],
|
||||||
"files": [
|
"files": [
|
||||||
"lib",
|
"dist",
|
||||||
"es"
|
"src",
|
||||||
|
"package.json"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "vite build",
|
||||||
"test": "build-scripts test --config build.test.json",
|
"build-dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs",
|
||||||
"test:cov": "build-scripts test --config build.test.json --jest-coverage"
|
"test": "vitest",
|
||||||
|
"test:cov": ""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alifd/next": "^1.27.8",
|
"@alifd/next": "^1.27.8",
|
||||||
|
@ -29,16 +41,18 @@
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"store": "^2.0.12",
|
"store": "^2.0.12",
|
||||||
"strict-event-emitter-types": "^2.0.0"
|
"strict-event-emitter-types": "^2.0.0",
|
||||||
|
"events": "^3.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alilc/lowcode-datasource-types": "^1.0.1",
|
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/react": "^18.2.0",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react-dom": "^18.2.0",
|
"@types/react-dom": "^18.2.0",
|
||||||
"@types/store": "^2.0.2"
|
"@types/store": "^2.0.2",
|
||||||
|
"less": "^4.2.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"@alifd/next": "^1.27.8",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/* eslint-disable no-console */
|
|
||||||
/* eslint-disable max-len */
|
|
||||||
import { StrictEventEmitter } from 'strict-event-emitter-types';
|
import { StrictEventEmitter } from 'strict-event-emitter-types';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { EventBus, IEventBus } from './event-bus';
|
import { EventBus, IEventBus } from './event-bus';
|
||||||
|
@ -39,6 +37,7 @@ const AssetsCache: {
|
||||||
[key: string]: IPublicTypeRemoteComponentDescription;
|
[key: string]: IPublicTypeRemoteComponentDescription;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalEvent.EventConfig> {
|
export declare interface Editor extends StrictEventEmitter<EventEmitter, GlobalEvent.EventConfig> {
|
||||||
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||||
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { configure } from 'mobx';
|
import { configure } from 'mobx';
|
||||||
|
import * as mobx from 'mobx';
|
||||||
|
|
||||||
configure({ enforceActions: 'never' });
|
configure({ enforceActions: 'never' });
|
||||||
|
|
||||||
|
@ -19,5 +20,4 @@ export {
|
||||||
} from 'mobx';
|
} from 'mobx';
|
||||||
export type { IReactionDisposer, IReactionPublic, IReactionOptions } from 'mobx';
|
export type { IReactionDisposer, IReactionPublic, IReactionOptions } from 'mobx';
|
||||||
|
|
||||||
export * as mobx from 'mobx';
|
export { observer, mobx };
|
||||||
export { observer };
|
|
||||||
|
|
|
@ -106,7 +106,11 @@ export class TipItem extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const tip: IPublicTypeTipConfig = tipHandler.tip || ({} as any);
|
const tip: IPublicTypeTipConfig = tipHandler.tip || ({} as any);
|
||||||
const className = classNames('lc-tip', tip.className, tip && tip.theme ? `lc-theme-${tip.theme}` : null);
|
const className = classNames(
|
||||||
|
'lc-tip',
|
||||||
|
tip.className,
|
||||||
|
tip && tip.theme ? `lc-theme-${tip.theme}` : null,
|
||||||
|
);
|
||||||
|
|
||||||
this.originClassName = className;
|
this.originClassName = className;
|
||||||
|
|
||||||
|
@ -118,7 +122,7 @@ export class TipItem extends Component {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i className="lc-arrow" />
|
<i className="lc-arrow" />
|
||||||
<div className="lc-tip-content">{intl(tip.children)}</div>
|
<div className="lc-tip-content">{intl((tip as any).children)}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "temp",
|
||||||
|
"stripInternal": true,
|
||||||
|
"paths": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "dist",
|
"outDir": "dist"
|
||||||
"paths": {
|
|
||||||
"@alilc/lowcode-*": ["packages/*"]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { devDependencies, peerDependencies } from './package.json';
|
||||||
|
|
||||||
|
const externals = [...Object.keys(peerDependencies), ...Object.keys(devDependencies)];
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
// Could also be a dictionary or array of multiple entry points
|
||||||
|
entry: resolve(import.meta.dirname, 'src/index.ts'),
|
||||||
|
name: 'LowCodeEditorCore',
|
||||||
|
formats: ['es'],
|
||||||
|
// the proper extensions will be added
|
||||||
|
fileName: 'editorCore',
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: externals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
"build-plugin-fusion",
|
|
||||||
["build-plugin-moment-locales", {
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}]
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
|
||||||
],
|
|
||||||
"babelPlugins": [
|
|
||||||
["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
const { join } = require('path');
|
|
||||||
const esModules = [].join('|');
|
|
||||||
const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.'));
|
|
||||||
|
|
||||||
const jestConfig = {
|
|
||||||
// transform: {
|
|
||||||
// '^.+\\.[jt]sx?$': 'babel-jest',
|
|
||||||
// // '^.+\\.(ts|tsx)$': 'ts-jest',
|
|
||||||
// // '^.+\\.(js|jsx)$': 'babel-jest',
|
|
||||||
// },
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
`/node_modules/(?!${esModules})/`,
|
|
||||||
],
|
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
|
||||||
collectCoverage: false,
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src/**/*.ts',
|
|
||||||
'!src/**/*.d.ts',
|
|
||||||
'!**/node_modules/**',
|
|
||||||
'!**/vendor/**',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 只对本仓库内的 pkg 做 mapping
|
|
||||||
jestConfig.moduleNameMapper = {};
|
|
||||||
jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '<rootDir>/../$1/src';
|
|
||||||
|
|
||||||
module.exports = jestConfig;
|
|
|
@ -1,38 +1,55 @@
|
||||||
{
|
{
|
||||||
"name": "@alilc/lowcode-editor-skeleton",
|
"name": "@alilc/lowcode-editor-skeleton",
|
||||||
"version": "1.3.2",
|
"version": "2.0.0-beta.0",
|
||||||
"description": "alibaba lowcode editor skeleton",
|
"description": "alibaba lowcode editor skeleton",
|
||||||
"main": "lib/index.js",
|
"type": "module",
|
||||||
"module": "es/index.js",
|
"main": "dist/designer.cjs",
|
||||||
"stylePath": "style.js",
|
"module": "dist/designer.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/designer.js",
|
||||||
|
"require": "./dist/designer.cjs",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sideEffects": [
|
||||||
|
"*.css"
|
||||||
|
],
|
||||||
"files": [
|
"files": [
|
||||||
"lib",
|
"dist",
|
||||||
"es"
|
"src",
|
||||||
|
"package.json"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "build-scripts test --config build.test.json",
|
"build": "vite build",
|
||||||
"build": "build-scripts build"
|
"build-dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs",
|
||||||
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"lowcode",
|
"lowcode",
|
||||||
"editor"
|
"editor"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alifd/next": "^1.20.12",
|
"@alifd/next": "^1.27.8",
|
||||||
"@alilc/lowcode-designer": "1.3.2",
|
"@alilc/lowcode-designer": "workspace:*",
|
||||||
"@alilc/lowcode-editor-core": "1.3.2",
|
"@alilc/lowcode-editor-core": "workspace:*",
|
||||||
"@alilc/lowcode-types": "1.3.2",
|
"@alilc/lowcode-types": "workspace:*",
|
||||||
"@alilc/lowcode-utils": "1.3.2",
|
"@alilc/lowcode-utils": "workspace:*",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"react": "^16.8.1",
|
"lodash-es": "^4.17.21",
|
||||||
"react-dom": "^16.8.1"
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.3",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/react": "^16.9.13",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react-dom": "^16.9.4",
|
"@types/react-dom": "^18.2.0"
|
||||||
"build-plugin-fusion": "^0.1.0",
|
},
|
||||||
"build-plugin-moment-locales": "^0.1.0"
|
"peerDependencies": {
|
||||||
|
"@alifd/next": "^1.27.8",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable react/no-unused-prop-types */
|
import { Component, ErrorInfo, MouseEvent, type ReactNode } from 'react';
|
||||||
import { Component, ErrorInfo, MouseEvent } from 'react';
|
import { isObject } from 'lodash-es';
|
||||||
import { isObject } from 'lodash';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Icon } from '@alifd/next';
|
import { Icon } from '@alifd/next';
|
||||||
import { Title } from '@alilc/lowcode-editor-core';
|
import { Title } from '@alilc/lowcode-editor-core';
|
||||||
|
@ -25,6 +24,7 @@ export interface FieldProps {
|
||||||
tip?: any;
|
tip?: any;
|
||||||
onExpandChange?: (expandState: boolean) => void;
|
onExpandChange?: (expandState: boolean) => void;
|
||||||
onClear?: () => void;
|
onClear?: () => void;
|
||||||
|
children?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Field extends Component<FieldProps> {
|
export class Field extends Component<FieldProps> {
|
||||||
|
@ -116,22 +116,37 @@ export class Field extends Component<FieldProps> {
|
||||||
getTipContent(propName: string, tip?: any): any {
|
getTipContent(propName: string, tip?: any): any {
|
||||||
let tipContent = (
|
let tipContent = (
|
||||||
<div>
|
<div>
|
||||||
<div>{intl('Attribute: ')}{propName}</div>
|
<div>
|
||||||
|
{intl('Attribute: ')}
|
||||||
|
{propName}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isObject(tip)) {
|
if (isObject(tip)) {
|
||||||
tipContent = (
|
tipContent = (
|
||||||
<div>
|
<div>
|
||||||
<div>{intl('Attribute: ')}{propName}</div>
|
<div>
|
||||||
<div>{intl('Description: ')}{(tip as any).content}</div>
|
{intl('Attribute: ')}
|
||||||
|
{propName}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{intl('Description: ')}
|
||||||
|
{(tip as any).content}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (tip) {
|
} else if (tip) {
|
||||||
tipContent = (
|
tipContent = (
|
||||||
<div>
|
<div>
|
||||||
<div>{intl('Attribute: ')}{propName}</div>
|
<div>
|
||||||
<div>{intl('Description: ')}{tip}</div>
|
{intl('Attribute: ')}
|
||||||
|
{propName}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{intl('Description: ')}
|
||||||
|
{tip}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +164,7 @@ export class Field extends Component<FieldProps> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { className, children, meta, title, valueState, name: propName, tip } = this.props;
|
const { className, children, meta, title, name: propName, tip } = this.props;
|
||||||
const { display, collapsed } = this.state;
|
const { display, collapsed } = this.state;
|
||||||
const isAccordion = display === 'accordion';
|
const isAccordion = display === 'accordion';
|
||||||
let hostName = '';
|
let hostName = '';
|
||||||
|
@ -167,22 +182,23 @@ export class Field extends Component<FieldProps> {
|
||||||
})}
|
})}
|
||||||
id={id}
|
id={id}
|
||||||
>
|
>
|
||||||
{
|
{display !== 'plain' && (
|
||||||
display !== 'plain' && (
|
<div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}>
|
||||||
<div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}>
|
<div className="lc-field-title">
|
||||||
<div className="lc-field-title">
|
{createValueState()}
|
||||||
{createValueState(valueState, this.handleClear)}
|
<Title title={title || ''} onClick={this.clickHandler} />
|
||||||
<Title
|
<InlineTip position="top">{tipContent}</InlineTip>
|
||||||
title={title || ''}
|
|
||||||
onClick={this.clickHandler}
|
|
||||||
/>
|
|
||||||
<InlineTip position="top">{tipContent}</InlineTip>
|
|
||||||
</div>
|
|
||||||
{isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
{isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />}
|
||||||
}
|
</div>
|
||||||
<div key="body" ref={(shell) => { this.body = shell; }} className="lc-field-body">
|
)}
|
||||||
|
<div
|
||||||
|
key="body"
|
||||||
|
ref={(shell) => {
|
||||||
|
this.body = shell;
|
||||||
|
}}
|
||||||
|
className="lc-field-body"
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,18 +8,17 @@ export interface PopupExtProps {
|
||||||
width?: number;
|
width?: number;
|
||||||
hasMask?: boolean;
|
hasMask?: boolean;
|
||||||
trigger?: ReactNode;
|
trigger?: ReactNode;
|
||||||
canCloseByOutSideClick?: boolean
|
canCloseByOutSideClick?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
safeNode?: string[];
|
safeNode?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PopupProps extends PopupExtProps{
|
interface PopupProps extends PopupExtProps {
|
||||||
content?: ReactNode,
|
content?: ReactNode;
|
||||||
title?: ReactNode,
|
title?: ReactNode;
|
||||||
actionKey?: string
|
actionKey?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const PopupContext = createContext<PopupPipe>({} as any);
|
export const PopupContext = createContext<PopupPipe>({} as any);
|
||||||
|
|
||||||
export class PopupPipe {
|
export class PopupPipe {
|
||||||
|
@ -84,6 +83,7 @@ export default class PopupService extends Component<{
|
||||||
actionKey?: string;
|
actionKey?: string;
|
||||||
safeId?: string;
|
safeId?: string;
|
||||||
popupContainer?: string;
|
popupContainer?: string;
|
||||||
|
children?: ReactNode;
|
||||||
}> {
|
}> {
|
||||||
private popupPipe = this.props.popupPipe || new PopupPipe();
|
private popupPipe = this.props.popupPipe || new PopupPipe();
|
||||||
|
|
||||||
|
@ -103,9 +103,9 @@ export default class PopupService extends Component<{
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StateType extends PopupProps {
|
interface StateType extends PopupProps {
|
||||||
visible?: boolean,
|
visible?: boolean;
|
||||||
offsetX?: number,
|
offsetX?: number;
|
||||||
pos?: {top: number, height: number}
|
pos?: { top: number; height: number };
|
||||||
}
|
}
|
||||||
export class PopupContent extends PureComponent<{ safeId?: string; popupContainer?: string }> {
|
export class PopupContent extends PureComponent<{ safeId?: string; popupContainer?: string }> {
|
||||||
static contextType = PopupContext;
|
static contextType = PopupContext;
|
||||||
|
@ -153,7 +153,18 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { content, visible, title, actionKey, pos, offsetX, width = 360, hasMask = false, canCloseByOutSideClick = true, safeNode = [] } = this.state;
|
const {
|
||||||
|
content,
|
||||||
|
visible,
|
||||||
|
title,
|
||||||
|
actionKey,
|
||||||
|
pos,
|
||||||
|
offsetX,
|
||||||
|
width = 360,
|
||||||
|
hasMask = false,
|
||||||
|
canCloseByOutSideClick = true,
|
||||||
|
safeNode = [],
|
||||||
|
} = this.state;
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +182,7 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||||
visible={visible}
|
visible={visible}
|
||||||
offset={[offsetX, 0]}
|
offset={[offsetX, 0]}
|
||||||
hasMask={hasMask}
|
hasMask={hasMask}
|
||||||
onVisibleChange={(_visible, type) => {
|
onVisibleChange={(_visible: boolean, type: string) => {
|
||||||
if (avoidLaterHidden) {
|
if (avoidLaterHidden) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -186,15 +197,12 @@ export class PopupContent extends PureComponent<{ safeId?: string; popupContaine
|
||||||
onClose={this.onClose}
|
onClose={this.onClose}
|
||||||
id={this.props.safeId}
|
id={this.props.safeId}
|
||||||
safeNode={[id, ...safeNode]}
|
safeNode={[id, ...safeNode]}
|
||||||
closeable
|
|
||||||
container={this.props.popupContainer}
|
container={this.props.popupContainer}
|
||||||
>
|
>
|
||||||
<div className="lc-ballon-title">{title}</div>
|
<div className="lc-ballon-title">{title}</div>
|
||||||
<div className="lc-ballon-content">
|
<div className="lc-ballon-content">
|
||||||
<PopupService actionKey={actionKey} safeId={id} popupContainer={this.popupContainerId}>
|
<PopupService actionKey={actionKey} safeId={id} popupContainer={this.popupContainerId}>
|
||||||
<ConfigProvider popupContainer={this.popupContainerId}>
|
<ConfigProvider popupContainer={this.popupContainerId}>{content}</ConfigProvider>
|
||||||
{content}
|
|
||||||
</ConfigProvider>
|
|
||||||
</PopupService>
|
</PopupService>
|
||||||
</div>
|
</div>
|
||||||
<div id={this.popupContainerId} />
|
<div id={this.popupContainerId} />
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import { Node, Designer, Selection, SettingTopEntry } from '@alilc/lowcode-designer';
|
import { Node, Designer, Selection, SettingTopEntry } from '@alilc/lowcode-designer';
|
||||||
import { Editor, obx, computed, makeObservable, action, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import {
|
||||||
|
Editor,
|
||||||
|
obx,
|
||||||
|
computed,
|
||||||
|
makeObservable,
|
||||||
|
action,
|
||||||
|
IEventBus,
|
||||||
|
createModuleEventBus,
|
||||||
|
} from '@alilc/lowcode-editor-core';
|
||||||
|
|
||||||
function generateSessionId(nodes: Node[]) {
|
function generateSessionId(nodes: Node[]) {
|
||||||
return nodes
|
return nodes
|
||||||
|
@ -72,9 +80,9 @@ export class SettingsMain {
|
||||||
// 当节点只有一个时,复用 node 上挂载的 settingEntry,不会产生平行的两个实例,这样在整个系统中对
|
// 当节点只有一个时,复用 node 上挂载的 settingEntry,不会产生平行的两个实例,这样在整个系统中对
|
||||||
// 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例
|
// 某个节点操作的 SettingTopEntry 只有一个实例,后续的 getProp() 也会拿到相同的 SettingField 实例
|
||||||
if (nodes.length === 1) {
|
if (nodes.length === 1) {
|
||||||
this._settings = nodes[0].settingEntry;
|
this._settings = nodes[0].settingEntry as any;
|
||||||
} else {
|
} else {
|
||||||
this._settings = this.designer.createSettingEntry(nodes);
|
this._settings = this.designer.createSettingEntry(nodes) as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,25 @@
|
||||||
import { Component, MouseEvent, Fragment, ReactNode } from 'react';
|
import { Component, MouseEvent, Fragment, ReactNode } from 'react';
|
||||||
import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core';
|
import { shallowIntl, observer, obx, engineConfig, runInAction } from '@alilc/lowcode-editor-core';
|
||||||
import { createContent, isJSSlot, isSetterConfig, shouldUseVariableSetter } from '@alilc/lowcode-utils';
|
import {
|
||||||
import { Skeleton, Stage } from '@alilc/lowcode-editor-skeleton';
|
createContent,
|
||||||
import { IPublicApiSetters, IPublicTypeCustomView, IPublicTypeDynamicProps } from '@alilc/lowcode-types';
|
isJSSlot,
|
||||||
import { ISettingEntry, IComponentMeta, ISettingField, isSettingField, ISettingTopEntry } from '@alilc/lowcode-designer';
|
isSetterConfig,
|
||||||
|
shouldUseVariableSetter,
|
||||||
|
} from '@alilc/lowcode-utils';
|
||||||
|
import { Skeleton } from '../../skeleton';
|
||||||
|
import { Stage } from '../../widget/stage';
|
||||||
|
import {
|
||||||
|
IPublicApiSetters,
|
||||||
|
IPublicTypeCustomView,
|
||||||
|
IPublicTypeDynamicProps,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
|
import {
|
||||||
|
ISettingEntry,
|
||||||
|
IComponentMeta,
|
||||||
|
ISettingField,
|
||||||
|
isSettingField,
|
||||||
|
ISettingTopEntry,
|
||||||
|
} from '@alilc/lowcode-designer';
|
||||||
import { createField } from '../field';
|
import { createField } from '../field';
|
||||||
import PopupService, { PopupPipe } from '../popup';
|
import PopupService, { PopupPipe } from '../popup';
|
||||||
import { SkeletonContext } from '../../context';
|
import { SkeletonContext } from '../../context';
|
||||||
|
@ -24,10 +40,14 @@ function isStandardComponent(componentMeta: IComponentMeta | null) {
|
||||||
*/
|
*/
|
||||||
function isInitialValueNotEmpty(initialValue: any) {
|
function isInitialValueNotEmpty(initialValue: any) {
|
||||||
if (isJSSlot(initialValue)) {
|
if (isJSSlot(initialValue)) {
|
||||||
// @ts-ignore visible 为 false 代表默认不展示
|
return (
|
||||||
return initialValue.visible !== false && Array.isArray(initialValue.value) && initialValue.value.length > 0;
|
// @ts-ignore visible 为 false 代表默认不展示
|
||||||
|
initialValue.visible !== false &&
|
||||||
|
Array.isArray(initialValue.value) &&
|
||||||
|
initialValue.value.length > 0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (initialValue !== undefined && initialValue !== null);
|
return initialValue !== undefined && initialValue !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
type SettingFieldViewProps = { field: ISettingField };
|
type SettingFieldViewProps = { field: ISettingField };
|
||||||
|
@ -61,7 +81,11 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
stages.add({
|
stages.add({
|
||||||
type: 'Widget',
|
type: 'Widget',
|
||||||
name: stageName,
|
name: stageName,
|
||||||
content: <Fragment>{field.items.map((item, index) => createSettingFieldView(item, field, index))}</Fragment>,
|
content: (
|
||||||
|
<Fragment>
|
||||||
|
{field.items.map((item, index) => createSettingFieldView(item, field, index))}
|
||||||
|
</Fragment>
|
||||||
|
),
|
||||||
props: {
|
props: {
|
||||||
title: field.title,
|
title: field.title,
|
||||||
},
|
},
|
||||||
|
@ -79,7 +103,9 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
const { extraProps } = this.field;
|
const { extraProps } = this.field;
|
||||||
const { condition } = extraProps;
|
const { condition } = extraProps;
|
||||||
try {
|
try {
|
||||||
return typeof condition === 'function' ? condition(this.field.internalToShellField()) !== false : true;
|
return typeof condition === 'function'
|
||||||
|
? condition(this.field.internalToShellField()) !== false
|
||||||
|
: true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('exception when condition (hidden) is excuted', error);
|
console.error('exception when condition (hidden) is excuted', error);
|
||||||
}
|
}
|
||||||
|
@ -111,16 +137,18 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
const { defaultValue } = extraProps;
|
const { defaultValue } = extraProps;
|
||||||
|
|
||||||
const { setter } = this.field;
|
const { setter } = this.field;
|
||||||
let setterProps: {
|
let setterProps:
|
||||||
setters?: (ReactNode | string)[];
|
| ({
|
||||||
} & Record<string, unknown> | IPublicTypeDynamicProps = {};
|
setters?: (ReactNode | string)[];
|
||||||
|
} & Record<string, unknown>)
|
||||||
|
| IPublicTypeDynamicProps = {};
|
||||||
let setterType: any;
|
let setterType: any;
|
||||||
let initialValue: any = null;
|
let initialValue: any = null;
|
||||||
|
|
||||||
if (Array.isArray(setter)) {
|
if (Array.isArray(setter)) {
|
||||||
setterType = 'MixedSetter';
|
setterType = 'MixedSetter';
|
||||||
setterProps = {
|
setterProps = {
|
||||||
setters: setter,
|
setters: setter as any,
|
||||||
};
|
};
|
||||||
} else if (isSetterConfig(setter)) {
|
} else if (isSetterConfig(setter)) {
|
||||||
setterType = setter.componentName;
|
setterType = setter.componentName;
|
||||||
|
@ -154,7 +182,8 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
// 根据是否支持变量配置做相应的更改
|
// 根据是否支持变量配置做相应的更改
|
||||||
const supportVariable = this.field.extraProps?.supportVariable;
|
const supportVariable = this.field.extraProps?.supportVariable;
|
||||||
// supportVariableGlobally 只对标准组件生效,vc 需要单独配置
|
// supportVariableGlobally 只对标准组件生效,vc 需要单独配置
|
||||||
const supportVariableGlobally = engineConfig.get('supportVariableGlobally', false) && isStandardComponent(componentMeta);
|
const supportVariableGlobally =
|
||||||
|
engineConfig.get('supportVariableGlobally', false) && isStandardComponent(componentMeta);
|
||||||
const isUseVariableSetter = shouldUseVariableSetter(supportVariable, supportVariableGlobally);
|
const isUseVariableSetter = shouldUseVariableSetter(supportVariable, supportVariableGlobally);
|
||||||
if (isUseVariableSetter === false) {
|
if (isUseVariableSetter === false) {
|
||||||
return {
|
return {
|
||||||
|
@ -172,10 +201,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
} else {
|
} else {
|
||||||
setterType = 'MixedSetter';
|
setterType = 'MixedSetter';
|
||||||
setterProps = {
|
setterProps = {
|
||||||
setters: [
|
setters: [setter as any, 'VariableSetter'],
|
||||||
setter,
|
|
||||||
'VariableSetter',
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
@ -191,7 +217,8 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
|
|
||||||
initDefaultValue() {
|
initDefaultValue() {
|
||||||
const { initialValue } = this.setterInfo;
|
const { initialValue } = this.setterInfo;
|
||||||
if (this.state?.fromOnChange ||
|
if (
|
||||||
|
this.state?.fromOnChange ||
|
||||||
!isInitialValueNotEmpty(initialValue) ||
|
!isInitialValueNotEmpty(initialValue) ||
|
||||||
this.ignoreDefaultValue ||
|
this.ignoreDefaultValue ||
|
||||||
this.value !== undefined
|
this.value !== undefined
|
||||||
|
@ -200,7 +227,10 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
}
|
}
|
||||||
// 当前 field 没有 value 值时,将 initialValue 写入 field
|
// 当前 field 没有 value 值时,将 initialValue 写入 field
|
||||||
// 之所以用 initialValue,而不是 defaultValue 是为了保持跟 props.onInitial 的逻辑一致
|
// 之所以用 initialValue,而不是 defaultValue 是为了保持跟 props.onInitial 的逻辑一致
|
||||||
const _initialValue = typeof initialValue === 'function' ? initialValue(this.field.internalToShellField()) : initialValue;
|
const _initialValue =
|
||||||
|
typeof initialValue === 'function'
|
||||||
|
? initialValue(this.field.internalToShellField())
|
||||||
|
: initialValue;
|
||||||
this.field.setValue(_initialValue);
|
this.field.setValue(_initialValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,11 +247,7 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { setterProps = {}, setterType, initialValue = null } = this.setterInfo;
|
||||||
setterProps = {},
|
|
||||||
setterType,
|
|
||||||
initialValue = null,
|
|
||||||
} = this.setterInfo;
|
|
||||||
|
|
||||||
const value = this.value;
|
const value = this.value;
|
||||||
|
|
||||||
|
@ -243,44 +269,47 @@ class SettingFieldView extends Component<SettingFieldViewProps, SettingFieldView
|
||||||
...extraProps,
|
...extraProps,
|
||||||
},
|
},
|
||||||
!stageName &&
|
!stageName &&
|
||||||
this.setters?.createSetterContent(setterType, {
|
this.setters?.createSetterContent(setterType, {
|
||||||
...shallowIntl(setterProps),
|
...shallowIntl(setterProps),
|
||||||
forceInline: extraProps.forceInline,
|
forceInline: extraProps.forceInline,
|
||||||
key: field.id,
|
key: field.id,
|
||||||
// === injection
|
// === injection
|
||||||
prop: field.internalToShellField(), // for compatible vision
|
prop: field.internalToShellField(), // for compatible vision
|
||||||
selected: field.top?.getNode()?.internalToShellNode(),
|
selected: field.top?.getNode()?.internalToShellNode(),
|
||||||
field: field.internalToShellField(),
|
field: field.internalToShellField(),
|
||||||
// === IO
|
// === IO
|
||||||
value, // reaction point
|
value, // reaction point
|
||||||
initialValue,
|
initialValue,
|
||||||
onChange: (value: any) => {
|
onChange: (value: any) => {
|
||||||
this.setState({
|
this.setState({
|
||||||
fromOnChange: true,
|
fromOnChange: true,
|
||||||
// eslint-disable-next-line react/no-unused-state
|
// eslint-disable-next-line react/no-unused-state
|
||||||
value,
|
value,
|
||||||
});
|
});
|
||||||
field.setValue(value, true);
|
field.setValue(value, true);
|
||||||
if (onChangeAPI) onChangeAPI(value, field.internalToShellField());
|
if (onChangeAPI) onChangeAPI(value, field.internalToShellField());
|
||||||
},
|
},
|
||||||
onInitial: () => {
|
onInitial: () => {
|
||||||
if (initialValue == null) {
|
if (initialValue == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const value = typeof initialValue === 'function' ? initialValue(field.internalToShellField()) : initialValue;
|
const value =
|
||||||
this.setState({
|
typeof initialValue === 'function'
|
||||||
// eslint-disable-next-line react/no-unused-state
|
? initialValue(field.internalToShellField())
|
||||||
value,
|
: initialValue;
|
||||||
});
|
this.setState({
|
||||||
field.setValue(value, true);
|
// eslint-disable-next-line react/no-unused-state
|
||||||
},
|
value,
|
||||||
|
});
|
||||||
|
field.setValue(value, true);
|
||||||
|
},
|
||||||
|
|
||||||
removeProp: () => {
|
removeProp: () => {
|
||||||
if (field.name) {
|
if (field.name) {
|
||||||
field.parent.clearPropValue(field.name);
|
field.parent.clearPropValue(field.name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
extraProps.forceInline ? 'plain' : extraProps.display,
|
extraProps.forceInline ? 'plain' : extraProps.display,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -311,7 +340,11 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
|
||||||
stages.add({
|
stages.add({
|
||||||
type: 'Widget',
|
type: 'Widget',
|
||||||
name: stageName,
|
name: stageName,
|
||||||
content: <Fragment>{field.items.map((item, index) => createSettingFieldView(item, field, index))}</Fragment>,
|
content: (
|
||||||
|
<Fragment>
|
||||||
|
{field.items.map((item, index) => createSettingFieldView(item, field, index))}
|
||||||
|
</Fragment>
|
||||||
|
),
|
||||||
props: {
|
props: {
|
||||||
title: field.title,
|
title: field.title,
|
||||||
},
|
},
|
||||||
|
@ -325,7 +358,10 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
|
||||||
const { field } = this.props;
|
const { field } = this.props;
|
||||||
const { extraProps } = field;
|
const { extraProps } = field;
|
||||||
const { condition, display } = extraProps;
|
const { condition, display } = extraProps;
|
||||||
const visible = field.isSingle && typeof condition === 'function' ? condition(field.internalToShellField()) !== false : true;
|
const visible =
|
||||||
|
field.isSingle && typeof condition === 'function'
|
||||||
|
? condition(field.internalToShellField()) !== false
|
||||||
|
: true;
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -349,7 +385,11 @@ class SettingGroupView extends Component<SettingGroupViewProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSettingFieldView(field: ISettingField | IPublicTypeCustomView, fieldEntry: ISettingEntry, index?: number) {
|
export function createSettingFieldView(
|
||||||
|
field: ISettingField | IPublicTypeCustomView,
|
||||||
|
fieldEntry: ISettingEntry,
|
||||||
|
index?: number,
|
||||||
|
) {
|
||||||
if (isSettingField(field)) {
|
if (isSettingField(field)) {
|
||||||
if (field.isGroup) {
|
if (field.isGroup) {
|
||||||
return <SettingGroupView field={field} key={field.id} />;
|
return <SettingGroupView field={field} key={field.id} />;
|
||||||
|
@ -411,10 +451,6 @@ export class SettingsPane extends Component<SettingsPaneProps> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private popStage() {
|
|
||||||
this.currentStage = this.currentStage?.getPrevious();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { target } = this.props;
|
const { target } = this.props;
|
||||||
const { items } = target;
|
const { items } = target;
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { Tab, Breadcrumb } from '@alifd/next';
|
import { Tab, Breadcrumb } from '@alifd/next';
|
||||||
import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core';
|
import {
|
||||||
|
Title,
|
||||||
|
observer,
|
||||||
|
Editor,
|
||||||
|
obx,
|
||||||
|
globalContext,
|
||||||
|
engineConfig,
|
||||||
|
makeObservable,
|
||||||
|
} from '@alilc/lowcode-editor-core';
|
||||||
import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer';
|
import { Node, SettingField, isSettingField, INode } from '@alilc/lowcode-designer';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { SettingsMain } from './main';
|
import { SettingsMain } from './main';
|
||||||
|
@ -16,7 +24,10 @@ interface ISettingsPrimaryPaneProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, { shouldIgnoreRoot: boolean }> {
|
export class SettingsPrimaryPane extends Component<
|
||||||
|
ISettingsPrimaryPaneProps,
|
||||||
|
{ shouldIgnoreRoot: boolean }
|
||||||
|
> {
|
||||||
state = {
|
state = {
|
||||||
shouldIgnoreRoot: false,
|
shouldIgnoreRoot: false,
|
||||||
};
|
};
|
||||||
|
@ -93,27 +104,29 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||||
l === 2
|
l === 2
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
onMouseOver: hoverNode.bind(null, _node, true),
|
onMouseOver: hoverNode.bind(null, _node, true),
|
||||||
onMouseOut: hoverNode.bind(null, _node, false),
|
onMouseOut: hoverNode.bind(null, _node, false),
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (!_node) {
|
if (!_node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
selectNode.call(null, _node);
|
selectNode.call(null, _node);
|
||||||
const getName = (node: any) => {
|
const getName = (node: any) => {
|
||||||
const npm = node?.componentMeta?.npm;
|
const npm = node?.componentMeta?.npm;
|
||||||
return [npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
return (
|
||||||
node?.componentMeta?.componentName ||
|
[npm?.package, npm?.componentName].filter((item) => !!item).join('-') ||
|
||||||
'';
|
node?.componentMeta?.componentName ||
|
||||||
};
|
''
|
||||||
const selected = getName(current);
|
);
|
||||||
const target = getName(_node);
|
};
|
||||||
editor?.eventBus.emit('skeleton.settingsPane.Breadcrumb', {
|
const selected = getName(current);
|
||||||
selected,
|
const target = getName(_node);
|
||||||
target,
|
editor?.eventBus.emit('skeleton.settingsPane.Breadcrumb', {
|
||||||
});
|
selected,
|
||||||
},
|
target,
|
||||||
};
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
items.unshift(
|
items.unshift(
|
||||||
<Breadcrumb.Item {...props} key={node.id}>
|
<Breadcrumb.Item {...props} key={node.id}>
|
||||||
<Title title={node.title} />
|
<Title title={node.title} />
|
||||||
|
@ -179,7 +192,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { items } = settings;
|
const { items } = settings;
|
||||||
if (items.length > 5 || items.some((item) => !isSettingField(item) || !item.isGroup)) {
|
if (items.length > 5 || items.some((item: any) => !isSettingField(item) || !item.isGroup)) {
|
||||||
return (
|
return (
|
||||||
<div className="lc-settings-main">
|
<div className="lc-settings-main">
|
||||||
{this.renderBreadcrumb()}
|
{this.renderBreadcrumb()}
|
||||||
|
@ -188,6 +201,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||||
{(skeleton) => {
|
{(skeleton) => {
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
<StageBox skeleton={skeleton} target={settings} key={settings.id}>
|
<StageBox skeleton={skeleton} target={settings} key={settings.id}>
|
||||||
<SettingsPane target={settings} usePopup={false} />
|
<SettingsPane target={settings} usePopup={false} />
|
||||||
</StageBox>
|
</StageBox>
|
||||||
|
@ -211,19 +225,18 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||||
className="lc-settings-tab-item"
|
className="lc-settings-tab-item"
|
||||||
title={<Title title={field.title} />}
|
title={<Title title={field.title} />}
|
||||||
key={field.name}
|
key={field.name}
|
||||||
onClick={
|
onClick={() => {
|
||||||
() => {
|
editor?.eventBus.emit('skeleton.settingsPane.change', {
|
||||||
editor?.eventBus.emit('skeleton.settingsPane.change', {
|
name: field.name,
|
||||||
name: field.name,
|
title: field.title,
|
||||||
title: field.title,
|
});
|
||||||
});
|
}}
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<SkeletonContext.Consumer>
|
<SkeletonContext.Consumer>
|
||||||
{(skeleton) => {
|
{(skeleton) => {
|
||||||
if (skeleton) {
|
if (skeleton) {
|
||||||
return (
|
return (
|
||||||
|
// @ts-ignore
|
||||||
<StageBox skeleton={skeleton} target={field} key={field.id}>
|
<StageBox skeleton={skeleton} target={field} key={field.id}>
|
||||||
<SettingsPane target={field} key={field.id} usePopup={false} />
|
<SettingsPane target={field} key={field.id} usePopup={false} />
|
||||||
</StageBox>
|
</StageBox>
|
||||||
|
@ -243,7 +256,7 @@ export class SettingsPrimaryPane extends Component<ISettingsPrimaryPaneProps, {
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={className}>
|
||||||
{ this.renderBreadcrumb() }
|
{this.renderBreadcrumb()}
|
||||||
<Tab
|
<Tab
|
||||||
activeKey={activeKey}
|
activeKey={activeKey}
|
||||||
onChange={(tabKey) => {
|
onChange={(tabKey) => {
|
||||||
|
|
|
@ -1,28 +1,34 @@
|
||||||
function getHotterFromSetter(setter) {
|
function getHotterFromSetter(setter: any) {
|
||||||
return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line
|
return (setter && (setter.Hotter || (setter.type && setter.type.Hotter))) || []; // eslint-disable-line
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransducerFromSetter(setter) {
|
function getTransducerFromSetter(setter: any) {
|
||||||
return setter && (
|
return (
|
||||||
setter.transducer || setter.Transducer
|
(setter &&
|
||||||
|| (setter.type && (setter.type.transducer || setter.type.Transducer))
|
(setter.transducer ||
|
||||||
) || null; // eslint-disable-line
|
setter.Transducer ||
|
||||||
|
(setter.type && (setter.type.transducer || setter.type.Transducer)))) ||
|
||||||
|
null
|
||||||
|
); // eslint-disable-line
|
||||||
}
|
}
|
||||||
|
|
||||||
function combineTransducer(transducer, arr, context) {
|
function combineTransducer(transducer: any, arr: any, context: any) {
|
||||||
if (!transducer && Array.isArray(arr)) {
|
if (!transducer && Array.isArray(arr)) {
|
||||||
const [toHot, toNative] = arr;
|
const [toHot, toNative] = arr;
|
||||||
transducer = { toHot, toNative };
|
transducer = { toHot, toNative };
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line
|
toHot: ((transducer && transducer.toHot) || ((x: any) => x)).bind(context), // eslint-disable-line
|
||||||
toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line
|
toNative: ((transducer && transducer.toNative) || ((x: any) => x)).bind(context), // eslint-disable-line
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Transducer {
|
export class Transducer {
|
||||||
constructor(context, config) {
|
context: any;
|
||||||
|
setterTransducer: any;
|
||||||
|
|
||||||
|
constructor(context: any, config: any) {
|
||||||
this.setterTransducer = combineTransducer(
|
this.setterTransducer = combineTransducer(
|
||||||
getTransducerFromSetter(config.setter),
|
getTransducerFromSetter(config.setter),
|
||||||
getHotterFromSetter(config.setter),
|
getHotterFromSetter(config.setter),
|
||||||
|
@ -31,11 +37,11 @@ export class Transducer {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
toHot(data) {
|
toHot(data: any) {
|
||||||
return this.setterTransducer.toHot(data);
|
return this.setterTransducer.toHot(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
toNative(data) {
|
toNative(data: any) {
|
||||||
return this.setterTransducer.toNative(data);
|
return this.setterTransducer.toNative(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,8 +104,12 @@ export default class StageBox extends Component<StageBoxProps> {
|
||||||
let contentRefer = null;
|
let contentRefer = null;
|
||||||
|
|
||||||
if (refer) {
|
if (refer) {
|
||||||
contentCurrent = <Stage key={stage.getId()} stage={stage} direction={refer.direction} current />;
|
contentCurrent = (
|
||||||
contentRefer = <Stage key={refer?.stage?.getId()} stage={refer?.stage} direction={refer.direction} />;
|
<Stage key={stage.getId()} stage={stage} direction={refer.direction} current />
|
||||||
|
);
|
||||||
|
contentRefer = (
|
||||||
|
<Stage key={refer?.stage?.getId()} stage={refer?.stage} direction={refer.direction} />
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
contentCurrent = <Stage key={stage.getId()} stage={stage} current />;
|
contentCurrent = <Stage key={stage.getId()} stage={stage} current />;
|
||||||
}
|
}
|
||||||
|
@ -117,12 +121,10 @@ export default class StageBox extends Component<StageBoxProps> {
|
||||||
}}
|
}}
|
||||||
className={className}
|
className={className}
|
||||||
>
|
>
|
||||||
|
{/* @ts-ignore */}
|
||||||
<PopupService popupPipe={this.popupPipe}>
|
<PopupService popupPipe={this.popupPipe}>
|
||||||
|
|
||||||
{contentRefer}
|
{contentRefer}
|
||||||
{contentCurrent}
|
{contentCurrent}
|
||||||
|
|
||||||
</PopupService>
|
</PopupService>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -78,9 +78,17 @@ export default class Stage extends Component<StageProps> {
|
||||||
|
|
||||||
const stageBacker = stage?.hasBack() ? (
|
const stageBacker = stage?.hasBack() ? (
|
||||||
<div className="skeleton-stagebox-stagebacker">
|
<div className="skeleton-stagebox-stagebacker">
|
||||||
<IconArrow className="skeleton-stagebox-stage-arrow" size="medium" data-stage-target="stageback" />
|
<IconArrow
|
||||||
<span className="skeleton-stagebox-stage-title">{newTitle}</span>
|
className="skeleton-stagebox-stage-arrow"
|
||||||
<IconExit className="skeleton-stagebox-stage-exit" size="medium" data-stage-target="stageexit" />
|
size="medium"
|
||||||
|
data-stage-target="stageback"
|
||||||
|
/>
|
||||||
|
<span className="skeleton-stagebox-stage-title">{newTitle as any}</span>
|
||||||
|
<IconExit
|
||||||
|
className="skeleton-stagebox-stage-exit"
|
||||||
|
size="medium"
|
||||||
|
data-stage-target="stageexit"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { IconFloat } from '../../icons/float';
|
||||||
import { Panel } from '../../widget/panel';
|
import { Panel } from '../../widget/panel';
|
||||||
|
|
||||||
export default class PanelOperationRow extends Component<{ panel: Panel }> {
|
export default class PanelOperationRow extends Component<{ panel: Panel }> {
|
||||||
constructor(props) {
|
constructor(props: any) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,8 @@ export default class PanelOperationRow extends Component<{ panel: Panel }> {
|
||||||
|
|
||||||
const hideTitleBar = panel?.config.props?.hideTitleBar;
|
const hideTitleBar = panel?.config.props?.hideTitleBar;
|
||||||
|
|
||||||
const areaName = panel?.parent?.name;
|
const areaName = panel?.parent?.name ?? '';
|
||||||
const area = panel.skeleton[areaName];
|
const area = (panel.skeleton as any)[areaName];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { SVGIcon, IconProps } from '@alilc/lowcode-utils';
|
||||||
export function IconSlot(props: IconProps) {
|
export function IconSlot(props: IconProps) {
|
||||||
return (
|
return (
|
||||||
<SVGIcon viewBox="0 0 1024 1024" {...props}>
|
<SVGIcon viewBox="0 0 1024 1024" {...props}>
|
||||||
<path d="M682.325333 135.509333V204.8H819.2v613.376h-614.741333V204.8h136.874666v-69.290667h-206.165333v752.298667h754.346667V135.509333z" c="Q29weXJpZ2h0IChjKSAyMDIwLXByZXNlbnQgQWxpYmFiYSBJbmMu" />
|
<path d="M682.325333 135.509333V204.8H819.2v613.376h-614.741333V204.8h136.874666v-69.290667h-206.165333v752.298667h754.346667V135.509333z" />
|
||||||
<path d="M512 512m-170.325333 0a170.325333 170.325333 0 1 0 340.650666 0 170.325333 170.325333 0 1 0-340.650666 0Z" />
|
<path d="M512 512m-170.325333 0a170.325333 170.325333 0 1 0 340.650666 0 170.325333 170.325333 0 1 0-340.650666 0Z" />
|
||||||
</SVGIcon>
|
</SVGIcon>
|
||||||
);
|
);
|
||||||
|
|
|
@ -9,3 +9,4 @@ export * from './context';
|
||||||
export * from './register-defaults';
|
export * from './register-defaults';
|
||||||
export * from './widget';
|
export * from './widget';
|
||||||
export * from './layouts';
|
export * from './layouts';
|
||||||
|
export * from './event';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Component, Fragment } from 'react';
|
import { Component, Fragment } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { observer } from '@alilc/lowcode-editor-core';
|
import { observer } from '@alilc/lowcode-editor-core';
|
||||||
import { Area } from '@alilc/lowcode-editor-skeleton';
|
import { Area } from '../area';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export default class SubTopArea extends Component<{ area: Area; itemClassName?: string }> {
|
export default class SubTopArea extends Component<{ area: Area; itemClassName?: string }> {
|
||||||
|
@ -13,9 +13,10 @@ export default class SubTopArea extends Component<{ area: Area; itemClassName?:
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames('lc-workspace-sub-top-area lc-sub-top-area engine-actionpane', {
|
<div
|
||||||
'lc-area-visible': area.visible,
|
className={classNames('lc-workspace-sub-top-area lc-sub-top-area engine-actionpane', {
|
||||||
})}
|
'lc-area-visible': area.visible,
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
<Contents area={area} itemClassName={itemClassName} />
|
<Contents area={area} itemClassName={itemClassName} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,38 +31,43 @@ class Contents extends Component<{ area: Area; itemClassName?: string }> {
|
||||||
const left: any[] = [];
|
const left: any[] = [];
|
||||||
const center: any[] = [];
|
const center: any[] = [];
|
||||||
const right: any[] = [];
|
const right: any[] = [];
|
||||||
area.container.items.slice().sort((a, b) => {
|
area.container.items
|
||||||
const index1 = a.config?.index || 0;
|
.slice()
|
||||||
const index2 = b.config?.index || 0;
|
.sort((a, b) => {
|
||||||
return index1 === index2 ? 0 : (index1 > index2 ? 1 : -1);
|
const index1 = a.config?.index || 0;
|
||||||
}).forEach(item => {
|
const index2 = b.config?.index || 0;
|
||||||
const content = (
|
return index1 === index2 ? 0 : index1 > index2 ? 1 : -1;
|
||||||
<div className={itemClassName || ''} key={`top-area-${item.name}`}>
|
})
|
||||||
{item.content}
|
.forEach((item) => {
|
||||||
</div>
|
const content = (
|
||||||
);
|
<div className={itemClassName || ''} key={`top-area-${item.name}`}>
|
||||||
if (item.align === 'center') {
|
{item.content}
|
||||||
center.push(content);
|
</div>
|
||||||
} else if (item.align === 'left') {
|
);
|
||||||
left.push(content);
|
if (item.align === 'center') {
|
||||||
} else {
|
center.push(content);
|
||||||
right.push(content);
|
} else if (item.align === 'left') {
|
||||||
}
|
left.push(content);
|
||||||
});
|
} else {
|
||||||
|
right.push(content);
|
||||||
|
}
|
||||||
|
});
|
||||||
let children = [];
|
let children = [];
|
||||||
if (left && left.length) {
|
if (left && left.length) {
|
||||||
children.push(<div className="lc-workspace-sub-top-area-left lc-sub-top-area-left">{left}</div>);
|
children.push(
|
||||||
|
<div className="lc-workspace-sub-top-area-left lc-sub-top-area-left">{left}</div>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (center && center.length) {
|
if (center && center.length) {
|
||||||
children.push(<div className="lc-workspace-sub-top-area-center lc-sub-top-area-center">{center}</div>);
|
children.push(
|
||||||
|
<div className="lc-workspace-sub-top-area-center lc-sub-top-area-center">{center}</div>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (right && right.length) {
|
if (right && right.length) {
|
||||||
children.push(<div className="lc-workspace-sub-top-area-right lc-sub-top-area-right">{right}</div>);
|
children.push(
|
||||||
|
<div className="lc-workspace-sub-top-area-right lc-sub-top-area-right">{right}</div>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return (
|
return <Fragment>{children}</Fragment>;
|
||||||
<Fragment>
|
|
||||||
{children}
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
declare module 'ric-shim';
|
|
@ -36,27 +36,29 @@ function transformStringToFunction(str: string) {
|
||||||
fn = new Function(fnBody)();
|
fn = new Function(fnBody)();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.error(str);
|
logger.error(str);
|
||||||
logger.error(e.message);
|
logger.error((e as Error).message);
|
||||||
}
|
}
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseJSFunc(obj: any, enableAllowedKeys = true) {
|
function parseJSFunc(obj: any, enableAllowedKeys = true) {
|
||||||
if (!obj) return;
|
if (!obj) return;
|
||||||
Object.keys(obj).forEach(key => {
|
Object.keys(obj).forEach((key) => {
|
||||||
const item = obj[key];
|
const item = obj[key];
|
||||||
if (isJSFunction(item)) {
|
if (isJSFunction(item)) {
|
||||||
obj[key] = transformStringToFunction(item.value);
|
obj[key] = transformStringToFunction(item.value);
|
||||||
} else if (Array.isArray(item)) {
|
} else if (Array.isArray(item)) {
|
||||||
item.forEach(o => parseJSFunc(o, enableAllowedKeys));
|
item.forEach((o) => parseJSFunc(o, enableAllowedKeys));
|
||||||
} else if (isPlainObject(item)) {
|
} else if (isPlainObject(item)) {
|
||||||
parseJSFunc(item, enableAllowedKeys);
|
parseJSFunc(item, enableAllowedKeys);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function (metadata: IPublicTypeTransformedComponentMetadata): IPublicTypeTransformedComponentMetadata {
|
export default function (
|
||||||
|
metadata: IPublicTypeTransformedComponentMetadata,
|
||||||
|
): IPublicTypeTransformedComponentMetadata {
|
||||||
parseJSFunc(metadata, false);
|
parseJSFunc(metadata, false);
|
||||||
|
|
||||||
return metadata;
|
return metadata;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ function propConfigToFieldConfig(propConfig: IPublicTypePropConfig): IPublicType
|
||||||
'zh-CN': description?.slice(0, 10) || name,
|
'zh-CN': description?.slice(0, 10) || name,
|
||||||
},
|
},
|
||||||
tip: description ? `${name} | ${description}` : undefined,
|
tip: description ? `${name} | ${description}` : undefined,
|
||||||
};
|
} as any;
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
...propConfig,
|
...propConfig,
|
||||||
|
@ -65,7 +65,8 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
const dataSource = ((propType as IPublicTypeOneOf).value || []).map((value, index) => {
|
const dataSource = ((propType as IPublicTypeOneOf).value || []).map((value, index) => {
|
||||||
const t = typeof value;
|
const t = typeof value;
|
||||||
return {
|
return {
|
||||||
label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`,
|
label:
|
||||||
|
t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`,
|
||||||
value,
|
value,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -93,7 +94,9 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
};
|
};
|
||||||
case 'shape':
|
case 'shape':
|
||||||
case 'exact':
|
case 'exact':
|
||||||
const items = ((propType as any).value || []).map((item: any) => propConfigToFieldConfig(item));
|
const items = ((propType as any).value || []).map((item: any) =>
|
||||||
|
propConfigToFieldConfig(item),
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
componentName: 'ObjectSetter',
|
componentName: 'ObjectSetter',
|
||||||
props: {
|
props: {
|
||||||
|
@ -110,7 +113,11 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
if (initial == null && item.setter && typeof item.setter === 'object') {
|
if (initial == null && item.setter && typeof item.setter === 'object') {
|
||||||
initial = (item.setter as any).initialValue;
|
initial = (item.setter as any).initialValue;
|
||||||
}
|
}
|
||||||
data[item.name] = initial ? (typeof initial === 'function' ? initial(field) : initial) : null;
|
data[item.name] = initial
|
||||||
|
? typeof initial === 'function'
|
||||||
|
? initial(field)
|
||||||
|
: initial
|
||||||
|
: null;
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
@ -121,7 +128,9 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
componentName: 'ObjectSetter',
|
componentName: 'ObjectSetter',
|
||||||
props: {
|
props: {
|
||||||
config: {
|
config: {
|
||||||
extraSetter: propTypeToSetter(typeName === 'objectOf' ? (propType as IPublicTypeObjectOf).value : 'any'),
|
extraSetter: propTypeToSetter(
|
||||||
|
typeName === 'objectOf' ? (propType as IPublicTypeObjectOf).value : 'any',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isRequired,
|
isRequired,
|
||||||
|
@ -132,7 +141,9 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
return {
|
return {
|
||||||
componentName: 'ArraySetter',
|
componentName: 'ArraySetter',
|
||||||
props: {
|
props: {
|
||||||
itemSetter: propTypeToSetter(typeName === 'arrayOf' ? (propType as IPublicTypeArrayOf).value : 'any'),
|
itemSetter: propTypeToSetter(
|
||||||
|
typeName === 'arrayOf' ? (propType as IPublicTypeArrayOf).value : 'any',
|
||||||
|
),
|
||||||
},
|
},
|
||||||
isRequired,
|
isRequired,
|
||||||
initialValue: [],
|
initialValue: [],
|
||||||
|
@ -157,7 +168,7 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
isRequired,
|
isRequired,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
componentName: 'MixedSetter',
|
componentName: 'MixedSetter',
|
||||||
|
@ -168,7 +179,9 @@ function propTypeToSetter(propType: IPublicTypePropType): IPublicTypeSetterType
|
||||||
|
|
||||||
const EVENT_RE = /^on|after|before[A-Z][\w]*$/;
|
const EVENT_RE = /^on|after|before[A-Z][\w]*$/;
|
||||||
|
|
||||||
export default function (metadata: IPublicTypeTransformedComponentMetadata): IPublicTypeTransformedComponentMetadata {
|
export default function (
|
||||||
|
metadata: IPublicTypeTransformedComponentMetadata,
|
||||||
|
): IPublicTypeTransformedComponentMetadata {
|
||||||
const { configure = {} } = metadata;
|
const { configure = {} } = metadata;
|
||||||
// TODO types后续补充
|
// TODO types后续补充
|
||||||
let extendsProps: any = null;
|
let extendsProps: any = null;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ReactNode, createElement } from 'react';
|
import { ReactNode, createElement } from 'react';
|
||||||
import { makeObservable, obx } from '@alilc/lowcode-editor-core';
|
import { makeObservable, obx } from '@alilc/lowcode-editor-core';
|
||||||
import { uniqueId, createContent } from '@alilc/lowcode-utils';
|
import { uniqueId, createContent } from '@alilc/lowcode-utils';
|
||||||
import { getEvent } from '@alilc/lowcode-shell';
|
import { getEvent } from '../event';
|
||||||
import { DockConfig } from '../types';
|
import { DockConfig } from '../types';
|
||||||
import { ISkeleton } from '../skeleton';
|
import { ISkeleton } from '../skeleton';
|
||||||
import { DockView, WidgetView } from '../components/widget-views';
|
import { DockView, WidgetView } from '../components/widget-views';
|
||||||
|
@ -59,7 +59,10 @@ export class Dock implements IWidget {
|
||||||
return this._body;
|
return this._body;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(readonly skeleton: ISkeleton, readonly config: DockConfig) {
|
constructor(
|
||||||
|
readonly skeleton: ISkeleton,
|
||||||
|
readonly config: DockConfig,
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
const { props = {}, name } = config;
|
const { props = {}, name } = config;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
|
@ -1,9 +1,19 @@
|
||||||
import { createElement, ReactNode } from 'react';
|
import { createElement, ReactNode } from 'react';
|
||||||
import { obx, computed, makeObservable, IEventBus, createModuleEventBus } from '@alilc/lowcode-editor-core';
|
import {
|
||||||
|
obx,
|
||||||
|
computed,
|
||||||
|
makeObservable,
|
||||||
|
IEventBus,
|
||||||
|
createModuleEventBus,
|
||||||
|
} from '@alilc/lowcode-editor-core';
|
||||||
import { uniqueId, createContent } from '@alilc/lowcode-utils';
|
import { uniqueId, createContent } from '@alilc/lowcode-utils';
|
||||||
import { IPublicTypeHelpTipConfig, IPublicTypePanelConfig, IPublicTypeTitleContent } from '@alilc/lowcode-types';
|
import {
|
||||||
|
IPublicTypeHelpTipConfig,
|
||||||
|
IPublicTypePanelConfig,
|
||||||
|
IPublicTypeTitleContent,
|
||||||
|
} from '@alilc/lowcode-types';
|
||||||
import { WidgetContainer } from './widget-container';
|
import { WidgetContainer } from './widget-container';
|
||||||
import { getEvent } from '@alilc/lowcode-shell';
|
import { getEvent } from '../event';
|
||||||
import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views';
|
import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views';
|
||||||
import { ISkeleton } from '../skeleton';
|
import { ISkeleton } from '../skeleton';
|
||||||
import { composeTitle } from './utils';
|
import { composeTitle } from './utils';
|
||||||
|
@ -49,7 +59,7 @@ export class Panel implements IWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { content, contentProps } = this.config;
|
const { content, contentProps } = this.config;
|
||||||
return createContent(content, {
|
return createContent(content as any, {
|
||||||
...contentProps,
|
...contentProps,
|
||||||
editor: getEvent(this.skeleton.editor),
|
editor: getEvent(this.skeleton.editor),
|
||||||
config: this.config,
|
config: this.config,
|
||||||
|
@ -80,7 +90,10 @@ export class Panel implements IWidget {
|
||||||
|
|
||||||
@obx.ref public parent?: WidgetContainer;
|
@obx.ref public parent?: WidgetContainer;
|
||||||
|
|
||||||
constructor(readonly skeleton: ISkeleton, readonly config: IPublicTypePanelConfig) {
|
constructor(
|
||||||
|
readonly skeleton: ISkeleton,
|
||||||
|
readonly config: IPublicTypePanelConfig,
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
const { name, content, props = {} } = config;
|
const { name, content, props = {} } = config;
|
||||||
const { hideTitleBar, title, icon, description, help } = props;
|
const { hideTitleBar, title, icon, description, help } = props;
|
||||||
|
@ -108,8 +121,8 @@ export class Panel implements IWidget {
|
||||||
props.onInit.call(this, this);
|
props.onInit.call(this, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof content !== 'string' && content && content.onInit) {
|
if (typeof content !== 'string' && content && (content as any).onInit) {
|
||||||
content.onInit.call(this, this);
|
(content as any).onInit.call(this, this);
|
||||||
}
|
}
|
||||||
// todo: process shortcut
|
// todo: process shortcut
|
||||||
}
|
}
|
||||||
|
@ -217,7 +230,7 @@ export class Panel implements IWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAssocDocks(): PanelDock[] {
|
getAssocDocks(): PanelDock[] {
|
||||||
return this.skeleton.widgets.filter(item => {
|
return this.skeleton.widgets.filter((item) => {
|
||||||
return isPanelDock(item) && item.panelName === this.name;
|
return isPanelDock(item) && item.panelName === this.name;
|
||||||
}) as any;
|
}) as any;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,19 @@ import { IPublicTypeIconType, IPublicTypeTitleContent, TipContent } from '@alilc
|
||||||
import { isI18nData, isTitleConfig } from '@alilc/lowcode-utils';
|
import { isI18nData, isTitleConfig } from '@alilc/lowcode-utils';
|
||||||
import { isValidElement } from 'react';
|
import { isValidElement } from 'react';
|
||||||
|
|
||||||
export function composeTitle(title?: IPublicTypeTitleContent, icon?: IPublicTypeIconType, tip?: TipContent, tipAsTitle?: boolean, noIcon?: boolean) {
|
export function composeTitle(
|
||||||
|
title?: IPublicTypeTitleContent,
|
||||||
|
icon?: IPublicTypeIconType,
|
||||||
|
tip?: TipContent,
|
||||||
|
tipAsTitle?: boolean,
|
||||||
|
noIcon?: boolean,
|
||||||
|
) {
|
||||||
let _title: IPublicTypeTitleContent | undefined;
|
let _title: IPublicTypeTitleContent | undefined;
|
||||||
if (!title) {
|
if (!title) {
|
||||||
_title = {};
|
_title = {};
|
||||||
if (!icon || tipAsTitle) {
|
if (!icon || tipAsTitle) {
|
||||||
_title = {
|
_title = {
|
||||||
label: tip,
|
label: tip as any,
|
||||||
};
|
};
|
||||||
tip = undefined;
|
tip = undefined;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +25,7 @@ export function composeTitle(title?: IPublicTypeTitleContent, icon?: IPublicType
|
||||||
if (icon || tip) {
|
if (icon || tip) {
|
||||||
if (typeof _title !== 'object' || isValidElement(_title) || isI18nData(_title)) {
|
if (typeof _title !== 'object' || isValidElement(_title) || isI18nData(_title)) {
|
||||||
if (isValidElement(_title)) {
|
if (isValidElement(_title)) {
|
||||||
if (_title.type === 'svg' || _title.type.getIcon) {
|
if (_title.type === 'svg' || (_title.type as any).getIcon) {
|
||||||
if (!icon) {
|
if (!icon) {
|
||||||
icon = _title;
|
icon = _title;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +38,7 @@ export function composeTitle(title?: IPublicTypeTitleContent, icon?: IPublicType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_title = {
|
_title = {
|
||||||
label: _title,
|
label: _title as any,
|
||||||
icon,
|
icon,
|
||||||
tip,
|
tip,
|
||||||
};
|
};
|
||||||
|
@ -41,7 +47,7 @@ export function composeTitle(title?: IPublicTypeTitleContent, icon?: IPublicType
|
||||||
..._title,
|
..._title,
|
||||||
icon,
|
icon,
|
||||||
tip,
|
tip,
|
||||||
};
|
} as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isTitleConfig(_title) && noIcon) {
|
if (isTitleConfig(_title) && noIcon) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ReactNode, createElement } from 'react';
|
import { ReactNode, createElement } from 'react';
|
||||||
import { makeObservable, obx } from '@alilc/lowcode-editor-core';
|
import { makeObservable, obx } from '@alilc/lowcode-editor-core';
|
||||||
import { createContent, uniqueId } from '@alilc/lowcode-utils';
|
import { createContent, uniqueId } from '@alilc/lowcode-utils';
|
||||||
import { getEvent } from '@alilc/lowcode-shell';
|
import { getEvent } from '../event';
|
||||||
import { WidgetConfig } from '../types';
|
import { WidgetConfig } from '../types';
|
||||||
import { ISkeleton } from '../skeleton';
|
import { ISkeleton } from '../skeleton';
|
||||||
import { WidgetView } from '../components/widget-views';
|
import { WidgetView } from '../components/widget-views';
|
||||||
|
@ -71,7 +71,10 @@ export class Widget implements IWidget {
|
||||||
|
|
||||||
readonly title: IPublicTypeTitleContent;
|
readonly title: IPublicTypeTitleContent;
|
||||||
|
|
||||||
constructor(readonly skeleton: ISkeleton, readonly config: WidgetConfig) {
|
constructor(
|
||||||
|
readonly skeleton: ISkeleton,
|
||||||
|
readonly config: WidgetConfig,
|
||||||
|
) {
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
const { props = {}, name } = config;
|
const { props = {}, name } = config;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "temp",
|
||||||
|
"stripInternal": true,
|
||||||
|
"paths": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { devDependencies, peerDependencies } from './package.json';
|
||||||
|
|
||||||
|
const externals = [...Object.keys(peerDependencies), ...Object.keys(devDependencies)];
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
// Could also be a dictionary or array of multiple entry points
|
||||||
|
entry: resolve(import.meta.dirname, 'src/index.ts'),
|
||||||
|
name: 'LowCodeEditorSkeleton',
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
// the proper extensions will be added
|
||||||
|
fileName: 'editorSkeleton',
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: externals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
|
@ -1 +0,0 @@
|
||||||
module.exports = require('../../babel.config');
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
[
|
|
||||||
"build-plugin-fusion",
|
|
||||||
{
|
|
||||||
"themePackage": "@alifd/theme-lowcode-light",
|
|
||||||
"externalNext": "umd"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"build-plugin-moment-locales",
|
|
||||||
{
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"./build.plugin.js"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
const { execSync } = require('child_process');
|
|
||||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
|
||||||
|
|
||||||
// get version from git branch name,
|
|
||||||
// e.g. release/1.0.7 => 1.0.7
|
|
||||||
// release/1.0.7-beta => 1.0.7 (beta)
|
|
||||||
// release/1.0.7-beta.0 => 1.0.7 (beta)
|
|
||||||
function getVersion() {
|
|
||||||
const gitBranchName = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' });
|
|
||||||
const reBranchVersion = /^(?:[\w-]+\/)(\d+\.\d+\.\d+)(-?beta)?(?:\.\d+)?$/im;
|
|
||||||
|
|
||||||
const match = reBranchVersion.exec(gitBranchName);
|
|
||||||
if (!match) {
|
|
||||||
console.warn(`[engine] gitBranchName: ${gitBranchName}`);
|
|
||||||
return 'N/A';
|
|
||||||
}
|
|
||||||
|
|
||||||
const [_, version, beta] = match;
|
|
||||||
|
|
||||||
return beta && beta.endsWith('beta') ? `${version}-beta` : version;
|
|
||||||
}
|
|
||||||
|
|
||||||
const releaseVersion = getVersion();
|
|
||||||
|
|
||||||
module.exports = ({ context, onGetWebpackConfig }) => {
|
|
||||||
onGetWebpackConfig((config) => {
|
|
||||||
config.resolve.plugin('tsconfigpaths').use(TsconfigPathsPlugin, [
|
|
||||||
{
|
|
||||||
configFile: './tsconfig.json',
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
config.plugin('define').use(context.webpack.DefinePlugin, [
|
|
||||||
{
|
|
||||||
VERSION_PLACEHOLDER: JSON.stringify(releaseVersion),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
config.plugins.delete('hot');
|
|
||||||
config.devServer.hot(false);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
[
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
{
|
|
||||||
"filename": "editor-preset-vision",
|
|
||||||
"library": "LowcodeEditor",
|
|
||||||
"libraryTarget": "umd",
|
|
||||||
"externals": {
|
|
||||||
"react": "var window.React",
|
|
||||||
"react-dom": "var window.ReactDOM",
|
|
||||||
"prop-types": "var window.PropTypes",
|
|
||||||
"rax": "var window.Rax"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"entry": {
|
|
||||||
"engine-core": "src/index"
|
|
||||||
},
|
|
||||||
"sourceMap": true,
|
|
||||||
"library": "AliLowCodeEngine",
|
|
||||||
"libraryTarget": "umd",
|
|
||||||
"externals": {
|
|
||||||
"react": "var window.React",
|
|
||||||
"react-dom": "var window.ReactDOM",
|
|
||||||
"prop-types": "var window.PropTypes",
|
|
||||||
"@ali/visualengine": "var window.VisualEngine",
|
|
||||||
"@ali/visualengine-utils": "var window.VisualEngineUtils",
|
|
||||||
"rax": "var window.Rax",
|
|
||||||
"monaco-editor/esm/vs/editor/editor.api": "var window.monaco",
|
|
||||||
"monaco-editor/esm/vs/editor/editor.main.js": "var window.monaco",
|
|
||||||
"@alifd/next": "var Next",
|
|
||||||
"@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
|
|
||||||
"moment": "var moment",
|
|
||||||
"lodash": "var _"
|
|
||||||
},
|
|
||||||
"polyfill": false,
|
|
||||||
"outputDir": "dist",
|
|
||||||
"vendor": false,
|
|
||||||
"ignoreHtmlTemplate": true,
|
|
||||||
"plugins": [
|
|
||||||
"build-plugin-react-app",
|
|
||||||
[
|
|
||||||
"build-plugin-fusion",
|
|
||||||
{
|
|
||||||
"themePackage": "@alifd/theme-lowcode-light",
|
|
||||||
"externalNext": "umd"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
["build-plugin-moment-locales", {
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}],
|
|
||||||
"./build.plugin.js"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
const esModules = [
|
|
||||||
'@recore/obx-react',
|
|
||||||
// '@ali/lowcode-editor-core',
|
|
||||||
].join('|');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
// transform: {
|
|
||||||
// '^.+\\.[jt]sx?$': 'babel-jest',
|
|
||||||
// // '^.+\\.(ts|tsx)$': 'ts-jest',
|
|
||||||
// // '^.+\\.(js|jsx)$': 'babel-jest',
|
|
||||||
// },
|
|
||||||
// testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
`/node_modules/(?!${esModules})/`,
|
|
||||||
],
|
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
|
||||||
collectCoverage: false,
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src/**/*.{ts,tsx}',
|
|
||||||
'!src/**/*.d.ts',
|
|
||||||
'!src/base/**',
|
|
||||||
'!src/fields/**',
|
|
||||||
'!src/prop.ts',
|
|
||||||
'!**/node_modules/**',
|
|
||||||
'!**/vendor/**',
|
|
||||||
],
|
|
||||||
};
|
|
|
@ -29,16 +29,16 @@
|
||||||
"@alilc/lowcode-shell": "1.3.2",
|
"@alilc/lowcode-shell": "1.3.2",
|
||||||
"@alilc/lowcode-utils": "1.3.2",
|
"@alilc/lowcode-utils": "1.3.2",
|
||||||
"@alilc/lowcode-workspace": "1.3.2",
|
"@alilc/lowcode-workspace": "1.3.2",
|
||||||
"react": "^16.8.1",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^16.8.1"
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.18",
|
"@alib/build-scripts": "^0.1.18",
|
||||||
"@alifd/theme-lowcode-dark": "^0.2.0",
|
"@alifd/theme-lowcode-dark": "^0.2.0",
|
||||||
"@alifd/theme-lowcode-light": "^0.2.0",
|
"@alifd/theme-lowcode-light": "^0.2.0",
|
||||||
"@types/domready": "^1.0.0",
|
"@types/domready": "^1.0.0",
|
||||||
"@types/react": "^16.8.3",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react-dom": "^16.8.2",
|
"@types/react-dom": "^18.2.0",
|
||||||
"build-plugin-fusion": "0.1.17-beta.0",
|
"build-plugin-fusion": "0.1.17-beta.0",
|
||||||
"build-plugin-moment-locales": "^0.1.0",
|
"build-plugin-moment-locales": "^0.1.0",
|
||||||
"build-plugin-react-app": "^1.8.0",
|
"build-plugin-react-app": "^1.8.0",
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
"build-plugin-fusion",
|
|
||||||
["build-plugin-moment-locales", {
|
|
||||||
"locales": ["zh-cn"]
|
|
||||||
}]
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"plugins": [
|
|
||||||
[
|
|
||||||
"@alilc/build-plugin-lce",
|
|
||||||
{
|
|
||||||
"filename": "editor-preset-vision",
|
|
||||||
"library": "LowcodeEditor",
|
|
||||||
"libraryTarget": "umd",
|
|
||||||
"externals": {
|
|
||||||
"react": "var window.React",
|
|
||||||
"react-dom": "var window.ReactDOM",
|
|
||||||
"prop-types": "var window.PropTypes",
|
|
||||||
"rax": "var window.Rax"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@alilc/lowcode-test-mate/plugin/index.ts"
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
const { join } = require('path');
|
|
||||||
const esModules = [].join('|');
|
|
||||||
const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.'));
|
|
||||||
|
|
||||||
const jestConfig = {
|
|
||||||
transformIgnorePatterns: [
|
|
||||||
`/node_modules/(?!${esModules})/`,
|
|
||||||
],
|
|
||||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
|
|
||||||
collectCoverage: true,
|
|
||||||
collectCoverageFrom: [
|
|
||||||
'src/**/*.ts',
|
|
||||||
'src/**/*.tsx',
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 只对本仓库内的 pkg 做 mapping
|
|
||||||
jestConfig.moduleNameMapper = {};
|
|
||||||
jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '<rootDir>/../$1/src';
|
|
||||||
|
|
||||||
module.exports = jestConfig;
|
|
|
@ -1,39 +1,46 @@
|
||||||
{
|
{
|
||||||
"name": "@alilc/lowcode-plugin-command",
|
"name": "@alilc/lowcode-plugin-command",
|
||||||
"version": "1.3.2",
|
"version": "2.0.0-beta.0",
|
||||||
"description": "> TODO: description",
|
"description": "> TODO: description",
|
||||||
"author": "liujuping <liujup@foxmail.com>",
|
"author": "liujuping <liujup@foxmail.com>",
|
||||||
"homepage": "https://github.com/alibaba/lowcode-engine#readme",
|
"homepage": "https://github.com/alibaba/lowcode-engine#readme",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"main": "lib/index.js",
|
"type": "module",
|
||||||
"module": "es/index.js",
|
"main": "dist/command.cjs",
|
||||||
"directories": {
|
"module": "dist/command.js",
|
||||||
"lib": "lib",
|
"types": "dist/index.d.ts",
|
||||||
"test": "__tests__"
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/command.js",
|
||||||
|
"require": "./dist/command.cjs",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"lib",
|
"dist",
|
||||||
"es"
|
"src",
|
||||||
|
"package.json"
|
||||||
],
|
],
|
||||||
|
"sideEffects": [
|
||||||
|
"*.css"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "vite build",
|
||||||
|
"build-dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs",
|
||||||
|
"test": "vitest"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/alibaba/lowcode-engine/issues"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@alilc/lowcode-types": "workspace:*",
|
||||||
|
"@alilc/lowcode-utils": "workspace:*"
|
||||||
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/alibaba/lowcode-engine.git"
|
"url": "git+https://github.com/alibaba/lowcode-engine.git"
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"test": "build-scripts test --config build.test.json --jest-passWithNoTests",
|
|
||||||
"build": "build-scripts build"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/alibaba/lowcode-engine/issues"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@alilc/lowcode-types": "1.3.2",
|
|
||||||
"@alilc/lowcode-utils": "1.3.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@alib/build-scripts": "^0.1.18"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "temp",
|
||||||
|
"stripInternal": true,
|
||||||
|
"paths": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist"
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
// Could also be a dictionary or array of multiple entry points
|
||||||
|
entry: resolve(import.meta.dirname, 'src/index.ts'),
|
||||||
|
name: 'LowCodePluginCommand',
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
// the proper extensions will be added
|
||||||
|
fileName: 'plugin-command',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,16 +1,27 @@
|
||||||
{
|
{
|
||||||
"name": "@alilc/lowcode-plugin-designer",
|
"name": "@alilc/lowcode-plugin-designer",
|
||||||
"version": "1.3.2",
|
"version": "2.0.0-beta.0",
|
||||||
"description": "alibaba lowcode editor designer plugin",
|
"description": "alibaba lowcode editor designer plugin",
|
||||||
|
"type": "module",
|
||||||
|
"main": "dist/designer.cjs",
|
||||||
|
"module": "dist/designer.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/designer.js",
|
||||||
|
"require": "./dist/designer.cjs",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"es",
|
"dist",
|
||||||
"lib"
|
"src",
|
||||||
|
"package.json"
|
||||||
],
|
],
|
||||||
"main": "lib/index.js",
|
|
||||||
"module": "es/index.js",
|
|
||||||
"stylePath": "style.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "build-scripts build"
|
"build": "vite build",
|
||||||
|
"build-dts": "tsc -p tsconfig.declaration.json && node ../../scripts/rollup-dts.mjs",
|
||||||
|
"test": "vitest"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"lowcode",
|
"lowcode",
|
||||||
|
@ -18,16 +29,19 @@
|
||||||
],
|
],
|
||||||
"author": "xiayang.xy",
|
"author": "xiayang.xy",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@alilc/lowcode-designer": "1.3.2",
|
"@alilc/lowcode-designer": "workspace:*",
|
||||||
"@alilc/lowcode-editor-core": "1.3.2",
|
"@alilc/lowcode-editor-core": "workspace:*",
|
||||||
"@alilc/lowcode-utils": "1.3.2",
|
"@alilc/lowcode-utils": "workspace:*",
|
||||||
"react": "^16.8.1",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^16.8.1"
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@alib/build-scripts": "^0.1.3",
|
"@types/react": "^18.2.0",
|
||||||
"@types/react": "^16.9.13",
|
"@types/react-dom": "^18.2.0"
|
||||||
"@types/react-dom": "^16.9.4"
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public",
|
"access": "public",
|
||||||
|
|
|
@ -13,6 +13,7 @@ export interface PluginProps {
|
||||||
interface DesignerPluginState {
|
interface DesignerPluginState {
|
||||||
componentMetadatas?: any[] | null;
|
componentMetadatas?: any[] | null;
|
||||||
library?: any[] | null;
|
library?: any[] | null;
|
||||||
|
utilsMetadata?: any[] | null;
|
||||||
extraEnvironment?: any[] | null;
|
extraEnvironment?: any[] | null;
|
||||||
renderEnv?: string;
|
renderEnv?: string;
|
||||||
device?: string;
|
device?: string;
|
||||||
|
@ -29,6 +30,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
||||||
|
|
||||||
state: DesignerPluginState = {
|
state: DesignerPluginState = {
|
||||||
componentMetadatas: null,
|
componentMetadatas: null,
|
||||||
|
utilsMetadata: null,
|
||||||
library: null,
|
library: null,
|
||||||
extraEnvironment: null,
|
extraEnvironment: null,
|
||||||
renderEnv: 'default',
|
renderEnv: 'default',
|
||||||
|
@ -58,7 +60,8 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
||||||
const deviceClassName = engineConfig.get('deviceClassName') || editor.get('deviceClassName');
|
const deviceClassName = engineConfig.get('deviceClassName') || editor.get('deviceClassName');
|
||||||
const simulatorUrl = engineConfig.get('simulatorUrl') || editor.get('simulatorUrl');
|
const simulatorUrl = engineConfig.get('simulatorUrl') || editor.get('simulatorUrl');
|
||||||
// @TODO setupAssets 里设置 requestHandlersMap 不太合适
|
// @TODO setupAssets 里设置 requestHandlersMap 不太合适
|
||||||
const requestHandlersMap = engineConfig.get('requestHandlersMap') || editor.get('requestHandlersMap');
|
const requestHandlersMap =
|
||||||
|
engineConfig.get('requestHandlersMap') || editor.get('requestHandlersMap');
|
||||||
if (!this._mounted) {
|
if (!this._mounted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -139,6 +142,7 @@ export default class DesignerPlugin extends PureComponent<PluginProps, DesignerP
|
||||||
name={editor.viewName}
|
name={editor.viewName}
|
||||||
designer={editor.get('designer')}
|
designer={editor.get('designer')}
|
||||||
componentMetadatas={componentMetadatas}
|
componentMetadatas={componentMetadatas}
|
||||||
|
shellModelFactory={{} as any}
|
||||||
simulatorProps={{
|
simulatorProps={{
|
||||||
library,
|
library,
|
||||||
utilsMetadata,
|
utilsMetadata,
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "temp",
|
||||||
|
"stripInternal": true,
|
||||||
|
"paths": {}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,7 @@
|
||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "lib"
|
"outDir": "dist"
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src"]
|
||||||
"./src/"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import { resolve } from 'node:path';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
import { devDependencies, peerDependencies } from './package.json';
|
||||||
|
|
||||||
|
const externals = [...Object.keys(peerDependencies), ...Object.keys(devDependencies)];
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
// Could also be a dictionary or array of multiple entry points
|
||||||
|
entry: resolve(import.meta.dirname, 'src/index.tsx'),
|
||||||
|
name: 'LowCodePluginDesigner',
|
||||||
|
formats: ['es', 'cjs'],
|
||||||
|
// the proper extensions will be added
|
||||||
|
fileName: 'plugin-designer',
|
||||||
|
},
|
||||||
|
rollupOptions: {
|
||||||
|
external: externals,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue