├── packages
├── vue2-renderer
│ ├── README.md
│ ├── build.json
│ ├── build.plugin.js
│ ├── tsconfig.json
│ ├── src
│ │ ├── index.ts
│ │ └── create-element
│ │ │ ├── Vue2ReactWrapper.tsx
│ │ │ ├── vue2-create-element.ts
│ │ │ └── adaptive-create-element.ts
│ └── package.json
├── vue3-renderer
│ ├── README.md
│ ├── build.json
│ ├── build.plugin.js
│ ├── tsconfig.json
│ ├── src
│ │ ├── index.ts
│ │ └── create-element
│ │ │ ├── Vue3ReactWrapper.tsx
│ │ │ ├── vue3-create-element.ts
│ │ │ └── adaptive-create-element.ts
│ └── package.json
├── vue-renderer-core
│ ├── README.md
│ ├── src
│ │ ├── utils
│ │ │ ├── index.ts
│ │ │ ├── is-react.ts
│ │ │ └── build-components.ts
│ │ ├── types
│ │ │ ├── index.ts
│ │ │ ├── create-element.ts
│ │ │ └── npm.ts
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── build.json
│ └── package.json
├── vue2-simulator-renderer
│ ├── README.md
│ ├── build.json
│ ├── build.test.json
│ ├── build.plugin.js
│ ├── .babelrc
│ ├── src
│ │ ├── host.ts
│ │ ├── utils
│ │ │ ├── is-dom-node.ts
│ │ │ ├── get-client-rects.ts
│ │ │ ├── misc.ts
│ │ │ ├── react-find-dom-nodes.ts
│ │ │ └── url.ts
│ │ ├── index.ts
│ │ ├── builtin-components
│ │ │ ├── leaf.tsx
│ │ │ ├── slot.tsx
│ │ │ └── builtin-components.ts
│ │ └── renderer.less
│ ├── tsconfig.json
│ ├── test
│ │ ├── utils
│ │ │ ├── components.tsx
│ │ │ └── host.ts
│ │ ├── src
│ │ │ └── renderer
│ │ │ │ ├── __snapshots__
│ │ │ │ └── demo.test.tsx.snap
│ │ │ │ └── demo.test.tsx
│ │ └── schema
│ │ │ └── basic.ts
│ ├── build.umd.json
│ ├── jest.config.js
│ └── package.json
└── vue3-simulator-renderer
│ ├── README.md
│ ├── build.json
│ ├── build.test.json
│ ├── build.plugin.js
│ ├── .babelrc
│ ├── src
│ ├── host.ts
│ ├── utils
│ │ ├── is-dom-node.ts
│ │ ├── get-client-rects.ts
│ │ ├── misc.ts
│ │ ├── react-find-dom-nodes.ts
│ │ └── url.ts
│ ├── index.ts
│ ├── builtin-components
│ │ ├── leaf.tsx
│ │ ├── slot.tsx
│ │ └── builtin-components.ts
│ └── renderer.less
│ ├── tsconfig.json
│ ├── test
│ ├── utils
│ │ ├── components.tsx
│ │ └── host.ts
│ ├── src
│ │ └── renderer
│ │ │ ├── __snapshots__
│ │ │ └── demo.test.tsx.snap
│ │ │ └── demo.test.tsx
│ └── schema
│ │ └── basic.ts
│ ├── build.umd.json
│ ├── jest.config.js
│ └── package.json
├── examples
├── lowcode-vue2-demo
│ ├── public
│ │ ├── index.html
│ │ ├── fixtures
│ │ │ └── basic-fusion-with-single-component
│ │ │ │ ├── view.css
│ │ │ │ ├── view.js
│ │ │ │ └── meta.js
│ │ ├── mock
│ │ │ └── info.json
│ │ ├── favicon.png
│ │ ├── mock-pages.json
│ │ ├── preview.html
│ │ ├── simulator
│ │ │ └── css
│ │ │ │ └── vue2-simulator-renderer.css
│ │ └── index.ejs
│ ├── .prettierrc.js
│ ├── src
│ │ ├── sample-plugins
│ │ │ ├── logo
│ │ │ │ ├── index.scss
│ │ │ │ └── index.tsx
│ │ │ ├── delete-hidden-transducer
│ │ │ │ └── index.ts
│ │ │ ├── scenario-switcher
│ │ │ │ └── index.tsx
│ │ │ └── set-ref-prop
│ │ │ │ └── index.tsx
│ │ ├── setters
│ │ │ ├── custom-setter.tsx
│ │ │ └── behavior-setter.tsx
│ │ ├── universal
│ │ │ ├── scenarios.json
│ │ │ ├── global.scss
│ │ │ ├── assets.json
│ │ │ └── plugin.tsx
│ │ ├── scenarios
│ │ │ └── index
│ │ │ │ └── index.ts
│ │ └── preview.tsx
│ ├── scripts
│ │ └── watchdog.js
│ ├── README.md
│ ├── LICENSE
│ ├── build.json
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── package.json
│ └── build.plugin.js
└── lowcode-vue3-demo
│ ├── public
│ ├── index.html
│ ├── fixtures
│ │ └── basic-fusion-with-single-component
│ │ │ ├── view.css
│ │ │ ├── view.js
│ │ │ └── meta.js
│ ├── mock
│ │ └── info.json
│ ├── favicon.png
│ ├── mock-pages.json
│ ├── preview.html
│ ├── simulator
│ │ └── css
│ │ │ └── vue3-simulator-renderer.css
│ └── index.ejs
│ ├── .prettierrc.js
│ ├── src
│ ├── sample-plugins
│ │ ├── logo
│ │ │ ├── index.scss
│ │ │ └── index.tsx
│ │ ├── delete-hidden-transducer
│ │ │ └── index.ts
│ │ ├── scenario-switcher
│ │ │ └── index.tsx
│ │ └── set-ref-prop
│ │ │ └── index.tsx
│ ├── setters
│ │ ├── custom-setter.tsx
│ │ └── behavior-setter.tsx
│ ├── universal
│ │ ├── scenarios.json
│ │ ├── global.scss
│ │ ├── assets.json
│ │ └── plugin.tsx
│ ├── scenarios
│ │ └── index
│ │ │ └── index.ts
│ └── preview.tsx
│ ├── scripts
│ └── watchdog.js
│ ├── README.md
│ ├── LICENSE
│ ├── build.json
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── package.json
│ └── build.plugin.js
├── .stylelintrc.js
├── .stylelintignore
├── .prettierrc.js
├── .eslintignore
├── pnpm-workspace.yaml
├── .editorconfig
├── scripts
└── build.sh
├── README.md
├── package.json
├── LICENSE
├── .eslintrc.js
├── tsconfig.json
└── .gitignore
/packages/vue2-renderer/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/README.md:
--------------------------------------------------------------------------------
1 | 沙箱环境
2 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/README.md:
--------------------------------------------------------------------------------
1 | 沙箱环境
2 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/index.html:
--------------------------------------------------------------------------------
1 | 勿删,删了有奇妙的 bug😄~
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/index.html:
--------------------------------------------------------------------------------
1 | 勿删,删了有奇妙的 bug😄~
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/fixtures/basic-fusion-with-single-component/view.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/fixtures/basic-fusion-with-single-component/view.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './build-components';
2 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/mock/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": "Hello AliLowCode!!"
3 | }
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/mock/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": "Hello AliLowCode!!"
3 | }
--------------------------------------------------------------------------------
/packages/vue2-renderer/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-component"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-component"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/types/index.ts:
--------------------------------------------------------------------------------
1 | export * from './create-element';
2 | export * from './npm';
3 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["build-plugin-component", "./build.plugin.js"]
3 | }
4 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["build-plugin-component", "./build.plugin.js"]
3 | }
4 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'stylelint-config-ali',
3 | rules: {
4 | "selector-max-id": 2
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/.stylelintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | node_modules/
3 | build/
4 | dist/
5 |
6 | # 忽略文件
7 | **/*.min.css
8 | **/*-min.css
9 | **/*.bundle.css
10 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | tabWidth: 2,
4 | semi: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lowcodecloud/lowcode-engine-vue-projects/HEAD/examples/lowcode-vue2-demo/public/favicon.png
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lowcodecloud/lowcode-engine-vue-projects/HEAD/examples/lowcode-vue3-demo/public/favicon.png
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/build.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-component",
4 | "@alilc/lowcode-test-mate/plugin/index.ts"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/build.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-component",
4 | "@alilc/lowcode-test-mate/plugin/index.ts"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/types/create-element.ts:
--------------------------------------------------------------------------------
1 | export interface CreateElementAdapter {
2 | createElement(component: any, props: any, ...children: any): any;
3 | }
4 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | tabWidth: 2,
4 | semi: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | printWidth: 100,
3 | tabWidth: 2,
4 | semi: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/build.plugin.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ onGetWebpackConfig }) => {
2 | onGetWebpackConfig((config) => {
3 | config.performance.hints(false);
4 | });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/build.plugin.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ onGetWebpackConfig }) => {
2 | onGetWebpackConfig((config) => {
3 | config.performance.hints(false);
4 | });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/build.plugin.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ onGetWebpackConfig }) => {
2 | onGetWebpackConfig((config) => {
3 | config.performance.hints(false);
4 | });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/build.plugin.js:
--------------------------------------------------------------------------------
1 | module.exports = ({ onGetWebpackConfig }) => {
2 | onGetWebpackConfig((config) => {
3 | config.performance.hints(false);
4 | });
5 | };
6 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib"
5 | },
6 | "include": [
7 | "./src/"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib"
5 | },
6 | "include": [
7 | "./src/"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib"
5 | },
6 | "include": [
7 | "./src/"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | ["@babel/plugin-proposal-decorators", { "legacy": true }],
4 | ["@babel/plugin-proposal-class-properties", { "loose": true }]
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | ["@babel/plugin-proposal-decorators", { "legacy": true }],
4 | ["@babel/plugin-proposal-class-properties", { "loose": true }]
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/host.ts:
--------------------------------------------------------------------------------
1 | // NOTE: 仅做类型标注,切勿做其它用途
2 | import { BuiltinSimulatorHost } from '@alilc/lowcode-designer';
3 |
4 | export const host: BuiltinSimulatorHost = (window as any).LCSimulatorHost;
5 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/host.ts:
--------------------------------------------------------------------------------
1 | // NOTE: 仅做类型标注,切勿做其它用途
2 | import { BuiltinSimulatorHost } from '@alilc/lowcode-designer';
3 |
4 | export const host: BuiltinSimulatorHost = (window as any).LCSimulatorHost;
5 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # 忽略目录
2 | node_modules
3 | test-cases
4 | test
5 | output
6 | build
7 | dist
8 | demo
9 | es
10 | lib
11 | tests
12 | .*
13 | ~*
14 |
15 | # 忽略文件
16 | **/*.min.js
17 | **/*-min.js
18 | **/*.bundle.js
19 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib"
5 | },
6 | "include": [
7 | "./src/", "../../index.ts"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "lib"
5 | },
6 | "include": [
7 | "./src/", "../../index.ts"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "build-plugin-component",
4 | "build-plugin-fusion",
5 | ["build-plugin-moment-locales", {
6 | "locales": ["zh-cn"]
7 | }]
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/utils/is-dom-node.ts:
--------------------------------------------------------------------------------
1 | export function isDOMNode(node: any): node is Element | Text {
2 | return node.nodeType && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE);
3 | }
4 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/utils/is-dom-node.ts:
--------------------------------------------------------------------------------
1 | export function isDOMNode(node: any): node is Element | Text {
2 | return node.nodeType && (node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.TEXT_NODE);
3 | }
4 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | # all packages in subdirs of packages/ and components/
3 | - 'packages/**'
4 | - 'examples/**'
5 | # exclude packages that are inside test directories
6 | - '!**/test/**'
7 | - '!**/scripts/**'
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/test/utils/components.tsx:
--------------------------------------------------------------------------------
1 | export const Text = ({
2 | __tag,
3 | content,
4 | ...props
5 | }: any) => (
{content}
);
6 |
7 | export const Page = (props: any) => ({props.children}
);
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/test/utils/components.tsx:
--------------------------------------------------------------------------------
1 | export const Text = ({
2 | __tag,
3 | content,
4 | ...props
5 | }: any) => ({content}
);
6 |
7 | export const Page = (props: any) => ({props.children}
);
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | quote_type = single
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/sample-plugins/logo/index.scss:
--------------------------------------------------------------------------------
1 | .lowcode-plugin-logo {
2 | .logo {
3 | display: block;
4 | width: 139px;
5 | height: 26px;
6 | cursor: pointer;
7 | background-size: contain;
8 | background-position: center;
9 | background-repeat: no-repeat;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/sample-plugins/logo/index.scss:
--------------------------------------------------------------------------------
1 | .lowcode-plugin-logo {
2 | .logo {
3 | display: block;
4 | width: 139px;
5 | height: 26px;
6 | cursor: pointer;
7 | background-size: contain;
8 | background-position: center;
9 | background-repeat: no-repeat;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/src/index.ts:
--------------------------------------------------------------------------------
1 | import createRendererFactory, { setRuntime, types, buildComponents } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
2 |
3 | import createElement from './create-element/adaptive-create-element';
4 |
5 | setRuntime({
6 | createElement,
7 | });
8 |
9 | export default createRendererFactory() as types.IRenderComponent;
10 | export { buildComponents, createElement };
11 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/src/index.ts:
--------------------------------------------------------------------------------
1 | import createRendererFactory, { setRuntime, types, buildComponents } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
2 |
3 | import createElement from './create-element/adaptive-create-element';
4 |
5 | setRuntime({
6 | createElement,
7 | });
8 |
9 | export default createRendererFactory() as types.IRenderComponent;
10 | export { buildComponents, createElement };
11 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/setters/custom-setter.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'; // import classNames from 'classnames';
2 |
3 | class CustomSetter extends Component {
4 | render() {
5 | const { defaultValue, value, onChange } = this.props;
6 | const { editor } = this.props.field;
7 |
8 | return hello world
;
9 | }
10 | }
11 |
12 | export default CustomSetter;
13 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/setters/custom-setter.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'; // import classNames from 'classnames';
2 |
3 | class CustomSetter extends Component {
4 | render() {
5 | const { defaultValue, value, onChange } = this.props;
6 | const { editor } = this.props.field;
7 |
8 | return hello world
;
9 | }
10 | }
11 |
12 | export default CustomSetter;
13 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/src/create-element/Vue3ReactWrapper.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { applyVueInReact } from 'veaury';
3 |
4 | class Vue3ReactWrapper extends Component {
5 | render() {
6 | const { $vueComponent, __events, ...rest } = this.props;
7 | let VueComponent = applyVueInReact($vueComponent);
8 | return ();
9 | }
10 | }
11 |
12 | export default Vue3ReactWrapper;
13 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/utils/get-client-rects.ts:
--------------------------------------------------------------------------------
1 | import { isElement } from '@alilc/lowcode-utils';
2 |
3 | // a range for test TextNode clientRect
4 | const cycleRange = document.createRange();
5 |
6 | export function getClientRects(node: Element | Text) {
7 | if (isElement(node)) {
8 | return [node.getBoundingClientRect()];
9 | }
10 |
11 | cycleRange.selectNode(node);
12 | return Array.from(cycleRange.getClientRects());
13 | }
14 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/utils/get-client-rects.ts:
--------------------------------------------------------------------------------
1 | import { isElement } from '@alilc/lowcode-utils';
2 |
3 | // a range for test TextNode clientRect
4 | const cycleRange = document.createRange();
5 |
6 | export function getClientRects(node: Element | Text) {
7 | if (isElement(node)) {
8 | return [node.getBoundingClientRect()];
9 | }
10 |
11 | cycleRange.selectNode(node);
12 | return Array.from(cycleRange.getClientRects());
13 | }
14 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/src/create-element/Vue2ReactWrapper.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { applyVueInReact } from 'vuereact-combined';
3 |
4 | class Vue2ReactWrapper extends Component {
5 | render() {
6 | const { $vueComponent, __events, ...rest } = this.props;
7 | let VueComponent = applyVueInReact($vueComponent);
8 | return ();
9 | }
10 | }
11 |
12 | export default Vue2ReactWrapper;
13 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/mock-pages.json:
--------------------------------------------------------------------------------
1 | {"success":true,"content":[{"gmtModified":"2021-03-06 00:40:54","formUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentNavUuid":"NAV-SYSTEM-PARENT-UUID","hidden":"n","navUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","navType":"PAGE","isIndex":"n","isNew":"n","gmtCreate":"2021-03-06 00:27:26","title":{"en_US":"页面1","zh_CN":"页面1","type":"i18n"},"relateUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentId":0,"listOrder":0,"id":556103}]}
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/mock-pages.json:
--------------------------------------------------------------------------------
1 | {"success":true,"content":[{"gmtModified":"2021-03-06 00:40:54","formUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentNavUuid":"NAV-SYSTEM-PARENT-UUID","hidden":"n","navUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","navType":"PAGE","isIndex":"n","isNew":"n","gmtCreate":"2021-03-06 00:27:26","title":{"en_US":"页面1","zh_CN":"页面1","type":"i18n"},"relateUuid":"FORM-6X866SC1KM4O4BLF3U7879QB0EMT2Z3TGIWLKW","parentId":0,"listOrder":0,"id":556103}]}
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/scripts/watchdog.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs');
3 | const { join } = require('path');
4 |
5 | const workingDir = process.cwd();
6 |
7 | const pkg = JSON.parse(fs.readFileSync(join(workingDir, 'package.json'), 'utf-8'));
8 | if (pkg.private) return;
9 | const { files } = pkg;
10 | files.forEach(file => {
11 | const fileDir = join(workingDir, file);
12 | if (!fs.existsSync(fileDir)) {
13 | throw new Error(`${fileDir} does not exist, plz run build`);
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/scripts/watchdog.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | const fs = require('fs');
3 | const { join } = require('path');
4 |
5 | const workingDir = process.cwd();
6 |
7 | const pkg = JSON.parse(fs.readFileSync(join(workingDir, 'package.json'), 'utf-8'));
8 | if (pkg.private) return;
9 | const { files } = pkg;
10 | files.forEach(file => {
11 | const fileDir = join(workingDir, file);
12 | if (!fs.existsSync(fileDir)) {
13 | throw new Error(`${fileDir} does not exist, plz run build`);
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { runInAction } from 'mobx';
2 | import renderer from './renderer';
3 |
4 | if (typeof window !== 'undefined') {
5 | (window as any).SimulatorRenderer = renderer;
6 | }
7 |
8 | window.addEventListener('beforeunload', () => {
9 | runInAction(() => {
10 | (window as any).LCSimulatorHost = null;
11 | renderer.dispose?.();
12 | (window as any).SimulatorRenderer = null;
13 | (window as any).ReactDOM.unmountComponentAtNode(document.getElementById('app'));
14 | });
15 | });
16 |
17 | export default renderer;
18 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/index.ts:
--------------------------------------------------------------------------------
1 | import { runInAction } from 'mobx';
2 | import renderer from './renderer';
3 |
4 | if (typeof window !== 'undefined') {
5 | (window as any).SimulatorRenderer = renderer;
6 | }
7 |
8 | window.addEventListener('beforeunload', () => {
9 | runInAction(() => {
10 | (window as any).LCSimulatorHost = null;
11 | renderer.dispose?.();
12 | (window as any).SimulatorRenderer = null;
13 | (window as any).ReactDOM.unmountComponentAtNode(document.getElementById('app'));
14 | });
15 | });
16 |
17 | export default renderer;
18 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/sample-plugins/logo/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './index.scss';
3 | import { PluginProps } from '@alilc/lowcode-types';
4 |
5 | export interface IProps {
6 | logo?: string;
7 | href?: string;
8 | }
9 |
10 | const Logo: React.FC = (props): React.ReactElement => {
11 | return (
12 |
15 | );
16 | };
17 |
18 | export default Logo;
19 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/sample-plugins/logo/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import './index.scss';
3 | import { PluginProps } from '@alilc/lowcode-types';
4 |
5 | export interface IProps {
6 | logo?: string;
7 | href?: string;
8 | }
9 |
10 | const Logo: React.FC = (props): React.ReactElement => {
11 | return (
12 |
15 | );
16 | };
17 |
18 | export default Logo;
19 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/builtin-components/leaf.tsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'react';
2 |
3 | class Leaf extends Component {
4 | static displayName = 'Leaf';
5 |
6 | static componentMetadata = {
7 | componentName: 'Leaf',
8 | configure: {
9 | props: [{
10 | name: 'children',
11 | setter: 'StringSetter',
12 | }],
13 | // events/className/style/general/directives
14 | supports: false,
15 | },
16 | };
17 |
18 | render() {
19 | const { children } = this.props;
20 | return children;
21 | }
22 | }
23 |
24 | export default Leaf;
25 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/builtin-components/leaf.tsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'react';
2 |
3 | class Leaf extends Component {
4 | static displayName = 'Leaf';
5 |
6 | static componentMetadata = {
7 | componentName: 'Leaf',
8 | configure: {
9 | props: [{
10 | name: 'children',
11 | setter: 'StringSetter',
12 | }],
13 | // events/className/style/general/directives
14 | supports: false,
15 | },
16 | };
17 |
18 | render() {
19 | const { children } = this.props;
20 | return children;
21 | }
22 | }
23 |
24 | export default Leaf;
25 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/sample-plugins/delete-hidden-transducer/index.ts:
--------------------------------------------------------------------------------
1 | import { ILowCodePluginContext, project } from '@alilc/lowcode-engine';
2 | import { CompositeObject, TransformStage } from '@alilc/lowcode-types';
3 |
4 | export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => {
5 | return {
6 | name: 'deleteHiddenTransducer',
7 | async init() {
8 | project.addPropsTransducer((props: CompositeObject): CompositeObject => {
9 | delete props.hidden;
10 | return props;
11 | }, TransformStage.Save);
12 | },
13 | };
14 | }
15 |
16 | deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer';
17 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/sample-plugins/delete-hidden-transducer/index.ts:
--------------------------------------------------------------------------------
1 | import { ILowCodePluginContext, project } from '@alilc/lowcode-engine';
2 | import { CompositeObject, TransformStage } from '@alilc/lowcode-types';
3 |
4 | export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => {
5 | return {
6 | name: 'deleteHiddenTransducer',
7 | async init() {
8 | project.addPropsTransducer((props: CompositeObject): CompositeObject => {
9 | delete props.hidden;
10 | return props;
11 | }, TransformStage.Save);
12 | },
13 | };
14 | }
15 |
16 | deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer';
17 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/universal/scenarios.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "index",
4 | "title": "综合场景"
5 | },
6 | {
7 | "name": "basic-fusion",
8 | "title": "基础 fusion 组件"
9 | },
10 | {
11 | "name": "basic-fusion-with-single-component",
12 | "title": "基础 fusion 组件 + 单自定义组件"
13 | },
14 | {
15 | "name": "basic-antd",
16 | "title": "基础 antd 组件"
17 | },
18 | {
19 | "name": "custom-initialization",
20 | "title": "自定义初始化引擎"
21 | },
22 | {
23 | "name": "node-extended-actions",
24 | "title": "扩展节点操作项"
25 | },
26 | {
27 | "name": "next-pro",
28 | "title": "基于next实现的高级表单低代码物料"
29 | }
30 | ]
31 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/universal/scenarios.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "index",
4 | "title": "综合场景"
5 | },
6 | {
7 | "name": "basic-fusion",
8 | "title": "基础 fusion 组件"
9 | },
10 | {
11 | "name": "basic-fusion-with-single-component",
12 | "title": "基础 fusion 组件 + 单自定义组件"
13 | },
14 | {
15 | "name": "basic-antd",
16 | "title": "基础 antd 组件"
17 | },
18 | {
19 | "name": "custom-initialization",
20 | "title": "自定义初始化引擎"
21 | },
22 | {
23 | "name": "node-extended-actions",
24 | "title": "扩展节点操作项"
25 | },
26 | {
27 | "name": "next-pro",
28 | "title": "基于next实现的高级表单低代码物料"
29 | }
30 | ]
31 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/src/create-element/vue2-create-element.ts:
--------------------------------------------------------------------------------
1 | import { createElement } from 'react';
2 | import { vueRendererExtTypes } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
3 | import Vue2ReactWrapper from './Vue2ReactWrapper';
4 |
5 | class Vue2CreateElement implements vueRendererExtTypes.CreateElementAdapter {
6 | createElement(component: any, props: any, ...children: any): any {
7 | // TODO 处理 reactWrapper
8 | let $vueComponent = component;
9 | let newProps = { $vueComponent, ...props };
10 | return createElement(Vue2ReactWrapper, newProps, ...children);
11 | }
12 | }
13 |
14 | export default new Vue2CreateElement().createElement;
15 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/src/create-element/vue3-create-element.ts:
--------------------------------------------------------------------------------
1 | import { createElement } from 'react';
2 | import { vueRendererExtTypes } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
3 | import Vue3ReactWrapper from './Vue3ReactWrapper';
4 |
5 | class Vue3CreateElement implements vueRendererExtTypes.CreateElementAdapter {
6 | createElement(component: any, props: any, ...children: any): any {
7 | // TODO 处理 reactWrapper
8 | let $vueComponent = component;
9 | let newProps = { $vueComponent, ...props };
10 | return createElement(Vue3ReactWrapper, newProps, ...children);
11 | }
12 | }
13 |
14 | export default new Vue3CreateElement().createElement;
15 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/utils/misc.ts:
--------------------------------------------------------------------------------
1 | interface UtilsMetadata {
2 | name: string;
3 | npm: {
4 | package: string;
5 | version?: string;
6 | exportName: string;
7 | subName?: string;
8 | destructuring?: boolean;
9 | main?: string;
10 | };
11 | }
12 |
13 | interface LibrayMap {
14 | [key: string]: string;
15 | }
16 |
17 | export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) {
18 | const projectUtils: { [packageName: string]: any } = {};
19 | if (utilsMetadata) {
20 | utilsMetadata.forEach(meta => {
21 | if (librayMap[meta?.npm.package]) {
22 | const lib = window[librayMap[meta?.npm.package]];
23 | }
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/utils/misc.ts:
--------------------------------------------------------------------------------
1 | interface UtilsMetadata {
2 | name: string;
3 | npm: {
4 | package: string;
5 | version?: string;
6 | exportName: string;
7 | subName?: string;
8 | destructuring?: boolean;
9 | main?: string;
10 | };
11 | }
12 |
13 | interface LibrayMap {
14 | [key: string]: string;
15 | }
16 |
17 | export function getProjectUtils(librayMap: LibrayMap, utilsMetadata: UtilsMetadata[]) {
18 | const projectUtils: { [packageName: string]: any } = {};
19 | if (utilsMetadata) {
20 | utilsMetadata.forEach(meta => {
21 | if (librayMap[meta?.npm.package]) {
22 | const lib = window[librayMap[meta?.npm.package]];
23 | }
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/utils/is-react.ts:
--------------------------------------------------------------------------------
1 | import { ComponentClass, Component, ComponentType } from 'react';
2 |
3 | const hasSymbol = typeof Symbol === 'function' && Symbol.for;
4 | const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
5 |
6 | export function isReactClass(obj: any): obj is ComponentClass {
7 | return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component);
8 | }
9 |
10 | function isForwardRefType(obj: any): boolean {
11 | return obj?.$$typeof && obj?.$$typeof === REACT_FORWARD_REF_TYPE;
12 | }
13 |
14 | export function isReactComponent(obj: any): obj is ComponentType {
15 | return obj && (isReactClass(obj) || isForwardRefType(obj));
16 | }
17 |
--------------------------------------------------------------------------------
/scripts/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | pnpm --filter=@lowcodecloud/lowcode-engine-vue-renderer-core build
4 |
5 | pnpm --filter=@lowcodecloud/lowcode-engine-vue2-renderer build
6 |
7 | pnpm --filter=@lowcodecloud/lowcode-engine-vue2-simulator-renderer build
8 | pnpm --filter=@lowcodecloud/lowcode-engine-vue2-simulator-renderer build:umd
9 |
10 | cp -r packages/vue2-simulator-renderer/dist/* examples/lowcode-vue2-demo/public/simulator/
11 |
12 |
13 | pnpm --filter=@lowcodecloud/lowcode-engine-vue3-renderer build
14 |
15 | pnpm --filter=@lowcodecloud/lowcode-engine-vue3-simulator-renderer build
16 | pnpm --filter=@lowcodecloud/lowcode-engine-vue3-simulator-renderer build:umd
17 |
18 | cp -r packages/vue3-simulator-renderer/dist/* examples/lowcode-vue3-demo/public/simulator/
19 |
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LowCode Engine Vue Projects
2 |
3 | ## 介绍
4 |
5 | 本项目初衷是让 `lowcode-engine` 能够快速接入 `Vue` 生态。
6 |
7 | ## 主要实现
8 |
9 | > vue-renderer
10 |
11 | 复用了`react-renderer` 改造原理比较简单,主要涉及:
12 | - 资产包增加Vue组件识别能力构造具有组件标识的`component` 核心改造 `buildComponents`及资产包描述
13 | - `createElement` 根据组件标识(devStack) 选择 `React` 实现 或 `Vue` 实现
14 |
15 | `createElement` Vue 实现,基于 `vuereact-combined`、`veaury`。
16 |
17 | 由于 `vue2.x`、`vue3.x` 命名空间都是 `Vue` 所以他们不能同时并存。
18 |
19 | > vue-simulator-renderer
20 |
21 | 原理同上
22 |
23 | ## 快速开始
24 |
25 | ### 环境准备
26 |
27 | - nodejs >= 14
28 | - 安装 pnpm (比较快,而且省磁盘🏅)
29 |
30 | ### 安装依赖
31 |
32 | ```bash
33 | pnpm install
34 | ```
35 |
36 | ### 构建
37 |
38 | ```bash
39 | pnpm build
40 | ```
41 |
42 | ### 启动
43 |
44 | 默认启动 vue2 demo
45 |
46 | ```bash
47 | pnpm start
48 | ```
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue-projects",
3 | "version": "1.0.0",
4 | "description": "lowcode-engine-vue-projects",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "sh ./scripts/build.sh",
8 | "start": "pnpm start:vue3",
9 | "start:vue2": "pnpm --filter=@lowcodecloud/lowcode-vue2-demo start",
10 | "start:vue3": "pnpm --filter=@lowcodecloud/lowcode-vue3-demo start"
11 | },
12 | "keywords": [
13 | "lowcode",
14 | "lowcode-engin",
15 | "vue"
16 | ],
17 | "author": "qinning",
18 | "license": "MIT",
19 | "devDependencies": {
20 | "react": "^16",
21 | "react-dom": "^16.7.0",
22 | "vue": "^2.6.14",
23 | "f2elint": "^2.0.1",
24 | "typescript": "^4.5.5"
25 | },
26 | "engines": {
27 | "node": ">=14.17.0 <16"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/README.md:
--------------------------------------------------------------------------------
1 | ## Low-Code Engine Demo
2 |
3 | 本 demo 是一个组合内核、setter、插件、物料的示范工程,因为未经长期生产环境打磨,可能还会有一些各个模块间结合的 bug,希望大家理解~
4 |
5 | 场景列表:
6 |
7 | - [index](https://lowcode-engine.cn/demo/index.html)
8 | - [basic-fusion](https://lowcode-engine.cn/demo/basic-fusion.html)(此 fusion 的元数据描述是很老的版本,只为了示意描述结构,请勿用于生产环境)
9 | - [basic-antd](https://lowcode-engine.cn/demo/basic-antd.html)
10 | - [basic-fusion-with-single-component](https://lowcode-engine.cn/demo/basic-fusion-with-single-component.html)
11 | - [custom-initialization](https://lowcode-engine.cn/demo/custom-initialization.html)
12 | - [node-extended-actions](https://lowcode-engine.cn/demo/node-extended-actions.html)
13 | - [next-pro](https://lowcode-engine.cn/demo/next-pro.html)
14 |
15 | 更多参考资料:
16 |
17 | - [马上玩一下](https://lowcode-engine.cn/demo/index.html)
18 | - [低代码引擎官网](http://lowcode-engine.cn)
19 | - [引擎主包](https://github.com/alibaba/lowcode-engine)
20 |
21 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/README.md:
--------------------------------------------------------------------------------
1 | ## Low-Code Engine Demo
2 |
3 | 本 demo 是一个组合内核、setter、插件、物料的示范工程,因为未经长期生产环境打磨,可能还会有一些各个模块间结合的 bug,希望大家理解~
4 |
5 | 场景列表:
6 |
7 | - [index](https://lowcode-engine.cn/demo/index.html)
8 | - [basic-fusion](https://lowcode-engine.cn/demo/basic-fusion.html)(此 fusion 的元数据描述是很老的版本,只为了示意描述结构,请勿用于生产环境)
9 | - [basic-antd](https://lowcode-engine.cn/demo/basic-antd.html)
10 | - [basic-fusion-with-single-component](https://lowcode-engine.cn/demo/basic-fusion-with-single-component.html)
11 | - [custom-initialization](https://lowcode-engine.cn/demo/custom-initialization.html)
12 | - [node-extended-actions](https://lowcode-engine.cn/demo/node-extended-actions.html)
13 | - [next-pro](https://lowcode-engine.cn/demo/next-pro.html)
14 |
15 | 更多参考资料:
16 |
17 | - [马上玩一下](https://lowcode-engine.cn/demo/index.html)
18 | - [低代码引擎官网](http://lowcode-engine.cn)
19 | - [引擎主包](https://github.com/alibaba/lowcode-engine)
20 |
21 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Base should be render NotFoundComponent 1`] = `
4 |
8 |
11 |
14 | Component Not Found
15 |
16 |
17 |
18 | `;
19 |
20 | exports[`Base should be render Text 1`] = `
21 |
25 |
28 |
37 | 我是一个简单的测试页面
38 |
39 |
40 |
41 | `;
42 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/test/src/renderer/__snapshots__/demo.test.tsx.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Base should be render NotFoundComponent 1`] = `
4 |
8 |
11 |
14 | Component Not Found
15 |
16 |
17 |
18 | `;
19 |
20 | exports[`Base should be render Text 1`] = `
21 |
25 |
28 |
37 | 我是一个简单的测试页面
38 |
39 |
40 |
41 | `;
42 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/types/npm.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 组件开发技术栈
3 | */
4 | export enum DevStack {
5 | React = 'react',
6 | Vue = 'vue',
7 | Vue2 = 'vue2',
8 | Vue3 = 'vue3',
9 | Mp = 'mp'
10 | }
11 |
12 | /**
13 | * Library -> Package 关系映射
14 | */
15 | export interface LibraryPackageMapping {
16 | [key: string]: string;
17 | }
18 |
19 | /**
20 | * npm 源引入完整描述对象
21 | */
22 | export interface NpmInfo {
23 | /**
24 | * 源码组件名称
25 | */
26 | componentName?: string;
27 | /**
28 | * 源码组件库名
29 | */
30 | package: string;
31 | /**
32 | * 源码组件版本号
33 | */
34 | version?: string;
35 | /**
36 | * 是否解构
37 | */
38 | destructuring?: boolean;
39 | /**
40 | * 源码组件名称
41 | */
42 | exportName?: string;
43 | /**
44 | * 子组件名
45 | */
46 | subName?: string;
47 | /**
48 | * 组件路径
49 | */
50 | main?: string;
51 |
52 | /**
53 | * 组件技术栈
54 | */
55 | devStack?: DevStack | string | undefined;
56 | }
57 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/build.umd.json:
--------------------------------------------------------------------------------
1 | {
2 | "entry": {
3 | "vue2-simulator-renderer": "src/index"
4 | },
5 | "sourceMap": true,
6 | "library": "___Vue2SimulatorRenderer___",
7 | "libraryTarget": "umd",
8 | "externals": {
9 | "react": "var window.React",
10 | "react-dom": "var window.ReactDOM",
11 | "prop-types": "var window.PropTypes",
12 | "@alifd/next": "var Next",
13 | "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
14 | "moment": "var moment",
15 | "lodash": "var _",
16 | "vue": "var window.Vue"
17 | },
18 | "polyfill": false,
19 | "outputDir": "dist",
20 | "vendor": false,
21 | "ignoreHtmlTemplate": true,
22 | "plugins": [
23 | "build-plugin-react-app",
24 | [
25 | "build-plugin-fusion",
26 | {
27 | "externalNext": "umd"
28 | }
29 | ],
30 | [
31 | "build-plugin-moment-locales",
32 | {
33 | "locales": ["zh-cn"]
34 | }
35 | ],
36 | "./build.plugin.js"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/build.umd.json:
--------------------------------------------------------------------------------
1 | {
2 | "entry": {
3 | "vue3-simulator-renderer": "src/index"
4 | },
5 | "sourceMap": true,
6 | "library": "___Vue3SimulatorRenderer___",
7 | "libraryTarget": "umd",
8 | "externals": {
9 | "react": "var window.React",
10 | "react-dom": "var window.ReactDOM",
11 | "prop-types": "var window.PropTypes",
12 | "@alifd/next": "var Next",
13 | "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
14 | "moment": "var moment",
15 | "lodash": "var _",
16 | "vue": "var window.Vue"
17 | },
18 | "polyfill": false,
19 | "outputDir": "dist",
20 | "vendor": false,
21 | "ignoreHtmlTemplate": true,
22 | "plugins": [
23 | "build-plugin-react-app",
24 | [
25 | "build-plugin-fusion",
26 | {
27 | "externalNext": "umd"
28 | }
29 | ],
30 | [
31 | "build-plugin-moment-locales",
32 | {
33 | "locales": ["zh-cn"]
34 | }
35 | ],
36 | "./build.plugin.js"
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/test/src/renderer/demo.test.tsx:
--------------------------------------------------------------------------------
1 | import renderer from 'react-test-renderer';
2 | import rendererContainer from '../../../src/renderer';
3 | import SimulatorRendererView from '../../../src/renderer-view';
4 | import { Text } from '../../utils/components';
5 |
6 | describe('Base', () => {
7 | const component = renderer.create(
8 |
11 | );
12 |
13 | it('should be render NotFoundComponent', () => {
14 | let tree = component.toJSON();
15 | expect(tree).toMatchSnapshot();
16 | });
17 |
18 | it('should be render Text', () => {
19 | // 更新 _componentsMap 值
20 | (rendererContainer as any)._componentsMap.Text = Text;// = host.designer.componentsMap;
21 | // 更新 components 列表
22 | (rendererContainer as any).buildComponents();
23 |
24 | expect(!!(rendererContainer.components as any).Text).toBeTruthy();
25 |
26 | rendererContainer.rerender();
27 |
28 | let tree = component.toJSON();
29 | expect(tree).toMatchSnapshot();
30 | });
31 | })
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/test/src/renderer/demo.test.tsx:
--------------------------------------------------------------------------------
1 | import renderer from 'react-test-renderer';
2 | import rendererContainer from '../../../src/renderer';
3 | import SimulatorRendererView from '../../../src/renderer-view';
4 | import { Text } from '../../utils/components';
5 |
6 | describe('Base', () => {
7 | const component = renderer.create(
8 |
11 | );
12 |
13 | it('should be render NotFoundComponent', () => {
14 | let tree = component.toJSON();
15 | expect(tree).toMatchSnapshot();
16 | });
17 |
18 | it('should be render Text', () => {
19 | // 更新 _componentsMap 值
20 | (rendererContainer as any)._componentsMap.Text = Text;// = host.designer.componentsMap;
21 | // 更新 components 列表
22 | (rendererContainer as any).buildComponents();
23 |
24 | expect(!!(rendererContainer.components as any).Text).toBeTruthy();
25 |
26 | rendererContainer.rerender();
27 |
28 | let tree = component.toJSON();
29 | expect(tree).toMatchSnapshot();
30 | });
31 | })
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/setters/behavior-setter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import BehaviorSetter from '@alilc/lowcode-setter-behavior';
3 |
4 |
5 | const defaultExtraBehaviorActions: any[] = [];
6 | class LocalBehaviorSetter extends React.Component {
7 | render() {
8 | // ignore url && responseFormatter props, use default ones
9 | const { url: propsUrl, responseFormatter: propsFormatter, extraBehaviorActions: propsExtraBehaviorActions = [], ...otherProps } = this.props;
10 | const url = 'https://hn.algolia.com/api/v1/search?query';
11 | const responseFormatter = (response) => response.hits.map((item) => ({
12 | label: item.title,
13 | value: item.author
14 | }));
15 | const extraBehaviorActions = propsExtraBehaviorActions.concat(defaultExtraBehaviorActions);
16 | return (
17 |
23 | );
24 | }
25 | }
26 |
27 | export default LocalBehaviorSetter;
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/setters/behavior-setter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import BehaviorSetter from '@alilc/lowcode-setter-behavior';
3 |
4 |
5 | const defaultExtraBehaviorActions: any[] = [];
6 | class LocalBehaviorSetter extends React.Component {
7 | render() {
8 | // ignore url && responseFormatter props, use default ones
9 | const { url: propsUrl, responseFormatter: propsFormatter, extraBehaviorActions: propsExtraBehaviorActions = [], ...otherProps } = this.props;
10 | const url = 'https://hn.algolia.com/api/v1/search?query';
11 | const responseFormatter = (response) => response.hits.map((item) => ({
12 | label: item.title,
13 | value: item.author
14 | }));
15 | const extraBehaviorActions = propsExtraBehaviorActions.concat(defaultExtraBehaviorActions);
16 | return (
17 |
23 | );
24 | }
25 | }
26 |
27 | export default LocalBehaviorSetter;
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 LowCodeCloud
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Alibaba
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Alibaba
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/jest.config.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const { join } = require('path');
3 | const esModules = ['zen-logger'].join('|');
4 | const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.'));
5 |
6 | const jestConfig = {
7 | // transform: {
8 | // '^.+\\.[jt]sx?$': 'babel-jest',
9 | // // '^.+\\.(ts|tsx)$': 'ts-jest',
10 | // // '^.+\\.(js|jsx)$': 'babel-jest',
11 | // },
12 | // testMatch: ['**/document/node/node.test.ts'],
13 | // testMatch: ['**/designer/builtin-hotkey.test.ts'],
14 | // testMatch: ['**/plugin/plugin-manager.test.ts'],
15 | // testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
16 | transformIgnorePatterns: [
17 | `/node_modules/(?!${esModules})/`,
18 | ],
19 | setupFiles: ['./test/utils/host.ts'],
20 | moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
21 | collectCoverage: true,
22 | collectCoverageFrom: [
23 | 'src/**/*.ts',
24 | '!src/**/*.d.ts',
25 | '!**/node_modules/**',
26 | ],
27 | };
28 |
29 | // 只对本仓库内的 pkg 做 mapping
30 | jestConfig.moduleNameMapper = {};
31 | jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '/../$1/src';
32 |
33 | module.exports = jestConfig;
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/jest.config.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const { join } = require('path');
3 | const esModules = ['zen-logger'].join('|');
4 | const pkgNames = fs.readdirSync(join('..')).filter(pkgName => !pkgName.startsWith('.'));
5 |
6 | const jestConfig = {
7 | // transform: {
8 | // '^.+\\.[jt]sx?$': 'babel-jest',
9 | // // '^.+\\.(ts|tsx)$': 'ts-jest',
10 | // // '^.+\\.(js|jsx)$': 'babel-jest',
11 | // },
12 | // testMatch: ['**/document/node/node.test.ts'],
13 | // testMatch: ['**/designer/builtin-hotkey.test.ts'],
14 | // testMatch: ['**/plugin/plugin-manager.test.ts'],
15 | // testMatch: ['(/tests?/.*(test))\\.[jt]s$'],
16 | transformIgnorePatterns: [
17 | `/node_modules/(?!${esModules})/`,
18 | ],
19 | setupFiles: ['./test/utils/host.ts'],
20 | moduleFileExtensions: ['ts', 'tsx', 'js', 'json'],
21 | collectCoverage: true,
22 | collectCoverageFrom: [
23 | 'src/**/*.ts',
24 | '!src/**/*.d.ts',
25 | '!**/node_modules/**',
26 | ],
27 | };
28 |
29 | // 只对本仓库内的 pkg 做 mapping
30 | jestConfig.moduleNameMapper = {};
31 | jestConfig.moduleNameMapper[`^@alilc/lowcode\\-(${pkgNames.join('|')})$`] = '/../$1/src';
32 |
33 | module.exports = jestConfig;
--------------------------------------------------------------------------------
/packages/vue-renderer-core/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue-renderer-core",
3 | "version": "1.0.0",
4 | "description": "lowcode-engine-vue-renderer-core",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "files": [
8 | "lib",
9 | "es",
10 | "dist"
11 | ],
12 | "scripts": {
13 | "build": "build-scripts build --skip-demo"
14 | },
15 | "keywords": [
16 | "lowcode",
17 | "engine",
18 | "vue"
19 | ],
20 | "dependencies": {
21 | "@alifd/next": "^1.21.16",
22 | "@alilc/lowcode-renderer-core": "^1.0.9",
23 | "@alilc/lowcode-types": "^1.0.9",
24 | "@alilc/lowcode-utils": "^1.0.9",
25 | "react": "^16"
26 | },
27 | "devDependencies": {
28 | "@alib/build-scripts": "^0.1.18",
29 | "@types/node": "^13.7.1",
30 | "@types/react": "^16",
31 | "@types/react-dom": "^16",
32 | "@types/react-router": "^5.1.17",
33 | "build-plugin-component": "^0.2.10",
34 | "react-test-renderer": "^16"
35 | },
36 | "publishConfig": {
37 | "access": "public",
38 | "registry": "https://registry.npmjs.org/"
39 | },
40 | "repository": {
41 | "type": "http",
42 | "url": "https://github.com/lowcodecloud"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "entry": {
3 | "preview": "./src/preview.tsx"
4 | },
5 | "vendor": false,
6 | "devServer": {
7 | "hot": false
8 | },
9 | "publicPath": "/",
10 | "externals": {
11 | "react": "var window.React",
12 | "react-dom": "var window.ReactDOM",
13 | "prop-types": "var window.PropTypes",
14 | "@alifd/next": "var window.Next",
15 | "@alilc/lowcode-engine": "var window.AliLowCodeEngine",
16 | "@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin",
17 | "@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin",
18 | "@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin",
19 | "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
20 | "@ali/lowcode-engine": "var window.AliLowCodeEngine",
21 | "moment": "var window.moment",
22 | "lodash": "var window._",
23 | "vue": "var window.Vue"
24 | },
25 | "plugins": [
26 | [
27 | "build-plugin-react-app"
28 | ],
29 | [
30 | "build-plugin-moment-locales",
31 | {
32 | "locales": [
33 | "zh-cn"
34 | ]
35 | }
36 | ],
37 | "./build.plugin.js"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/build.json:
--------------------------------------------------------------------------------
1 | {
2 | "entry": {
3 | "preview": "./src/preview.tsx"
4 | },
5 | "vendor": false,
6 | "devServer": {
7 | "hot": false
8 | },
9 | "publicPath": "/",
10 | "externals": {
11 | "react": "var window.React",
12 | "react-dom": "var window.ReactDOM",
13 | "prop-types": "var window.PropTypes",
14 | "@alifd/next": "var window.Next",
15 | "@alilc/lowcode-engine": "var window.AliLowCodeEngine",
16 | "@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin",
17 | "@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin",
18 | "@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin",
19 | "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt",
20 | "@ali/lowcode-engine": "var window.AliLowCodeEngine",
21 | "moment": "var window.moment",
22 | "lodash": "var window._",
23 | "vue": "var window.Vue"
24 | },
25 | "plugins": [
26 | [
27 | "build-plugin-react-app"
28 | ],
29 | [
30 | "build-plugin-moment-locales",
31 | {
32 | "locales": [
33 | "zh-cn"
34 | ]
35 | }
36 | ],
37 | "./build.plugin.js"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/universal/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, PingFang SC-Light, Microsoft YaHei;
3 | font-size: 12px;
4 | * {
5 | box-sizing: border-box;
6 | }
7 | }
8 |
9 | body, #lce-container {
10 | position: fixed;
11 | left: 0;
12 | right: 0;
13 | bottom: 0;
14 | top: 0;
15 | box-sizing: border-box;
16 | padding: 0;
17 | margin: 0;
18 | overflow: hidden;
19 | text-rendering: optimizeLegibility;
20 | -webkit-user-select: none;
21 | -webkit-user-drag: none;
22 | -webkit-text-size-adjust: none;
23 | -webkit-touch-callout: none;
24 | -webkit-font-smoothing: antialiased;
25 | #engine {
26 | width: 100%;
27 | height: 100%;
28 | }
29 | }
30 |
31 | html {
32 | min-width: 1024px;
33 | }
34 |
35 | .save-sample {
36 | width: 80px;
37 | height: 30px;
38 | background-color: #5584FF;
39 | border: none;
40 | outline: none;
41 | border-radius: 4px;
42 | color: white;
43 | cursor: pointer;
44 | }
45 |
46 | .load-assets {
47 | width: 100px;
48 | height: 30px;
49 | background-color: #5584FF;
50 | border: none;
51 | outline: none;
52 | border-radius: 4px;
53 | color: white;
54 | cursor: pointer;
55 | }
56 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/universal/global.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, PingFang SC-Light, Microsoft YaHei;
3 | font-size: 12px;
4 | * {
5 | box-sizing: border-box;
6 | }
7 | }
8 |
9 | body, #lce-container {
10 | position: fixed;
11 | left: 0;
12 | right: 0;
13 | bottom: 0;
14 | top: 0;
15 | box-sizing: border-box;
16 | padding: 0;
17 | margin: 0;
18 | overflow: hidden;
19 | text-rendering: optimizeLegibility;
20 | -webkit-user-select: none;
21 | -webkit-user-drag: none;
22 | -webkit-text-size-adjust: none;
23 | -webkit-touch-callout: none;
24 | -webkit-font-smoothing: antialiased;
25 | #engine {
26 | width: 100%;
27 | height: 100%;
28 | }
29 | }
30 |
31 | html {
32 | min-width: 1024px;
33 | }
34 |
35 | .save-sample {
36 | width: 80px;
37 | height: 30px;
38 | background-color: #5584FF;
39 | border: none;
40 | outline: none;
41 | border-radius: 4px;
42 | color: white;
43 | cursor: pointer;
44 | }
45 |
46 | .load-assets {
47 | width: 100px;
48 | height: 30px;
49 | background-color: #5584FF;
50 | border: none;
51 | outline: none;
52 | border-radius: 4px;
53 | color: white;
54 | cursor: pointer;
55 | }
56 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/utils/react-find-dom-nodes.ts:
--------------------------------------------------------------------------------
1 | import { ReactInstance } from 'react';
2 | import { findDOMNode } from 'react-dom';
3 | import { isElement } from '@alilc/lowcode-utils';
4 | import { isDOMNode } from './is-dom-node';
5 |
6 | export const FIBER_KEY = '_reactInternalFiber';
7 |
8 | function elementsFromFiber(fiber: any, elements: Array) {
9 | if (fiber) {
10 | if (fiber.stateNode && isDOMNode(fiber.stateNode)) {
11 | elements.push(fiber.stateNode);
12 | } else if (fiber.child) {
13 | // deep fiberNode.child
14 | elementsFromFiber(fiber.child, elements);
15 | }
16 |
17 | if (fiber.sibling) {
18 | elementsFromFiber(fiber.sibling, elements);
19 | }
20 | }
21 | }
22 |
23 | export function reactFindDOMNodes(elem: ReactInstance | null): Array | null {
24 | if (!elem) {
25 | return null;
26 | }
27 | if (isElement(elem)) {
28 | return [elem];
29 | }
30 | const elements: Array = [];
31 | const fiberNode = (elem as any)[FIBER_KEY];
32 | elementsFromFiber(fiberNode?.child, elements);
33 | if (elements.length > 0) return elements;
34 | try {
35 | return [findDOMNode(elem)];
36 | } catch (e) {
37 | return null;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/utils/react-find-dom-nodes.ts:
--------------------------------------------------------------------------------
1 | import { ReactInstance } from 'react';
2 | import { findDOMNode } from 'react-dom';
3 | import { isElement } from '@alilc/lowcode-utils';
4 | import { isDOMNode } from './is-dom-node';
5 |
6 | export const FIBER_KEY = '_reactInternalFiber';
7 |
8 | function elementsFromFiber(fiber: any, elements: Array) {
9 | if (fiber) {
10 | if (fiber.stateNode && isDOMNode(fiber.stateNode)) {
11 | elements.push(fiber.stateNode);
12 | } else if (fiber.child) {
13 | // deep fiberNode.child
14 | elementsFromFiber(fiber.child, elements);
15 | }
16 |
17 | if (fiber.sibling) {
18 | elementsFromFiber(fiber.sibling, elements);
19 | }
20 | }
21 | }
22 |
23 | export function reactFindDOMNodes(elem: ReactInstance | null): Array | null {
24 | if (!elem) {
25 | return null;
26 | }
27 | if (isElement(elem)) {
28 | return [elem];
29 | }
30 | const elements: Array = [];
31 | const fiberNode = (elem as any)[FIBER_KEY];
32 | elementsFromFiber(fiberNode?.child, elements);
33 | if (elements.length > 0) return elements;
34 | try {
35 | return [findDOMNode(elem)];
36 | } catch (e) {
37 | return null;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/preview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 阿里低代码引擎 Demo - 预览页
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/preview.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 阿里低代码引擎 Demo - 预览页
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/scenarios/index/index.ts:
--------------------------------------------------------------------------------
1 | import { init, plugins } from '@alilc/lowcode-engine';
2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
3 | import registerPlugins from '../../universal/plugin';
4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher';
5 | import '../../universal/global.scss';
6 |
7 | const preference = new Map();
8 | preference.set('DataSourcePane', {
9 | importPlugins: [],
10 | dataSourceTypes: [
11 | {
12 | type: 'fetch',
13 | },
14 | {
15 | type: 'jsonp',
16 | },
17 | ],
18 | });
19 |
20 | (async function main() {
21 | await plugins.register(scenarioSwitcher);
22 | await registerPlugins();
23 |
24 | init(document.getElementById('lce-container')!, {
25 | // designMode: 'live',
26 | // locale: 'zh-CN',
27 | enableCondition: true,
28 | enableCanvasLock: true,
29 | // 默认绑定变量
30 | supportVariableGlobally: true,
31 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!!
32 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径
33 | simulatorUrl: [
34 | './simulator/css/vue2-simulator-renderer.css',
35 | './simulator/js/vue2-simulator-renderer.js',
36 | ],
37 | requestHandlersMap: {
38 | fetch: createFetchHandler(),
39 | },
40 | }, preference);
41 | })();
42 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/scenarios/index/index.ts:
--------------------------------------------------------------------------------
1 | import { init, plugins } from '@alilc/lowcode-engine';
2 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
3 | import registerPlugins from '../../universal/plugin';
4 | import { scenarioSwitcher } from '../../sample-plugins/scenario-switcher';
5 | import '../../universal/global.scss';
6 |
7 | const preference = new Map();
8 | preference.set('DataSourcePane', {
9 | importPlugins: [],
10 | dataSourceTypes: [
11 | {
12 | type: 'fetch',
13 | },
14 | {
15 | type: 'jsonp',
16 | },
17 | ],
18 | });
19 |
20 | (async function main() {
21 | await plugins.register(scenarioSwitcher);
22 | await registerPlugins();
23 |
24 | init(document.getElementById('lce-container')!, {
25 | // designMode: 'live',
26 | // locale: 'zh-CN',
27 | enableCondition: true,
28 | enableCanvasLock: true,
29 | // 默认绑定变量
30 | supportVariableGlobally: true,
31 | // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!!
32 | // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径
33 | simulatorUrl: [
34 | './simulator/css/vue3-simulator-renderer.css',
35 | './simulator/js/vue3-simulator-renderer.js',
36 | ],
37 | requestHandlersMap: {
38 | fetch: createFetchHandler(),
39 | },
40 | }, preference);
41 | })();
42 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/sample-plugins/scenario-switcher/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | ILowCodePluginContext,
4 | } from '@alilc/lowcode-engine';
5 | import { Select } from '@alifd/next';
6 | import scenarios from '../../universal/scenarios.json';
7 | const { Option } = Select;
8 |
9 | const getCurrentScenarioName = () => {
10 | // return 'index'
11 | const list = location.href.split('/');
12 | return list[list.length - 1].replace('.html', '');
13 | }
14 |
15 | function Switcher(props: any) {
16 | return ()
26 | }
27 |
28 | export const scenarioSwitcher = (ctx: ILowCodePluginContext) => {
29 | return {
30 | name: 'scenarioSwitcher',
31 | async init() {
32 | const { skeleton } = ctx;
33 |
34 | skeleton.add({
35 | name: 'scenarioSwitcher',
36 | area: 'topArea',
37 | type: 'Widget',
38 | props: {
39 | align: 'right',
40 | width: 80,
41 | },
42 | content: Switcher,
43 | });
44 | },
45 | };
46 | };
47 | scenarioSwitcher.pluginName = 'scenarioSwitcher';
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/sample-plugins/scenario-switcher/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | ILowCodePluginContext,
4 | } from '@alilc/lowcode-engine';
5 | import { Select } from '@alifd/next';
6 | import scenarios from '../../universal/scenarios.json';
7 | const { Option } = Select;
8 |
9 | const getCurrentScenarioName = () => {
10 | // return 'index'
11 | const list = location.href.split('/');
12 | return list[list.length - 1].replace('.html', '');
13 | }
14 |
15 | function Switcher(props: any) {
16 | return ()
26 | }
27 |
28 | export const scenarioSwitcher = (ctx: ILowCodePluginContext) => {
29 | return {
30 | name: 'scenarioSwitcher',
31 | async init() {
32 | const { skeleton } = ctx;
33 |
34 | skeleton.add({
35 | name: 'scenarioSwitcher',
36 | area: 'topArea',
37 | type: 'Widget',
38 | props: {
39 | align: 'right',
40 | width: 80,
41 | },
42 | content: Switcher,
43 | });
44 | },
45 | };
46 | };
47 | scenarioSwitcher.pluginName = 'scenarioSwitcher';
--------------------------------------------------------------------------------
/packages/vue3-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue3-renderer",
3 | "version": "1.0.0",
4 | "description": "lowcode-engine-vue3-renderer",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "files": [
8 | "lib",
9 | "es",
10 | "dist"
11 | ],
12 | "scripts": {
13 | "start": "build-scripts start",
14 | "build": "build-scripts build --skip-demo",
15 | "build:umd": "build-scripts build --config build.umd.json"
16 | },
17 | "keywords": [
18 | "lowcode",
19 | "engine",
20 | "vue"
21 | ],
22 | "dependencies": {
23 | "@alifd/next": "^1.19.17",
24 | "@alilc/lowcode-renderer-core": "^1.0.9",
25 | "@alilc/lowcode-types": "^1.0.9",
26 | "@alilc/lowcode-utils": "^1.0.9",
27 | "@lowcodecloud/lowcode-engine-vue-renderer-core": "1.0.0",
28 | "react": "^16",
29 | "react-dom": "^16",
30 | "veaury": "^2.0.1",
31 | "vue": "^3.2.37",
32 | "moment": "^2.24.0"
33 | },
34 | "devDependencies": {
35 | "@alib/build-scripts": "^0.1.18",
36 | "@babel/runtime": "^7.18.3",
37 | "@types/node": "^13.7.1",
38 | "@types/react": "^16",
39 | "@types/react-dom": "^16",
40 | "build-plugin-component": "^0.2.10",
41 | "build-plugin-fusion": "^0.1.0",
42 | "build-plugin-moment-locales": "^0.1.0",
43 | "react-test-renderer": "^16"
44 | },
45 | "publishConfig": {
46 | "access": "public",
47 | "registry": "https://registry.npmjs.org/"
48 | },
49 | "repository": {
50 | "type": "http",
51 | "url": "https://github.com/lowcodecloud"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/test/utils/host.ts:
--------------------------------------------------------------------------------
1 | import { Box, Breadcrumb, Form, Select, Input, Button, Table, Pagination, Dialog } from '@alifd/next';
2 | import defaultSchema from '../schema/basic';
3 | import { Page } from './components';
4 |
5 | class Designer {
6 | componentsMap = {
7 | Box,
8 | Breadcrumb,
9 | 'Breadcrumb.Item': Breadcrumb.Item,
10 | Form,
11 | 'Form.Item': Form.Item,
12 | Select,
13 | Input,
14 | Button,
15 | 'Button.Group': Button.Group,
16 | Table,
17 | Pagination,
18 | Dialog,
19 | Page,
20 | }
21 | }
22 |
23 | class Host {
24 | designer = new Designer();
25 |
26 | connect = () => {}
27 |
28 | autorun = (fn: Function) => {
29 | fn();
30 | }
31 |
32 | autoRender = true;
33 |
34 | componentsConsumer = {
35 | consume() {}
36 | }
37 |
38 | schema = defaultSchema;
39 |
40 | project = {
41 | documents: [
42 | {
43 | id: '1',
44 | path: '/',
45 | fileName: '',
46 | export: () => {
47 | return this.schema;
48 | },
49 | getNode: () => {},
50 | }
51 | ],
52 | get: () => ({}),
53 | }
54 |
55 | setInstance() {}
56 |
57 | designMode = 'design'
58 |
59 | get() {}
60 |
61 | injectionConsumer = {
62 | consume() {}
63 | }
64 |
65 | /** 下列的函数或者方法是方便测试用 */
66 | mockSchema = (schema: any) => {
67 | this.schema = schema;
68 | };
69 | }
70 |
71 | if (!(window as any).LCSimulatorHost) {
72 | (window as any).LCSimulatorHost = new Host();
73 | }
74 |
75 | export default (window as any).LCSimulatorHost;
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/test/utils/host.ts:
--------------------------------------------------------------------------------
1 | import { Box, Breadcrumb, Form, Select, Input, Button, Table, Pagination, Dialog } from '@alifd/next';
2 | import defaultSchema from '../schema/basic';
3 | import { Page } from './components';
4 |
5 | class Designer {
6 | componentsMap = {
7 | Box,
8 | Breadcrumb,
9 | 'Breadcrumb.Item': Breadcrumb.Item,
10 | Form,
11 | 'Form.Item': Form.Item,
12 | Select,
13 | Input,
14 | Button,
15 | 'Button.Group': Button.Group,
16 | Table,
17 | Pagination,
18 | Dialog,
19 | Page,
20 | }
21 | }
22 |
23 | class Host {
24 | designer = new Designer();
25 |
26 | connect = () => {}
27 |
28 | autorun = (fn: Function) => {
29 | fn();
30 | }
31 |
32 | autoRender = true;
33 |
34 | componentsConsumer = {
35 | consume() {}
36 | }
37 |
38 | schema = defaultSchema;
39 |
40 | project = {
41 | documents: [
42 | {
43 | id: '1',
44 | path: '/',
45 | fileName: '',
46 | export: () => {
47 | return this.schema;
48 | },
49 | getNode: () => {},
50 | }
51 | ],
52 | get: () => ({}),
53 | }
54 |
55 | setInstance() {}
56 |
57 | designMode = 'design'
58 |
59 | get() {}
60 |
61 | injectionConsumer = {
62 | consume() {}
63 | }
64 |
65 | /** 下列的函数或者方法是方便测试用 */
66 | mockSchema = (schema: any) => {
67 | this.schema = schema;
68 | };
69 | }
70 |
71 | if (!(window as any).LCSimulatorHost) {
72 | (window as any).LCSimulatorHost = new Host();
73 | }
74 |
75 | export default (window as any).LCSimulatorHost;
--------------------------------------------------------------------------------
/packages/vue2-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue2-renderer",
3 | "version": "1.0.0",
4 | "description": "lowcode-engine-vue2-renderer",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "files": [
8 | "lib",
9 | "es",
10 | "dist"
11 | ],
12 | "scripts": {
13 | "start": "build-scripts start",
14 | "build": "build-scripts build --skip-demo",
15 | "build:umd": "build-scripts build --config build.umd.json"
16 | },
17 | "keywords": [
18 | "lowcode",
19 | "engine",
20 | "vue"
21 | ],
22 | "dependencies": {
23 | "@alifd/next": "^1.19.17",
24 | "@alilc/lowcode-renderer-core": "^1.0.9",
25 | "@alilc/lowcode-types": "^1.0.9",
26 | "@alilc/lowcode-utils": "^1.0.9",
27 | "@lowcodecloud/lowcode-engine-vue-renderer-core": "1.0.0",
28 | "react": "^16",
29 | "react-dom": "^16",
30 | "vuereact-combined": "^1.2.5",
31 | "moment": "^2.24.0",
32 | "vue": "^2.6.0"
33 | },
34 | "devDependencies": {
35 | "@alib/build-scripts": "^0.1.18",
36 | "@babel/runtime": "^7.18.3",
37 | "@types/node": "^13.7.1",
38 | "@types/react": "^16",
39 | "@types/react-dom": "^16",
40 | "build-plugin-component": "^0.2.10",
41 | "build-plugin-fusion": "^0.1.0",
42 | "build-plugin-moment-locales": "^0.1.0",
43 | "react-test-renderer": "^16"
44 | },
45 | "publishConfig": {
46 | "access": "public",
47 | "registry": "https://registry.npmjs.org/"
48 | },
49 | "repository": {
50 | "type": "http",
51 | "url": "https://github.com/lowcodecloud"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/builtin-components/slot.tsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'react';
2 |
3 | class Slot extends Component {
4 | static displayName = 'Slot';
5 |
6 | static componentMetadata = {
7 | componentName: 'Slot',
8 | configure: {
9 | props: [
10 | {
11 | name: '___title',
12 | title: {
13 | type: 'i18n',
14 | 'en-US': 'Slot Title',
15 | 'zh-CN': '插槽标题',
16 | },
17 | setter: 'StringSetter',
18 | defaultValue: '插槽容器',
19 | },
20 | {
21 | name: '___params',
22 | title: {
23 | type: 'i18n',
24 | 'en-US': 'Slot Params',
25 | 'zh-CN': '插槽入参',
26 | },
27 | setter: {
28 | componentName: 'ArraySetter',
29 | props: {
30 | itemSetter: {
31 | componentName: 'StringSetter',
32 | props: {
33 | placeholder: {
34 | type: 'i18n',
35 | 'zh-CN': '参数名称',
36 | 'en-US': 'Argument Name',
37 | },
38 | },
39 | },
40 | },
41 | },
42 | },
43 | ],
44 | component: {
45 | isContainer: true,
46 | },
47 | // events/className/style/general/directives
48 | supports: false,
49 | },
50 | };
51 |
52 | render() {
53 | const { children } = this.props;
54 | return {children}
;
55 | }
56 | }
57 |
58 | export default Slot;
59 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/builtin-components/slot.tsx:
--------------------------------------------------------------------------------
1 | import { Component } from 'react';
2 |
3 | class Slot extends Component {
4 | static displayName = 'Slot';
5 |
6 | static componentMetadata = {
7 | componentName: 'Slot',
8 | configure: {
9 | props: [
10 | {
11 | name: '___title',
12 | title: {
13 | type: 'i18n',
14 | 'en-US': 'Slot Title',
15 | 'zh-CN': '插槽标题',
16 | },
17 | setter: 'StringSetter',
18 | defaultValue: '插槽容器',
19 | },
20 | {
21 | name: '___params',
22 | title: {
23 | type: 'i18n',
24 | 'en-US': 'Slot Params',
25 | 'zh-CN': '插槽入参',
26 | },
27 | setter: {
28 | componentName: 'ArraySetter',
29 | props: {
30 | itemSetter: {
31 | componentName: 'StringSetter',
32 | props: {
33 | placeholder: {
34 | type: 'i18n',
35 | 'zh-CN': '参数名称',
36 | 'en-US': 'Argument Name',
37 | },
38 | },
39 | },
40 | },
41 | },
42 | },
43 | ],
44 | component: {
45 | isContainer: true,
46 | },
47 | // events/className/style/general/directives
48 | supports: false,
49 | },
50 | };
51 |
52 | render() {
53 | const { children } = this.props;
54 | return {children}
;
55 | }
56 | }
57 |
58 | export default Slot;
59 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'eslint-config-ali/typescript/react',
3 | parserOptions: {
4 | project: [], // for lint performance
5 | createDefaultProgram: false, // for lint performance
6 | },
7 | rules: {
8 | 'react/no-multi-comp': 0,
9 | 'no-unused-expressions': 0,
10 | 'implicit-arrow-linebreak': 1,
11 | 'no-nested-ternary': 1,
12 | 'no-mixed-operators': 1,
13 | '@typescript-eslint/ban-types': 1,
14 | 'no-shadow': 1,
15 | 'no-prototype-builtins': 1,
16 | 'no-useless-constructor': 1,
17 | 'no-empty-function': 1,
18 | '@typescript-eslint/member-ordering': 0,
19 | 'lines-between-class-members': 0,
20 | 'no-await-in-loop': 0,
21 | 'no-plusplus': 0,
22 | '@typescript-eslint/no-parameter-properties': 0,
23 | '@typescript-eslint/no-unused-vars': 1,
24 | 'no-multi-assign': 1,
25 | 'no-dupe-class-members': 1,
26 | 'react/no-deprecated': 1,
27 | 'no-useless-escape': 1,
28 | 'brace-style': 1,
29 | '@typescript-eslint/no-inferrable-types': 0,
30 | 'no-proto': 0,
31 | 'prefer-const': 0,
32 | 'eol-last': 0,
33 | 'react/no-find-dom-node': 0,
34 | 'no-case-declarations': 0,
35 | '@typescript-eslint/indent': 0,
36 | 'import/no-cycle': 0,
37 | '@typescript-eslint/no-shadow': 0,
38 | "@typescript-eslint/method-signature-style": 0,
39 | "@typescript-eslint/consistent-type-assertions": 0,
40 | "@typescript-eslint/no-useless-constructor": 0,
41 | '@typescript-eslint/dot-notation': 0, // for lint performance
42 | '@typescript-eslint/restrict-plus-operands': 0, // for lint performance
43 | }
44 | };
45 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/.gitignore:
--------------------------------------------------------------------------------
1 | # project custom
2 | build
3 | dist
4 |
5 |
6 | # IDE
7 | .vscode
8 | .idea
9 |
10 | # Logs
11 | logs
12 | *.log
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 | lerna-debug.log*
17 |
18 | # Runtime data
19 | pids
20 | *.pid
21 | *.seed
22 | *.pid.lock
23 |
24 |
25 | # Directory for instrumented libs generated by jscoverage/JSCover
26 | lib-cov
27 |
28 | # Coverage directory used by tools like istanbul
29 | coverage
30 |
31 | # nyc test coverage
32 | .nyc_output
33 |
34 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
35 | .grunt
36 |
37 | # Bower dependency directory (https://bower.io/)
38 | bower_components
39 |
40 | # node-waf configuration
41 | .lock-wscript
42 |
43 | # Compiled binary addons (https://nodejs.org/api/addons.html)
44 | build/Release
45 | lib
46 |
47 | # Dependency directories
48 | node_modules/
49 | jspm_packages/
50 |
51 | # TypeScript v1 declaration files
52 | typings/
53 |
54 | # Optional npm cache directory
55 | .npm
56 |
57 | # Optional eslint cache
58 | .eslintcache
59 |
60 | # Optional REPL history
61 | .node_repl_history
62 |
63 | # Output of 'npm pack'
64 | *.tgz
65 |
66 | # Yarn Integrity file
67 | .yarn-integrity
68 |
69 | # dotenv environment variables file
70 | .env
71 | .env.test
72 |
73 | # parcel-bundler cache (https://parceljs.org/)
74 | .cache
75 |
76 | # next.js build output
77 | .next
78 |
79 | # nuxt.js build output
80 | .nuxt
81 |
82 | # vuepress build output
83 | .vuepress/dist
84 |
85 | # Serverless directories
86 | .serverless/
87 |
88 | # FuseBox cache
89 | .fusebox/
90 |
91 | # DynamoDB Local files
92 | .dynamodb/
93 |
94 | # mac config files
95 | .DS_Store
96 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/.gitignore:
--------------------------------------------------------------------------------
1 | # project custom
2 | build
3 | dist
4 |
5 |
6 | # IDE
7 | .vscode
8 | .idea
9 |
10 | # Logs
11 | logs
12 | *.log
13 | npm-debug.log*
14 | yarn-debug.log*
15 | yarn-error.log*
16 | lerna-debug.log*
17 |
18 | # Runtime data
19 | pids
20 | *.pid
21 | *.seed
22 | *.pid.lock
23 |
24 |
25 | # Directory for instrumented libs generated by jscoverage/JSCover
26 | lib-cov
27 |
28 | # Coverage directory used by tools like istanbul
29 | coverage
30 |
31 | # nyc test coverage
32 | .nyc_output
33 |
34 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
35 | .grunt
36 |
37 | # Bower dependency directory (https://bower.io/)
38 | bower_components
39 |
40 | # node-waf configuration
41 | .lock-wscript
42 |
43 | # Compiled binary addons (https://nodejs.org/api/addons.html)
44 | build/Release
45 | lib
46 |
47 | # Dependency directories
48 | node_modules/
49 | jspm_packages/
50 |
51 | # TypeScript v1 declaration files
52 | typings/
53 |
54 | # Optional npm cache directory
55 | .npm
56 |
57 | # Optional eslint cache
58 | .eslintcache
59 |
60 | # Optional REPL history
61 | .node_repl_history
62 |
63 | # Output of 'npm pack'
64 | *.tgz
65 |
66 | # Yarn Integrity file
67 | .yarn-integrity
68 |
69 | # dotenv environment variables file
70 | .env
71 | .env.test
72 |
73 | # parcel-bundler cache (https://parceljs.org/)
74 | .cache
75 |
76 | # next.js build output
77 | .next
78 |
79 | # nuxt.js build output
80 | .nuxt
81 |
82 | # vuepress build output
83 | .vuepress/dist
84 |
85 | # Serverless directories
86 | .serverless/
87 |
88 | # FuseBox cache
89 | .fusebox/
90 |
91 | # DynamoDB Local files
92 | .dynamodb/
93 |
94 | # mac config files
95 | .DS_Store
96 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue2-simulator-renderer",
3 | "version": "1.0.9",
4 | "description": "lowcode-engine-vue2-simulator-renderer",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "license": "MIT",
8 | "files": [
9 | "es",
10 | "lib",
11 | "dist"
12 | ],
13 | "scripts": {
14 | "test": "build-scripts test --config build.test.json",
15 | "build": "build-scripts build --skip-demo",
16 | "build:umd": "build-scripts build --config build.umd.json"
17 | },
18 | "dependencies": {
19 | "@alilc/lowcode-designer": "^1.0.9",
20 | "@alilc/lowcode-react-renderer": "^1.0.9",
21 | "@alilc/lowcode-types": "^1.0.9",
22 | "@alilc/lowcode-utils": "^1.0.9",
23 | "@lowcodecloud/lowcode-engine-vue2-renderer": "1.0.0",
24 | "classnames": "^2.2.6",
25 | "history": "^5.3.0",
26 | "lodash": "^4.17.21",
27 | "mobx": "^6.3.0",
28 | "mobx-react": "^7.2.0",
29 | "react": "^16",
30 | "react-dom": "^16.7.0",
31 | "react-router": "^5.2.1",
32 | "tslib": "^2.4.0"
33 | },
34 | "devDependencies": {
35 | "@alib/build-scripts": "^0.1.18",
36 | "@babel/runtime": "^7.18.3",
37 | "@types/classnames": "^2.2.7",
38 | "@types/lodash": "^4.14.182",
39 | "@types/node": "^13.7.1",
40 | "@types/react": "^16",
41 | "@types/react-dom": "^16",
42 | "@types/react-router": "^5.1.17",
43 | "build-plugin-component": "^0.2.11"
44 | },
45 | "publishConfig": {
46 | "access": "public",
47 | "registry": "https://registry.npmjs.org/"
48 | },
49 | "repository": {
50 | "type": "http",
51 | "url": "https://github.com/lowcodecloud"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-engine-vue3-simulator-renderer",
3 | "version": "1.0.9",
4 | "description": "lowcode-engine-vue3-simulator-renderer",
5 | "main": "lib/index.js",
6 | "module": "es/index.js",
7 | "license": "MIT",
8 | "files": [
9 | "es",
10 | "lib",
11 | "dist"
12 | ],
13 | "scripts": {
14 | "test": "build-scripts test --config build.test.json",
15 | "build": "build-scripts build --skip-demo",
16 | "build:umd": "build-scripts build --config build.umd.json"
17 | },
18 | "dependencies": {
19 | "@alilc/lowcode-designer": "^1.0.9",
20 | "@alilc/lowcode-react-renderer": "^1.0.9",
21 | "@alilc/lowcode-types": "^1.0.9",
22 | "@alilc/lowcode-utils": "^1.0.9",
23 | "@lowcodecloud/lowcode-engine-vue3-renderer": "1.0.0",
24 | "classnames": "^2.2.6",
25 | "history": "^5.3.0",
26 | "lodash": "^4.17.21",
27 | "mobx": "^6.3.0",
28 | "mobx-react": "^7.2.0",
29 | "react": "^16",
30 | "react-dom": "^16.7.0",
31 | "react-router": "^5.2.1",
32 | "tslib": "^2.4.0"
33 | },
34 | "devDependencies": {
35 | "@alib/build-scripts": "^0.1.18",
36 | "@babel/runtime": "^7.18.3",
37 | "@types/classnames": "^2.2.7",
38 | "@types/lodash": "^4.14.182",
39 | "@types/node": "^13.7.1",
40 | "@types/react": "^16",
41 | "@types/react-dom": "^16",
42 | "@types/react-router": "^5.1.17",
43 | "build-plugin-component": "^0.2.11"
44 | },
45 | "publishConfig": {
46 | "access": "public",
47 | "registry": "https://registry.npmjs.org/"
48 | },
49 | "repository": {
50 | "type": "http",
51 | "url": "https://github.com/lowcodecloud"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/packages/vue2-renderer/src/create-element/adaptive-create-element.ts:
--------------------------------------------------------------------------------
1 | import { createElement as reactCreateElement } from 'react';
2 |
3 | import { vueRendererExtTypes } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
4 |
5 | import vue2CreateElement from './vue2-create-element';
6 |
7 | class AdaptiveCreateElementAdapter implements vueRendererExtTypes.CreateElementAdapter {
8 | createElement(component: any, props: any, ...children: any): any {
9 | if (!component) {
10 | return reactCreateElement(component, props, ...children);
11 | }
12 | let { $$devStack } = component;
13 |
14 | if ($$devStack === undefined) {
15 | return reactCreateElement(component, props, ...children);
16 | }
17 |
18 | switch ($$devStack as vueRendererExtTypes.DevStack) {
19 | case vueRendererExtTypes.DevStack.React:
20 | return reactCreateElement(component, props, ...children);
21 | case vueRendererExtTypes.DevStack.Vue:
22 | if (component.render && typeof component.render.toString === 'function' && !component.render.toString().startsWith('function()')) {
23 | return reactCreateElement(component, props, ...children);
24 | }
25 | return vue2CreateElement(component, props, ...children);
26 | case vueRendererExtTypes.DevStack.Vue2:
27 | if (component.render && typeof component.render.toString === 'function' && !component.render.toString().startsWith('function()')) {
28 | return reactCreateElement(component, props, ...children);
29 | }
30 | return vue2CreateElement(component, props, ...children);
31 | default:
32 | return reactCreateElement(component, props, ...children);
33 | }
34 | }
35 | }
36 |
37 | export default new AdaptiveCreateElementAdapter().createElement;
38 |
--------------------------------------------------------------------------------
/packages/vue3-renderer/src/create-element/adaptive-create-element.ts:
--------------------------------------------------------------------------------
1 | import { createElement as reactCreateElement } from 'react';
2 |
3 | import { vueRendererExtTypes } from '@lowcodecloud/lowcode-engine-vue-renderer-core';
4 |
5 | import vue2CreateElement from './vue3-create-element';
6 |
7 | class AdaptiveCreateElementAdapter implements vueRendererExtTypes.CreateElementAdapter {
8 | createElement(component: any, props: any, ...children: any): any {
9 | if (!component) {
10 | return reactCreateElement(component, props, ...children);
11 | }
12 | let { $$devStack } = component;
13 |
14 | if ($$devStack === undefined) {
15 | return reactCreateElement(component, props, ...children);
16 | }
17 |
18 | switch ($$devStack as vueRendererExtTypes.DevStack) {
19 | case vueRendererExtTypes.DevStack.React:
20 | return reactCreateElement(component, props, ...children);
21 | case vueRendererExtTypes.DevStack.Vue:
22 | if (component.render && typeof component.render.toString === 'function' && !component.render.toString().startsWith('function()')) {
23 | return reactCreateElement(component, props, ...children);
24 | }
25 | return vue2CreateElement(component, props, ...children);
26 | case vueRendererExtTypes.DevStack.Vue2:
27 | if (component.render && typeof component.render.toString === 'function' && !component.render.toString().startsWith('function()')) {
28 | return reactCreateElement(component, props, ...children);
29 | }
30 | return vue2CreateElement(component, props, ...children);
31 | default:
32 | return reactCreateElement(component, props, ...children);
33 | }
34 | }
35 | }
36 |
37 | export default new AdaptiveCreateElementAdapter().createElement;
38 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "lib": [
5 | "es2015",
6 | "dom"
7 | ],
8 | // Target latest version of ECMAScript.
9 | "target": "esnext",
10 | // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
11 | "module": "esnext",
12 | // Search under node_modules for non-relative imports.
13 | "moduleResolution": "node",
14 | // Enable strictest settings like strictNullChecks & noImplicitAny.
15 | "strict": true,
16 | "strictPropertyInitialization": false,
17 | // Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
18 | "allowSyntheticDefaultImports": true,
19 | // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.
20 | "esModuleInterop": true,
21 | // Specify JSX code generation: 'preserve', 'react-native', or 'react'.
22 | "jsx": "preserve",
23 | // Import emit helpers (e.g. __extends, __rest, etc..) from tslib
24 | "importHelpers": true,
25 | // Enables experimental support for ES7 decorators.
26 | "experimentalDecorators": true,
27 | "emitDecoratorMetadata": true,
28 | // Generates corresponding .map file.
29 | "sourceMap": true,
30 | // Disallow inconsistently-cased references to the same file.
31 | "forceConsistentCasingInFileNames": true,
32 | // Allow json import
33 | "resolveJsonModule": true,
34 | // skip type checking of declaration files
35 | "skipLibCheck": true,
36 | "useDefineForClassFields": true,
37 | "baseUrl": "./",
38 | "outDir": "lib"
39 | },
40 | "exclude": [
41 | "**/dist",
42 | "**/build",
43 | "**/lib",
44 | "**/es",
45 | "node_modules"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "declaration": true,
5 | "lib": ["es2015", "dom"],
6 | // Target latest version of ECMAScript.
7 | "target": "esnext",
8 | // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
9 | "module": "esnext",
10 | // Search under node_modules for non-relative imports.
11 | "moduleResolution": "node",
12 | // Process & infer types from .js files.
13 | "allowJs": true,
14 | // Report errors in .js files.
15 | "checkJs": false,
16 | // Don't emit; allow Babel to transform files.
17 | // "noEmit": true,
18 | // Enable strictest settings like strictNullChecks & noImplicitAny.
19 | "strict": true,
20 | // Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
21 | "allowSyntheticDefaultImports": true,
22 | // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.
23 | "esModuleInterop": true,
24 | // Specify JSX code generation: 'preserve', 'react-native', or 'react'.
25 | "jsx": "preserve",
26 | // Import emit helpers (e.g. __extends, __rest, etc..) from tslib
27 | "importHelpers": true,
28 | // Enables experimental support for ES7 decorators.
29 | "experimentalDecorators": true,
30 | // Generates corresponding .map file.
31 | "sourceMap": true,
32 | // Disallow inconsistently-cased references to the same file.
33 | "forceConsistentCasingInFileNames": true,
34 | // Allow json import
35 | "resolveJsonModule": true,
36 | // skip type checking of declaration files
37 | "skipLibCheck": true,
38 | "outDir": "lib"
39 | },
40 | "include": [
41 | "./src/"
42 | ],
43 | "exclude": ["**/test", "**/lib", "**/es", "node_modules"]
44 | }
45 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "declaration": true,
5 | "lib": ["es2015", "dom"],
6 | // Target latest version of ECMAScript.
7 | "target": "esnext",
8 | // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.
9 | "module": "esnext",
10 | // Search under node_modules for non-relative imports.
11 | "moduleResolution": "node",
12 | // Process & infer types from .js files.
13 | "allowJs": true,
14 | // Report errors in .js files.
15 | "checkJs": false,
16 | // Don't emit; allow Babel to transform files.
17 | // "noEmit": true,
18 | // Enable strictest settings like strictNullChecks & noImplicitAny.
19 | "strict": true,
20 | // Allow default imports from modules with no default export. This does not affect code emit, just typechecking.
21 | "allowSyntheticDefaultImports": true,
22 | // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.
23 | "esModuleInterop": true,
24 | // Specify JSX code generation: 'preserve', 'react-native', or 'react'.
25 | "jsx": "preserve",
26 | // Import emit helpers (e.g. __extends, __rest, etc..) from tslib
27 | "importHelpers": true,
28 | // Enables experimental support for ES7 decorators.
29 | "experimentalDecorators": true,
30 | // Generates corresponding .map file.
31 | "sourceMap": true,
32 | // Disallow inconsistently-cased references to the same file.
33 | "forceConsistentCasingInFileNames": true,
34 | // Allow json import
35 | "resolveJsonModule": true,
36 | // skip type checking of declaration files
37 | "skipLibCheck": true,
38 | "outDir": "lib"
39 | },
40 | "include": [
41 | "./src/"
42 | ],
43 | "exclude": ["**/test", "**/lib", "**/es", "node_modules"]
44 | }
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # project custom
2 | build
3 | dist
4 | packages/*/lib/
5 | packages/*/es/
6 | packages/*/dist/
7 | packages/*/output/
8 | packages/demo/
9 | package-lock.json
10 | yarn.lock
11 | deploy-space/packages
12 | deploy-space/.env
13 |
14 |
15 | # IDE
16 | .vscode
17 | .idea
18 |
19 | # Logs
20 | logs
21 | *.log
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 | lerna-debug.log*
26 |
27 | # Runtime data
28 | pids
29 | *.pid
30 | *.seed
31 | *.pid.lock
32 |
33 |
34 | # Directory for instrumented libs generated by jscoverage/JSCover
35 | lib-cov
36 |
37 | # Coverage directory used by tools like istanbul
38 | coverage
39 |
40 | # nyc test coverage
41 | .nyc_output
42 |
43 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
44 | .grunt
45 |
46 | # Bower dependency directory (https://bower.io/)
47 | bower_components
48 |
49 | # node-waf configuration
50 | .lock-wscript
51 |
52 | # Compiled binary addons (https://nodejs.org/api/addons.html)
53 | build/Release
54 | lib
55 |
56 | # Dependency directories
57 | node_modules/
58 | jspm_packages/
59 |
60 | # TypeScript v1 declaration files
61 | typings/
62 |
63 | # Optional npm cache directory
64 | .npm
65 |
66 | # pnpm
67 | pnpm-lock.yaml
68 |
69 | # Optional eslint cache
70 | .eslintcache
71 |
72 | # Optional REPL history
73 | .node_repl_history
74 |
75 | # Output of 'npm pack'
76 | *.tgz
77 |
78 | # Yarn Integrity file
79 | .yarn-integrity
80 |
81 | # dotenv environment variables file
82 | .env
83 | .env.test
84 |
85 | # parcel-bundler cache (https://parceljs.org/)
86 | .cache
87 |
88 | # next.js build output
89 | .next
90 |
91 | # nuxt.js build output
92 | .nuxt
93 |
94 | # vuepress build output
95 | .vuepress/dist
96 |
97 | # Serverless directories
98 | .serverless/
99 |
100 | # FuseBox cache
101 | .fusebox/
102 |
103 | # DynamoDB Local files
104 | .dynamodb/
105 |
106 | # mac config files
107 | .DS_Store
108 |
109 | # codealike
110 | codealike.json
111 | .node
112 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/renderer.less:
--------------------------------------------------------------------------------
1 | body, html {
2 | display: block;
3 | background: white;
4 | padding: 0;
5 | margin: 0;
6 | }
7 |
8 | html.engine-design-mode {
9 | padding-bottom: 0;
10 | }
11 |
12 | html.engine-cursor-move, html.engine-cursor-move * {
13 | cursor: grabbing !important;
14 | }
15 |
16 | html.engine-cursor-copy, html.engine-cursor-copy * {
17 | cursor: copy !important;
18 | }
19 |
20 | html.engine-cursor-ew-resize, html.engine-cursor-ew-resize * {
21 | cursor: ew-resize !important;
22 | }
23 |
24 | ::-webkit-scrollbar {
25 | width: 5px;
26 | height: 5px;
27 | }
28 |
29 | ::-webkit-scrollbar-thumb {
30 | background-color: rgba(0, 0, 0, 0.3);
31 | border-radius: 5px;
32 | }
33 |
34 | .lc-container {
35 | &:empty {
36 | background: #f2f3f5;
37 | color: #a7b1bd;
38 | outline: 1px dashed rgba(31, 56, 88, 0.2);
39 | outline-offset: -1px !important;
40 | height: 66px;
41 | max-height: 100%;
42 | min-width: 140px;
43 | text-align: center;
44 | overflow: hidden;
45 | display: flex;
46 | align-items: center;
47 | &:before {
48 | content: '\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC';
49 | font-size: 14px;
50 | z-index: 1;
51 | width: 100%;
52 | white-space: nowrap;
53 | }
54 | }
55 | }
56 |
57 | .lc-container-placeholder {
58 | min-height: 60px;
59 | height: 100%;
60 | width: 100%;
61 | background-color: rgb(240, 240, 240);
62 | border: 1px dotted;
63 | color: rgb(167, 177, 189);
64 | display: flex;
65 | align-items: center;
66 | justify-content: center;
67 | font-size: 14px;
68 |
69 | &.lc-container-locked {
70 | background: #eccfcf;
71 | }
72 | }
73 |
74 | body.engine-document {
75 | &:after, &:before {
76 | content: "";
77 | display: table;
78 | }
79 | &:after {
80 | clear: both;
81 | }
82 | }
83 |
84 | .engine-live-editing {
85 | cursor: text;
86 | outline: none;
87 | box-shadow: 0 0 0 2px rgb(102, 188, 92);
88 | user-select: text;
89 | }
90 |
91 | #app {
92 | height: 100vh;
93 | }
94 |
95 |
96 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/renderer.less:
--------------------------------------------------------------------------------
1 | body, html {
2 | display: block;
3 | background: white;
4 | padding: 0;
5 | margin: 0;
6 | }
7 |
8 | html.engine-design-mode {
9 | padding-bottom: 0;
10 | }
11 |
12 | html.engine-cursor-move, html.engine-cursor-move * {
13 | cursor: grabbing !important;
14 | }
15 |
16 | html.engine-cursor-copy, html.engine-cursor-copy * {
17 | cursor: copy !important;
18 | }
19 |
20 | html.engine-cursor-ew-resize, html.engine-cursor-ew-resize * {
21 | cursor: ew-resize !important;
22 | }
23 |
24 | ::-webkit-scrollbar {
25 | width: 5px;
26 | height: 5px;
27 | }
28 |
29 | ::-webkit-scrollbar-thumb {
30 | background-color: rgba(0, 0, 0, 0.3);
31 | border-radius: 5px;
32 | }
33 |
34 | .lc-container {
35 | &:empty {
36 | background: #f2f3f5;
37 | color: #a7b1bd;
38 | outline: 1px dashed rgba(31, 56, 88, 0.2);
39 | outline-offset: -1px !important;
40 | height: 66px;
41 | max-height: 100%;
42 | min-width: 140px;
43 | text-align: center;
44 | overflow: hidden;
45 | display: flex;
46 | align-items: center;
47 | &:before {
48 | content: '\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC';
49 | font-size: 14px;
50 | z-index: 1;
51 | width: 100%;
52 | white-space: nowrap;
53 | }
54 | }
55 | }
56 |
57 | .lc-container-placeholder {
58 | min-height: 60px;
59 | height: 100%;
60 | width: 100%;
61 | background-color: rgb(240, 240, 240);
62 | border: 1px dotted;
63 | color: rgb(167, 177, 189);
64 | display: flex;
65 | align-items: center;
66 | justify-content: center;
67 | font-size: 14px;
68 |
69 | &.lc-container-locked {
70 | background: #eccfcf;
71 | }
72 | }
73 |
74 | body.engine-document {
75 | &:after, &:before {
76 | content: "";
77 | display: table;
78 | }
79 | &:after {
80 | clear: both;
81 | }
82 | }
83 |
84 | .engine-live-editing {
85 | cursor: text;
86 | outline: none;
87 | box-shadow: 0 0 0 2px rgb(102, 188, 92);
88 | user-select: text;
89 | }
90 |
91 | #app {
92 | height: 100vh;
93 | }
94 |
95 |
96 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/fixtures/basic-fusion-with-single-component/view.js:
--------------------------------------------------------------------------------
1 | !function e(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.M220318=n():t.M220318=n()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function t(){return e.default}:function t(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=345)}({3:function(e,t){e.exports=window.React},345:function(e,t,n){e.exports=n(429)},346:function(e,t,n){},429:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return l}));var r={};n.r(r),n.d(r,"default",(function(){return l}));var o=n(3),u=function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols)for(var o=0,r=Object.getOwnPropertySymbols(e);o {
20 | const parts = param.replace(/\+/g, ' ').split('=');
21 | let key = parts.shift()!;
22 | let val: any = parts.length > 0 ? parts.join('=') : undefined;
23 |
24 | key = decodeURIComponent(key);
25 |
26 | val = val === undefined ? null : decodeURIComponent(val);
27 |
28 | if (ret[key] === undefined) {
29 | ret[key] = val;
30 | } else if (Array.isArray(ret[key])) {
31 | ret[key].push(val);
32 | } else {
33 | ret[key] = [ret[key], val];
34 | }
35 | });
36 |
37 | return ret;
38 | }
39 |
40 | /**
41 | * Stringify object to query parammeters
42 | * @param {Object} obj
43 | * @return {String}
44 | */
45 | export function stringifyQuery(obj: any): string {
46 | const param: string[] = [];
47 | Object.keys(obj).forEach((key) => {
48 | let value = obj[key];
49 | if (value && typeof value === 'object') {
50 | value = JSON.stringify(value);
51 | }
52 | param.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
53 | });
54 | return param.join('&');
55 | }
56 |
57 | export function uriEncode(uri: string) {
58 | return encodeURIComponent(uri);
59 | }
60 |
61 | export function uriDecode(uri: string) {
62 | return decodeURIComponent(uri);
63 | }
64 |
65 | export function withQueryParams(url: string, params?: object) {
66 | const queryStr = params ? stringifyQuery(params) : '';
67 | if (queryStr === '') {
68 | return url;
69 | }
70 | const urlSplit = url.split('#');
71 | const hash = urlSplit[1] ? `#${urlSplit[1]}` : '';
72 | const urlWithoutHash = urlSplit[0];
73 | return `${urlWithoutHash}${~urlWithoutHash.indexOf('?') ? '&' : '?'}${queryStr}${hash}`;
74 | }
75 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/utils/url.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Parse queryString
3 | * @param {String} str '?q=query&b=test'
4 | * @return {Object}
5 | */
6 | export function parseQuery(str: string): object {
7 | const ret: any = {};
8 |
9 | if (typeof str !== 'string') {
10 | return ret;
11 | }
12 |
13 | const s = str.trim().replace(/^(\?|#|&)/, '');
14 |
15 | if (!s) {
16 | return ret;
17 | }
18 |
19 | s.split('&').forEach((param) => {
20 | const parts = param.replace(/\+/g, ' ').split('=');
21 | let key = parts.shift()!;
22 | let val: any = parts.length > 0 ? parts.join('=') : undefined;
23 |
24 | key = decodeURIComponent(key);
25 |
26 | val = val === undefined ? null : decodeURIComponent(val);
27 |
28 | if (ret[key] === undefined) {
29 | ret[key] = val;
30 | } else if (Array.isArray(ret[key])) {
31 | ret[key].push(val);
32 | } else {
33 | ret[key] = [ret[key], val];
34 | }
35 | });
36 |
37 | return ret;
38 | }
39 |
40 | /**
41 | * Stringify object to query parammeters
42 | * @param {Object} obj
43 | * @return {String}
44 | */
45 | export function stringifyQuery(obj: any): string {
46 | const param: string[] = [];
47 | Object.keys(obj).forEach((key) => {
48 | let value = obj[key];
49 | if (value && typeof value === 'object') {
50 | value = JSON.stringify(value);
51 | }
52 | param.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
53 | });
54 | return param.join('&');
55 | }
56 |
57 | export function uriEncode(uri: string) {
58 | return encodeURIComponent(uri);
59 | }
60 |
61 | export function uriDecode(uri: string) {
62 | return decodeURIComponent(uri);
63 | }
64 |
65 | export function withQueryParams(url: string, params?: object) {
66 | const queryStr = params ? stringifyQuery(params) : '';
67 | if (queryStr === '') {
68 | return url;
69 | }
70 | const urlSplit = url.split('#');
71 | const hash = urlSplit[1] ? `#${urlSplit[1]}` : '';
72 | const urlWithoutHash = urlSplit[0];
73 | return `${urlWithoutHash}${~urlWithoutHash.indexOf('?') ? '&' : '?'}${queryStr}${hash}`;
74 | }
75 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-vue2-demo",
3 | "version": "1.0.0",
4 | "description": "Low-Code Engine 低代码搭建引擎 Vue2 Demo 项目",
5 | "repository": "git@github.com:alibaba/lowcode-demo.git",
6 | "license": "MIT",
7 | "main": "index.js",
8 | "scripts": {
9 | "start": "build-scripts start --disable-reload --port 5556",
10 | "build": "build-scripts build",
11 | "prepublishOnly": "npm run build",
12 | "pub": "node ./scripts/watchdog.js && npm pub"
13 | },
14 | "files": [
15 | "build"
16 | ],
17 | "config": {},
18 | "dependencies": {
19 | "@alilc/lowcode-utils": "^1.0.9",
20 | "@alilc/lowcode-datasource-fetch-handler": "^1.0.1",
21 | "@alilc/lowcode-plugin-code-editor": "^1.0.2",
22 | "@alilc/lowcode-plugin-code-generator": "^1.0.4",
23 | "@alilc/lowcode-plugin-components-pane": "^1.0.2",
24 | "@alilc/lowcode-plugin-datasource-pane": "^1.0.5",
25 | "@alilc/lowcode-plugin-inject": "^1.0.0",
26 | "@alilc/lowcode-plugin-manual": "^1.0.3",
27 | "@alilc/lowcode-plugin-schema": "^1.0.1",
28 | "@alilc/lowcode-plugin-simulator-select": "^1.0.0",
29 | "@alilc/lowcode-plugin-undo-redo": "^1.0.0",
30 | "@alilc/lowcode-plugin-zh-en": "^1.0.0",
31 | "@alilc/lowcode-react-renderer": "^1.0.0",
32 | "@alilc/lowcode-setter-behavior": "^1.0.0",
33 | "@alilc/lowcode-setter-title": "^1.0.2",
34 | "@lowcodecloud/lowcode-engine-vue2-renderer": "1.0.0",
35 | "regenerator-runtime": "^0.13.9",
36 | "uuid": "^8.3.2"
37 | },
38 | "devDependencies": {
39 | "@alib/build-scripts": "^0.1.18",
40 | "@alilc/lowcode-engine": "^1.0.0",
41 | "@alilc/lowcode-engine-ext": "^1.0.0",
42 | "@alilc/lowcode-types": "^1.0.0",
43 | "@babel/runtime": "^7.18.3",
44 | "@types/events": "^3.0.0",
45 | "@types/react": "^16.8.3",
46 | "@types/react-dom": "^16.8.2",
47 | "@types/streamsaver": "^2.0.0",
48 | "@types/uuid": "^8.3.4",
49 | "build-plugin-fusion": "^0.1.0",
50 | "build-plugin-moment-locales": "^0.1.0",
51 | "build-plugin-react-app": "^1.1.2",
52 | "fs-extra": "^10.0.1",
53 | "tsconfig-paths-webpack-plugin": "^3.2.0"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@lowcodecloud/lowcode-vue3-demo",
3 | "version": "1.0.0",
4 | "description": "Low-Code Engine 低代码搭建引擎 Vue3 Demo 项目",
5 | "repository": "git@github.com:alibaba/lowcode-demo.git",
6 | "license": "MIT",
7 | "main": "index.js",
8 | "scripts": {
9 | "start": "build-scripts start --disable-reload --port 5557",
10 | "build": "build-scripts build",
11 | "prepublishOnly": "npm run build",
12 | "pub": "node ./scripts/watchdog.js && npm pub"
13 | },
14 | "files": [
15 | "build"
16 | ],
17 | "config": {},
18 | "dependencies": {
19 | "@alilc/lowcode-utils": "^1.0.9",
20 | "@alilc/lowcode-datasource-fetch-handler": "^1.0.1",
21 | "@alilc/lowcode-plugin-code-editor": "^1.0.2",
22 | "@alilc/lowcode-plugin-code-generator": "^1.0.4",
23 | "@alilc/lowcode-plugin-components-pane": "^1.0.2",
24 | "@alilc/lowcode-plugin-datasource-pane": "^1.0.5",
25 | "@alilc/lowcode-plugin-inject": "^1.0.0",
26 | "@alilc/lowcode-plugin-manual": "^1.0.3",
27 | "@alilc/lowcode-plugin-schema": "^1.0.1",
28 | "@alilc/lowcode-plugin-simulator-select": "^1.0.0",
29 | "@alilc/lowcode-plugin-undo-redo": "^1.0.0",
30 | "@alilc/lowcode-plugin-zh-en": "^1.0.0",
31 | "@alilc/lowcode-react-renderer": "^1.0.0",
32 | "@alilc/lowcode-setter-behavior": "^1.0.0",
33 | "@alilc/lowcode-setter-title": "^1.0.2",
34 | "@lowcodecloud/lowcode-engine-vue3-renderer": "1.0.0",
35 | "regenerator-runtime": "^0.13.9",
36 | "uuid": "^8.3.2"
37 | },
38 | "devDependencies": {
39 | "@alib/build-scripts": "^0.1.18",
40 | "@alilc/lowcode-engine": "^1.0.0",
41 | "@alilc/lowcode-engine-ext": "^1.0.0",
42 | "@alilc/lowcode-types": "^1.0.0",
43 | "@babel/runtime": "^7.18.3",
44 | "@types/events": "^3.0.0",
45 | "@types/react": "^16.8.3",
46 | "@types/react-dom": "^16.8.2",
47 | "@types/streamsaver": "^2.0.0",
48 | "@types/uuid": "^8.3.4",
49 | "build-plugin-fusion": "^0.1.0",
50 | "build-plugin-moment-locales": "^0.1.0",
51 | "build-plugin-react-app": "^1.1.2",
52 | "fs-extra": "^10.0.1",
53 | "tsconfig-paths-webpack-plugin": "^3.2.0"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/sample-plugins/set-ref-prop/index.tsx:
--------------------------------------------------------------------------------
1 | import { TransformedComponentMetadata, FieldConfig } from '@alilc/lowcode-types';
2 | import { v4 as uuidv4 } from 'uuid';
3 | import { material } from '@alilc/lowcode-engine';
4 |
5 | function addonCombine(metadata: TransformedComponentMetadata) {
6 | const { componentName, configure = {} } = metadata;
7 |
8 | const isRoot: boolean = componentName === 'Page' || componentName === 'Component';
9 |
10 | if (isRoot) {
11 | return metadata;
12 | }
13 |
14 | let advancedGroup: FieldConfig | undefined;
15 |
16 | const refItem: FieldConfig = {
17 | title: {
18 | label: 'refId',
19 | tip: '用于获取组件实例,调用物料内部方法',
20 | icon: '',
21 | },
22 | name: "ref",
23 | setter: {
24 | componentName: 'StringSetter',
25 | },
26 | defaultValue: () => {
27 | const uuid = uuidv4().replace('-', '').substring(0, 8);
28 | return `${componentName.toLowerCase()}-${uuid}`;
29 | },
30 | extraProps: {
31 | display: 'block',
32 | supportVariable: false,
33 | },
34 | }
35 |
36 | if (!configure.combined) {
37 | configure.combined = []
38 | }
39 |
40 | advancedGroup = configure.combined?.filter(d => d.name === '#advanced')[0];
41 |
42 | if (!advancedGroup) {
43 | advancedGroup = {
44 | name: '#advanced',
45 | title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' },
46 | items: [
47 | refItem,
48 | ],
49 | };
50 |
51 | configure.combined.push(advancedGroup);
52 | }
53 |
54 | if (!advancedGroup.items) {
55 | advancedGroup.items = [refItem];
56 | }
57 |
58 | const advanceItems: FieldConfig[] = advancedGroup.items || [];
59 |
60 | if (!advanceItems || !advanceItems.length || !advanceItems?.filter(d => d.name === 'ref').length) {
61 | advanceItems.push(refItem);
62 | }
63 |
64 | return {
65 | ...metadata,
66 | configure,
67 | };
68 | }
69 |
70 | export const registerRefProp = () => {
71 | return {
72 | init() {
73 | material.registerMetadataTransducer(addonCombine, 110, 'register-ref-prop')
74 | }
75 | };
76 | };
77 |
78 | registerRefProp.pluginName = 'register-ref-prop';
79 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/sample-plugins/set-ref-prop/index.tsx:
--------------------------------------------------------------------------------
1 | import { TransformedComponentMetadata, FieldConfig } from '@alilc/lowcode-types';
2 | import { v4 as uuidv4 } from 'uuid';
3 | import { material } from '@alilc/lowcode-engine';
4 |
5 | function addonCombine(metadata: TransformedComponentMetadata) {
6 | const { componentName, configure = {} } = metadata;
7 |
8 | const isRoot: boolean = componentName === 'Page' || componentName === 'Component';
9 |
10 | if (isRoot) {
11 | return metadata;
12 | }
13 |
14 | let advancedGroup: FieldConfig | undefined;
15 |
16 | const refItem: FieldConfig = {
17 | title: {
18 | label: 'refId',
19 | tip: '用于获取组件实例,调用物料内部方法',
20 | icon: '',
21 | },
22 | name: "ref",
23 | setter: {
24 | componentName: 'StringSetter',
25 | },
26 | defaultValue: () => {
27 | const uuid = uuidv4().replace('-', '').substring(0, 8);
28 | return `${componentName.toLowerCase()}-${uuid}`;
29 | },
30 | extraProps: {
31 | display: 'block',
32 | supportVariable: false,
33 | },
34 | }
35 |
36 | if (!configure.combined) {
37 | configure.combined = []
38 | }
39 |
40 | advancedGroup = configure.combined?.filter(d => d.name === '#advanced')[0];
41 |
42 | if (!advancedGroup) {
43 | advancedGroup = {
44 | name: '#advanced',
45 | title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' },
46 | items: [
47 | refItem,
48 | ],
49 | };
50 |
51 | configure.combined.push(advancedGroup);
52 | }
53 |
54 | if (!advancedGroup.items) {
55 | advancedGroup.items = [refItem];
56 | }
57 |
58 | const advanceItems: FieldConfig[] = advancedGroup.items || [];
59 |
60 | if (!advanceItems || !advanceItems.length || !advanceItems?.filter(d => d.name === 'ref').length) {
61 | advanceItems.push(refItem);
62 | }
63 |
64 | return {
65 | ...metadata,
66 | configure,
67 | };
68 | }
69 |
70 | export const registerRefProp = () => {
71 | return {
72 | init() {
73 | material.registerMetadataTransducer(addonCombine, 110, 'register-ref-prop')
74 | }
75 | };
76 | };
77 |
78 | registerRefProp.pluginName = 'register-ref-prop';
79 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/build.plugin.js:
--------------------------------------------------------------------------------
1 | const { join } = require('path');
2 | const fs = require('fs-extra');
3 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 |
6 | const scenarioNames = fs.readdirSync(join('./src/scenarios')).filter(name => !name.startsWith('.'));
7 | const { version } = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
8 |
9 | module.exports = ({ onGetWebpackConfig }) => {
10 | onGetWebpackConfig((config) => {
11 | config.resolve.plugin('tsconfigpaths').use(TsconfigPathsPlugin, [
12 | {
13 | configFile: './tsconfig.json',
14 | },
15 | ]);
16 |
17 | config.merge({
18 | node: {
19 | fs: 'empty',
20 | },
21 | });
22 |
23 | scenarioNames.forEach(name => {
24 | const hasTsx = fs.existsSync(join(`./src/scenarios/${name}/index.tsx`));
25 | config.merge({
26 | entry: {
27 | [name]: hasTsx ? require.resolve(`./src/scenarios/${name}/index.tsx`) : require.resolve(`./src/scenarios/${name}/index.ts`),
28 | },
29 | });
30 | config
31 | .plugin(name)
32 | .use(HtmlWebpackPlugin, [
33 | {
34 | inject: false,
35 | minify: false,
36 | templateParameters: {
37 | scenario: name,
38 | version,
39 | },
40 | template: require.resolve('./public/index.ejs'),
41 | filename: `${name}.html`,
42 | },
43 | ]);
44 | })
45 |
46 | config
47 | .plugin('preview')
48 | .use(HtmlWebpackPlugin, [
49 | {
50 | inject: false,
51 | templateParameters: {
52 | },
53 | template: require.resolve('./public/preview.html'),
54 | filename: 'preview.html',
55 | },
56 | ]);
57 |
58 | config.plugins.delete('hot');
59 | config.devServer.hot(false);
60 |
61 | config.module // fixes https://github.com/graphql/graphql-js/issues/1272
62 | .rule('mjs$')
63 | .test(/\.mjs$/)
64 | .include
65 | .add(/node_modules/)
66 | .end()
67 | .type('javascript/auto');
68 | });
69 | };
70 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/build.plugin.js:
--------------------------------------------------------------------------------
1 | const { join } = require('path');
2 | const fs = require('fs-extra');
3 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 |
6 | const scenarioNames = fs.readdirSync(join('./src/scenarios')).filter(name => !name.startsWith('.'));
7 | const { version } = JSON.parse(fs.readFileSync('./package.json', 'utf8'));
8 |
9 | module.exports = ({ onGetWebpackConfig }) => {
10 | onGetWebpackConfig((config) => {
11 | config.resolve.plugin('tsconfigpaths').use(TsconfigPathsPlugin, [
12 | {
13 | configFile: './tsconfig.json',
14 | },
15 | ]);
16 |
17 | config.merge({
18 | node: {
19 | fs: 'empty',
20 | },
21 | });
22 |
23 | scenarioNames.forEach(name => {
24 | const hasTsx = fs.existsSync(join(`./src/scenarios/${name}/index.tsx`));
25 | config.merge({
26 | entry: {
27 | [name]: hasTsx ? require.resolve(`./src/scenarios/${name}/index.tsx`) : require.resolve(`./src/scenarios/${name}/index.ts`),
28 | },
29 | });
30 | config
31 | .plugin(name)
32 | .use(HtmlWebpackPlugin, [
33 | {
34 | inject: false,
35 | minify: false,
36 | templateParameters: {
37 | scenario: name,
38 | version,
39 | },
40 | template: require.resolve('./public/index.ejs'),
41 | filename: `${name}.html`,
42 | },
43 | ]);
44 | })
45 |
46 | config
47 | .plugin('preview')
48 | .use(HtmlWebpackPlugin, [
49 | {
50 | inject: false,
51 | templateParameters: {
52 | },
53 | template: require.resolve('./public/preview.html'),
54 | filename: 'preview.html',
55 | },
56 | ]);
57 |
58 | config.plugins.delete('hot');
59 | config.devServer.hot(false);
60 |
61 | config.module // fixes https://github.com/graphql/graphql-js/issues/1272
62 | .rule('mjs$')
63 | .test(/\.mjs$/)
64 | .include
65 | .add(/node_modules/)
66 | .end()
67 | .type('javascript/auto');
68 | });
69 | };
70 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/simulator/css/vue2-simulator-renderer.css:
--------------------------------------------------------------------------------
1 | .visual-dom .panel-container{-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #e9e9e9}.visual-dom .panel-container .title{display:block;font-size:12px;color:#333;background-color:#ebecf0;line-height:28px;padding:0 12px;border-bottom:1px solid #e9e9e9}.visual-dom .panel-container .content{min-height:20px;padding:5px}html.lc-cursor-dragging,html.lc-cursor-dragging *{cursor:move!important}html.lc-cursor-x-resizing,html.lc-cursor-x-resizing *{cursor:col-resize}html.lc-cursor-y-resizing,html.lc-cursor-y-resizing *{cursor:row-resize}html.lc-cursor-copy,html.lc-cursor-copy *{cursor:copy!important}body,html{display:block;background:#fff;padding:0;margin:0}html.engine-design-mode{padding-bottom:0}html.engine-cursor-move,html.engine-cursor-move *{cursor:-webkit-grabbing!important;cursor:grabbing!important}html.engine-cursor-copy,html.engine-cursor-copy *{cursor:copy!important}html.engine-cursor-ew-resize,html.engine-cursor-ew-resize *{cursor:ew-resize!important}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:5px}.lc-container:empty{background:#f2f3f5;color:#a7b1bd;outline:1px dashed rgba(31,56,88,.2);outline-offset:-1px!important;height:66px;max-height:100%;min-width:140px;text-align:center;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.lc-container:empty:before{content:"\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC";font-size:14px;z-index:1;width:100%;white-space:nowrap}.lc-container-placeholder{min-height:60px;height:100%;width:100%;background-color:#f0f0f0;border:1px dotted;color:#a7b1bd;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;font-size:14px}.lc-container-placeholder.lc-container-locked{background:#eccfcf}body.engine-document:after,body.engine-document:before{content:"";display:table}body.engine-document:after{clear:both}.engine-live-editing{cursor:text;outline:none;-webkit-box-shadow:0 0 0 2px #66bc5c;box-shadow:0 0 0 2px #66bc5c;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}#app{height:100vh}
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/simulator/css/vue3-simulator-renderer.css:
--------------------------------------------------------------------------------
1 | .visual-dom .panel-container{-webkit-box-sizing:border-box;box-sizing:border-box;border:1px solid #e9e9e9}.visual-dom .panel-container .title{display:block;font-size:12px;color:#333;background-color:#ebecf0;line-height:28px;padding:0 12px;border-bottom:1px solid #e9e9e9}.visual-dom .panel-container .content{min-height:20px;padding:5px}html.lc-cursor-dragging,html.lc-cursor-dragging *{cursor:move!important}html.lc-cursor-x-resizing,html.lc-cursor-x-resizing *{cursor:col-resize}html.lc-cursor-y-resizing,html.lc-cursor-y-resizing *{cursor:row-resize}html.lc-cursor-copy,html.lc-cursor-copy *{cursor:copy!important}body,html{display:block;background:#fff;padding:0;margin:0}html.engine-design-mode{padding-bottom:0}html.engine-cursor-move,html.engine-cursor-move *{cursor:-webkit-grabbing!important;cursor:grabbing!important}html.engine-cursor-copy,html.engine-cursor-copy *{cursor:copy!important}html.engine-cursor-ew-resize,html.engine-cursor-ew-resize *{cursor:ew-resize!important}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.3);border-radius:5px}.lc-container:empty{background:#f2f3f5;color:#a7b1bd;outline:1px dashed rgba(31,56,88,.2);outline-offset:-1px!important;height:66px;max-height:100%;min-width:140px;text-align:center;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.lc-container:empty:before{content:"\62D6\62FD\7EC4\4EF6\6216\6A21\677F\5230\8FD9\91CC";font-size:14px;z-index:1;width:100%;white-space:nowrap}.lc-container-placeholder{min-height:60px;height:100%;width:100%;background-color:#f0f0f0;border:1px dotted;color:#a7b1bd;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;font-size:14px}.lc-container-placeholder.lc-container-locked{background:#eccfcf}body.engine-document:after,body.engine-document:before{content:"";display:table}body.engine-document:after{clear:both}.engine-live-editing{cursor:text;outline:none;-webkit-box-shadow:0 0 0 2px #66bc5c;box-shadow:0 0 0 2px #66bc5c;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}#app{height:100vh}
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/index.ts:
--------------------------------------------------------------------------------
1 | import React, {
2 | Component,
3 | PureComponent,
4 | createElement,
5 | createContext,
6 | forwardRef,
7 | ReactInstance,
8 | ContextType,
9 | } from 'react';
10 | import ReactDOM from 'react-dom';
11 | import {
12 | adapter,
13 | pageRendererFactory,
14 | componentRendererFactory,
15 | blockRendererFactory,
16 | addonRendererFactory,
17 | tempRendererFactory,
18 | rendererFactory,
19 | types,
20 | } from '@alilc/lowcode-renderer-core';
21 | import ConfigProvider from '@alifd/next/lib/config-provider';
22 |
23 | import { buildComponents } from './utils';
24 |
25 | import * as vueRendererExtTypes from './types';
26 |
27 | window.React = React;
28 | (window as any).ReactDom = ReactDOM;
29 |
30 | const defaultRuntime = {
31 | Component,
32 | PureComponent,
33 | createContext,
34 | createElement,
35 | forwardRef,
36 | findDOMNode: ReactDOM.findDOMNode,
37 | };
38 | adapter.setRuntime(defaultRuntime);
39 |
40 | function setRuntime(runtime: any) {
41 | adapter.setRuntime({ ...defaultRuntime, ...runtime } as types.IRuntime);
42 | }
43 |
44 | const defaultRenderers = {
45 | PageRenderer: pageRendererFactory(),
46 | ComponentRenderer: componentRendererFactory(),
47 | BlockRenderer: blockRendererFactory(),
48 | AddonRenderer: addonRendererFactory(),
49 | TempRenderer: tempRendererFactory(),
50 | DivRenderer: blockRendererFactory(),
51 | };
52 | adapter.setRenderers(defaultRenderers);
53 |
54 | function setRenderers(renderers: any) {
55 | adapter.setRenderers({ ...defaultRenderers, ...renderers } as types.IRendererModules);
56 | }
57 |
58 | const defaultConfigProvider = ConfigProvider;
59 | adapter.setConfigProvider(defaultConfigProvider);
60 |
61 | function setConfigProvider(configProvide: any) {
62 | adapter.setConfigProvider(configProvide);
63 | }
64 |
65 | function createRendererFactory(): types.IRenderComponent {
66 | const Renderer = rendererFactory();
67 | return class ReactRenderer extends Renderer implements Component {
68 | readonly props: types.IRendererProps;
69 |
70 | context: ContextType;
71 |
72 | setState: (
73 | state: types.IRendererState,
74 | callback?: () => void,
75 | ) => void;
76 |
77 | forceUpdate: (callback?: () => void) => void;
78 |
79 | refs: {
80 | [key: string]: ReactInstance;
81 | };
82 |
83 | constructor(props: types.IRendererProps, context: ContextType) {
84 | super(props, context);
85 | }
86 |
87 | isValidComponent(obj: any) {
88 | return obj?.prototype?.isReactComponent || obj?.prototype instanceof Component;
89 | }
90 | };
91 | }
92 |
93 | export default createRendererFactory;
94 |
95 | export { setRuntime, setRenderers, setConfigProvider, buildComponents, types, vueRendererExtTypes };
96 |
97 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 阿里低代码引擎 Demo
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | 阿里低代码引擎 Demo
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/preview.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom';
2 | import React, { useState } from 'react';
3 | import { Loading } from '@alifd/next';
4 | import { assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils';
5 | import ReactRenderer, { buildComponents } from '@lowcodecloud/lowcode-engine-vue2-renderer';
6 | import { injectComponents } from '@alilc/lowcode-plugin-inject';
7 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
8 |
9 | import { getProjectSchemaFromLocalStorage, getPackagesFromLocalStorage } from './universal/utils';
10 |
11 | const getScenarioName = function () {
12 | if (location.search) {
13 | return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'index';
14 | }
15 | return 'index';
16 | };
17 |
18 | const SamplePreview = () => {
19 | const [data, setData] = useState({});
20 |
21 | async function init() {
22 | const scenarioName = getScenarioName();
23 | const packages = getPackagesFromLocalStorage(scenarioName);
24 | const projectSchema = getProjectSchemaFromLocalStorage(scenarioName);
25 | const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
26 | const componentsMap: any = {};
27 | componentsMapArray.forEach((component: any) => {
28 | componentsMap[component.componentName] = component;
29 | });
30 | const schema = componentsTree[0];
31 |
32 | const libraryMap = {};
33 | const libraryAsset = [];
34 | packages.forEach(({ package: _package, library, urls, renderUrls }) => {
35 | libraryMap[_package] = library;
36 | if (_package === 'vue') {
37 | return;
38 | }
39 | if (renderUrls) {
40 | libraryAsset.push(renderUrls);
41 | } else if (urls) {
42 | libraryAsset.push(urls);
43 | }
44 | });
45 |
46 | const vendors = [assetBundle(libraryAsset, AssetLevel.Library)];
47 |
48 | // TODO asset may cause pollution
49 | const assetLoader = new AssetLoader();
50 | await assetLoader.load(libraryAsset);
51 | const components = await injectComponents(buildComponents(libraryMap, componentsMap));
52 |
53 | setData({
54 | schema,
55 | components,
56 | });
57 | }
58 |
59 | const { schema, components } = data;
60 |
61 | if (!schema || !components) {
62 | init();
63 | return ;
64 | }
65 |
66 | return (
67 |
68 |
78 |
79 | );
80 | };
81 |
82 | ReactDOM.render(, document.getElementById('ice-container'));
83 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/preview.tsx:
--------------------------------------------------------------------------------
1 | import ReactDOM from 'react-dom';
2 | import React, { useState } from 'react';
3 | import { Loading } from '@alifd/next';
4 | import { assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils';
5 | import ReactRenderer, { buildComponents } from '@lowcodecloud/lowcode-engine-vue3-renderer';
6 | import { injectComponents } from '@alilc/lowcode-plugin-inject';
7 |
8 | import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
9 |
10 | import { getProjectSchemaFromLocalStorage, getPackagesFromLocalStorage } from './universal/utils';
11 |
12 | const getScenarioName = function () {
13 | if (location.search) {
14 | return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'index';
15 | }
16 | return 'index';
17 | };
18 |
19 | const SamplePreview = () => {
20 | const [data, setData] = useState({});
21 |
22 | async function init() {
23 | const scenarioName = getScenarioName();
24 | const packages = getPackagesFromLocalStorage(scenarioName);
25 | const projectSchema = getProjectSchemaFromLocalStorage(scenarioName);
26 | const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
27 | const componentsMap: any = {};
28 | componentsMapArray.forEach((component: any) => {
29 | componentsMap[component.componentName] = component;
30 | });
31 | const schema = componentsTree[0];
32 |
33 | const libraryMap = {};
34 | const libraryAsset = [];
35 | packages.forEach(({ package: _package, library, urls, renderUrls }) => {
36 | libraryMap[_package] = library;
37 | if (_package === 'vue') {
38 | return;
39 | }
40 | if (renderUrls) {
41 | libraryAsset.push(renderUrls);
42 | } else if (urls) {
43 | libraryAsset.push(urls);
44 | }
45 | });
46 |
47 | const vendors = [assetBundle(libraryAsset, AssetLevel.Library)];
48 |
49 | // TODO asset may cause pollution
50 | const assetLoader = new AssetLoader();
51 | await assetLoader.load(libraryAsset);
52 | const components = await injectComponents(buildComponents(libraryMap, componentsMap));
53 |
54 | setData({
55 | schema,
56 | components,
57 | });
58 | }
59 |
60 | const { schema, components } = data;
61 |
62 | if (!schema || !components) {
63 | init();
64 | return ;
65 | }
66 |
67 | return (
68 |
69 |
79 |
80 | );
81 | };
82 |
83 | ReactDOM.render(, document.getElementById('ice-container'));
84 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/test/schema/basic.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | id: 'node_ockvuu8u911',
3 | css: 'body{background-color:#f2f3f5}',
4 | flows: [],
5 | props: {
6 | className: 'page_kvuu9hym',
7 | pageStyle: {
8 | backgroundColor: '#f2f3f5',
9 | },
10 | containerStyle: {},
11 | templateVersion: '1.0.0',
12 | },
13 | state: {},
14 | title: '',
15 | methods: {
16 | __initMethods__: {
17 | type: 'JSExpression',
18 | value: "function (exports, module) { \"use strict\";\n\nexports.__esModule = true;\nexports.func1 = func1;\nexports.helloPage = helloPage;\n\nfunction func1() {\n console.info('hello, this is a page function');\n}\n\nfunction helloPage() {\n // 你可以这么调用其他函数\n this.func1(); // 你可以这么调用组件的函数\n // this.$('textField_xxx').getValue();\n // 你可以这么使用「数据源面板」定义的「变量」\n // this.state.xxx\n // 你可以这么发送一个在「数据源面板」定义的「远程 API」\n // this.dataSourceMap['xxx'].load(data)\n // API 详见:https://go.alibaba-inc.com/help3/API\n} \n}",
19 | },
20 | },
21 | children: [
22 | {
23 | id: 'node_ockvuu8u915',
24 | props: {
25 | fieldId: 'div_kvuu9gl1',
26 | behavior: 'NORMAL',
27 | __style__: {},
28 | customClassName: '',
29 | useFieldIdAsDomId: false,
30 | },
31 | title: '',
32 | children: [
33 | {
34 | id: 'node_ockvuu8u916',
35 | props: {
36 | content: {
37 | use: 'zh_CN',
38 | type: 'JSExpression',
39 | en_US: 'Tips content',
40 | value: '"我是一个简单的测试页面"',
41 | zh_CN: '我是一个简单的测试页面',
42 | extType: 'i18n',
43 | },
44 | fieldId: 'text_kvuu9gl2',
45 | maxLine: 0,
46 | behavior: 'NORMAL',
47 | __style__: {},
48 | showTitle: false,
49 | },
50 | title: '',
51 | condition: true,
52 | componentName: 'Text',
53 | },
54 | ],
55 | condition: true,
56 | componentName: 'Div',
57 | },
58 | ],
59 | condition: true,
60 | dataSource: {
61 | list: [],
62 | sync: true,
63 | online: [],
64 | offline: [],
65 | globalConfig: {
66 | fit: {
67 | type: 'JSExpression',
68 | value: "function main(){\n 'use strict';\n\nvar __compiledFunc__ = function fit(response) {\n var content = response.content !== undefined ? response.content : response;\n var error = {\n message: response.errorMsg || response.errors && response.errors[0] && response.errors[0].msg || response.content || '远程数据源请求出错,success is false'\n };\n var success = true;\n if (response.success !== undefined) {\n success = response.success;\n } else if (response.hasError !== undefined) {\n success = !response.hasError;\n }\n return {\n content: content,\n success: success,\n error: error\n };\n};\n return __compiledFunc__.apply(this, arguments);\n}",
69 | extType: 'function',
70 | },
71 | },
72 | },
73 | lifeCycles: {
74 | constructor: {
75 | type: 'JSExpression',
76 | value: "function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
77 | extType: 'function',
78 | },
79 | },
80 | componentName: 'Page',
81 | };
82 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/test/schema/basic.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | id: 'node_ockvuu8u911',
3 | css: 'body{background-color:#f2f3f5}',
4 | flows: [],
5 | props: {
6 | className: 'page_kvuu9hym',
7 | pageStyle: {
8 | backgroundColor: '#f2f3f5',
9 | },
10 | containerStyle: {},
11 | templateVersion: '1.0.0',
12 | },
13 | state: {},
14 | title: '',
15 | methods: {
16 | __initMethods__: {
17 | type: 'JSExpression',
18 | value: "function (exports, module) { \"use strict\";\n\nexports.__esModule = true;\nexports.func1 = func1;\nexports.helloPage = helloPage;\n\nfunction func1() {\n console.info('hello, this is a page function');\n}\n\nfunction helloPage() {\n // 你可以这么调用其他函数\n this.func1(); // 你可以这么调用组件的函数\n // this.$('textField_xxx').getValue();\n // 你可以这么使用「数据源面板」定义的「变量」\n // this.state.xxx\n // 你可以这么发送一个在「数据源面板」定义的「远程 API」\n // this.dataSourceMap['xxx'].load(data)\n // API 详见:https://go.alibaba-inc.com/help3/API\n} \n}",
19 | },
20 | },
21 | children: [
22 | {
23 | id: 'node_ockvuu8u915',
24 | props: {
25 | fieldId: 'div_kvuu9gl1',
26 | behavior: 'NORMAL',
27 | __style__: {},
28 | customClassName: '',
29 | useFieldIdAsDomId: false,
30 | },
31 | title: '',
32 | children: [
33 | {
34 | id: 'node_ockvuu8u916',
35 | props: {
36 | content: {
37 | use: 'zh_CN',
38 | type: 'JSExpression',
39 | en_US: 'Tips content',
40 | value: '"我是一个简单的测试页面"',
41 | zh_CN: '我是一个简单的测试页面',
42 | extType: 'i18n',
43 | },
44 | fieldId: 'text_kvuu9gl2',
45 | maxLine: 0,
46 | behavior: 'NORMAL',
47 | __style__: {},
48 | showTitle: false,
49 | },
50 | title: '',
51 | condition: true,
52 | componentName: 'Text',
53 | },
54 | ],
55 | condition: true,
56 | componentName: 'Div',
57 | },
58 | ],
59 | condition: true,
60 | dataSource: {
61 | list: [],
62 | sync: true,
63 | online: [],
64 | offline: [],
65 | globalConfig: {
66 | fit: {
67 | type: 'JSExpression',
68 | value: "function main(){\n 'use strict';\n\nvar __compiledFunc__ = function fit(response) {\n var content = response.content !== undefined ? response.content : response;\n var error = {\n message: response.errorMsg || response.errors && response.errors[0] && response.errors[0].msg || response.content || '远程数据源请求出错,success is false'\n };\n var success = true;\n if (response.success !== undefined) {\n success = response.success;\n } else if (response.hasError !== undefined) {\n success = !response.hasError;\n }\n return {\n content: content,\n success: success,\n error: error\n };\n};\n return __compiledFunc__.apply(this, arguments);\n}",
69 | extType: 'function',
70 | },
71 | },
72 | },
73 | lifeCycles: {
74 | constructor: {
75 | type: 'JSExpression',
76 | value: "function constructor() {\nvar module = { exports: {} };\nvar _this = this;\nthis.__initMethods__(module.exports, module);\nObject.keys(module.exports).forEach(function(item) {\n if(typeof module.exports[item] === 'function'){\n _this[item] = module.exports[item];\n }\n});\n\n}",
77 | extType: 'function',
78 | },
79 | },
80 | componentName: 'Page',
81 | };
82 |
--------------------------------------------------------------------------------
/packages/vue-renderer-core/src/utils/build-components.ts:
--------------------------------------------------------------------------------
1 | import { ComponentType, FunctionComponent } from 'react';
2 | import { ComponentSchema } from '@alilc/lowcode-types';
3 | import { accessLibrary, isESModule, acceptsRef, wrapReactClass } from '@alilc/lowcode-utils';
4 | import { isReactComponent } from './is-react';
5 | import { LibraryPackageMapping, NpmInfo, DevStack } from '../types';
6 |
7 | export type Component = ComponentType | object;
8 |
9 | export function findComponent(libraryMap: LibraryPackageMapping, componentName: string, npm?: NpmInfo) {
10 | if (!npm) {
11 | return accessLibrary(componentName);
12 | }
13 |
14 | // libraryName the key access to global
15 | // export { exportName } from xxx exportName === global.libraryName.exportName
16 | // export exportName from xxx exportName === global.libraryName.default || global.libraryName
17 | // export { exportName as componentName } from package
18 | // if exportName == null exportName === componentName;
19 | // const componentName = exportName.subName, if exportName empty subName donot use
20 | const exportName = npm.exportName || npm.componentName || componentName;
21 | const libraryName = libraryMap[npm.package] || exportName;
22 | const library = accessLibrary(libraryName);
23 | const paths = npm.exportName && npm.subName ? npm.subName.split('.') : [];
24 | if (npm.destructuring) {
25 | paths.unshift(exportName);
26 | } else if (isESModule(library)) {
27 | paths.unshift('default');
28 | }
29 | let component = getSubComponent(library, paths);
30 | if (component) {
31 | (component as any).$$devStack = npm.devStack;
32 | }
33 | return component;
34 | }
35 |
36 | export function buildComponents(libraryMap: LibraryPackageMapping,
37 | componentsMap: { [componentName: string]: NpmInfo | ComponentType | ComponentSchema },
38 | createComponent: (schema: ComponentSchema) => Component | null) {
39 | const components: any = {};
40 | Object.keys(componentsMap).forEach((componentName) => {
41 | let component = componentsMap[componentName];
42 | let devStack = component ? (component as NpmInfo).devStack : undefined;
43 | if (component && (component as ComponentSchema).componentName === 'Component') {
44 | components[componentName] = createComponent(component as ComponentSchema);
45 | } else if (devStack === 'vue' || devStack === 'vue2' || devStack === 'vue3') {
46 | // @ts-ignore
47 | component = findComponent(libraryMap, componentName, component);
48 | (component as any).$$devStack = DevStack.Vue;
49 | components[componentName] = component;
50 | } else if (devStack === 'react' || isReactComponent(component)) {
51 | if (!acceptsRef(component)) {
52 | component = wrapReactClass(component as FunctionComponent);
53 | }
54 | (component as any).$$devStack = DevStack.React;
55 | components[componentName] = component;
56 | } else {
57 | // @ts-ignore
58 | component = findComponent(libraryMap, componentName, component);
59 | if (component) {
60 | if (!acceptsRef(component)) {
61 | component = wrapReactClass(component as FunctionComponent);
62 | }
63 | components[componentName] = component;
64 | }
65 | }
66 | });
67 | return components;
68 | }
69 |
70 | export function getSubComponent(library: any, paths: string[]) {
71 | const l = paths.length;
72 | if (l < 1 || !library) {
73 | return library;
74 | }
75 | let originLibrary = library;
76 | let i = 0;
77 | let component: any;
78 | while (i < l) {
79 | const key = paths[i]!;
80 | let ex: any;
81 | try {
82 | component = library[key];
83 | component.$$devStack = originLibrary.$$devStack;
84 | } catch (e) {
85 | ex = e;
86 | component = null;
87 | }
88 | if (i === 0 && component == null && key === 'default') {
89 | if (ex) {
90 | return l === 1 ? library : null;
91 | }
92 | component = library;
93 | } else if (component == null) {
94 | return null;
95 | }
96 | library = component;
97 | library.$$devStack = originLibrary.$$devStack;
98 | i++;
99 | }
100 | return component;
101 | }
102 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/public/fixtures/basic-fusion-with-single-component/meta.js:
--------------------------------------------------------------------------------
1 | !function e(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.M220318Meta=n():t.M220318Meta=n()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function t(){return e.default}:function t(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";n.r(t),n.d(t,"components",(function(){return S})),n.d(t,"componentList",(function(){return O}));var r={componentName:"M220318",title:"M220318",docUrl:"",screenshot:"",devMode:"proCode",npm:{package:"m-220318",version:"0.1.0",exportName:"default",main:"src/index.tsx",destructuring:!1,subName:""},configure:{props:[{title:{label:{type:"i18n","en-US":"title","zh-CN":"title"}},name:"title",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"content","zh-CN":"content"}},name:"content",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"ref","zh-CN":"ref"}},name:"ref",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"FunctionSetter"},{componentName:"ObjectSetter",props:{config:{extraSetter:{componentName:"MixedSetter",isRequired:!1,props:{}}}},isRequired:!1,initialValue:{}}]}}},{title:{label:{type:"i18n","en-US":"key","zh-CN":"key"}},name:"key",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"StringSetter",isRequired:!1,initialValue:""},{componentName:"NumberSetter",isRequired:!1,initialValue:0}]}}}],supports:{style:!0},component:{}}},o=[{title:"M220318",screenshot:"",schema:{componentName:"M220318",props:{}}}],i=Object.assign(Object.assign({},r),{snippets:o});function c(e){return l(e)||p(e)||u(e)||a()}function a(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function u(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function p(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function l(e){if(Array.isArray(e))return s(e)}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:"m-220318",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"0.1.0",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{"@alifd/next":"1.25.23","@alifd/meet":"2.6.3",antd:"4.17.3"};if(!e||!n)return e;var o=e.npm;return o?("object"===d(r)&&r[o.package]?e.npm=m(m({},o),{},{version:r[o.package]}):o.package===t&&(e.npm=m(m({},o),{},{version:n})),e):e}["\u57fa\u7840\u5143\u7d20","\u5e03\u5c40\u5bb9\u5668\u7c7b","\u8868\u683c\u7c7b","\u8868\u5355\u8be6\u60c5\u7c7b","\u5e2e\u52a9\u7c7b","\u5bf9\u8bdd\u6846\u7c7b","\u4e1a\u52a1\u7c7b","\u901a\u7528","\u5f15\u5bfc","\u4fe1\u606f\u8f93\u5165","\u4fe1\u606f\u5c55\u793a","\u4fe1\u606f\u53cd\u9988"].reverse().forEach((function(e,t){b[e]=++t}));var v,S=[];[i].forEach((function(e){Array.isArray(e)?S.push.apply(S,c(e.map((function(e){return h(e)})))):e.components?S.push.apply(S,c(e.components.map((function(e){return h(e)})))):S.push(h(e))}));var O=g(S),j=!0}])}));
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/public/fixtures/basic-fusion-with-single-component/meta.js:
--------------------------------------------------------------------------------
1 | !function e(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.M220318Meta=n():t.M220318Meta=n()}(window,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function t(){return e.default}:function t(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";n.r(t),n.d(t,"components",(function(){return S})),n.d(t,"componentList",(function(){return O}));var r={componentName:"M220318",title:"M220318",docUrl:"",screenshot:"",devMode:"proCode",npm:{package:"m-220318",version:"0.1.0",exportName:"default",main:"src/index.tsx",destructuring:!1,subName:""},configure:{props:[{title:{label:{type:"i18n","en-US":"title","zh-CN":"title"}},name:"title",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"content","zh-CN":"content"}},name:"content",setter:{componentName:"StringSetter",isRequired:!0,initialValue:""}},{title:{label:{type:"i18n","en-US":"ref","zh-CN":"ref"}},name:"ref",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"FunctionSetter"},{componentName:"ObjectSetter",props:{config:{extraSetter:{componentName:"MixedSetter",isRequired:!1,props:{}}}},isRequired:!1,initialValue:{}}]}}},{title:{label:{type:"i18n","en-US":"key","zh-CN":"key"}},name:"key",setter:{componentName:"MixedSetter",props:{setters:[{componentName:"StringSetter",isRequired:!1,initialValue:""},{componentName:"NumberSetter",isRequired:!1,initialValue:0}]}}}],supports:{style:!0},component:{}}},o=[{title:"M220318",screenshot:"",schema:{componentName:"M220318",props:{}}}],i=Object.assign(Object.assign({},r),{snippets:o});function c(e){return l(e)||p(e)||u(e)||a()}function a(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function u(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function p(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function l(e){if(Array.isArray(e))return s(e)}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:"m-220318",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"0.1.0",r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{"@alifd/next":"1.25.23","@alifd/meet":"2.6.3",antd:"4.17.3"};if(!e||!n)return e;var o=e.npm;return o?("object"===d(r)&&r[o.package]?e.npm=m(m({},o),{},{version:r[o.package]}):o.package===t&&(e.npm=m(m({},o),{},{version:n})),e):e}["\u57fa\u7840\u5143\u7d20","\u5e03\u5c40\u5bb9\u5668\u7c7b","\u8868\u683c\u7c7b","\u8868\u5355\u8be6\u60c5\u7c7b","\u5e2e\u52a9\u7c7b","\u5bf9\u8bdd\u6846\u7c7b","\u4e1a\u52a1\u7c7b","\u901a\u7528","\u5f15\u5bfc","\u4fe1\u606f\u8f93\u5165","\u4fe1\u606f\u5c55\u793a","\u4fe1\u606f\u53cd\u9988"].reverse().forEach((function(e,t){b[e]=++t}));var v,S=[];[i].forEach((function(e){Array.isArray(e)?S.push.apply(S,c(e.map((function(e){return h(e)})))):e.components?S.push.apply(S,c(e.components.map((function(e){return h(e)})))):S.push(h(e))}));var O=g(S),j=!0}])}));
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/universal/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | {
4 | "package": "moment",
5 | "version": "2.24.0",
6 | "urls": [
7 | "https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"
8 | ],
9 | "library": "moment"
10 | },
11 | {
12 | "package": "lodash",
13 | "library": "_",
14 | "urls": [
15 | "https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"
16 | ]
17 | },
18 | {
19 | "package": "vue",
20 | "library": "Vue",
21 | "urls": [
22 | "./vue/vue.global.js"
23 | ]
24 | },
25 | {
26 | "title": "fusion组件库",
27 | "package": "@alifd/next",
28 | "version": "1.24.18",
29 | "urls": [
30 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css",
31 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js"
32 | ],
33 | "library": "Next"
34 | },
35 | {
36 | "title": "NextTable",
37 | "package": "NextTable",
38 | "version": "1.0.1",
39 | "urls": [
40 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.js",
41 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.css"
42 | ],
43 | "library": "NextTable"
44 | },
45 | {
46 | "package": "@alilc/lowcode-materials",
47 | "version": "1.0.2",
48 | "library": "AlilcLowcodeMaterials",
49 | "urls": [
50 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.js",
51 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.css"
52 | ],
53 | "editUrls": [
54 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.js",
55 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.css"
56 | ]
57 | },
58 | {
59 | "package": "@alifd/pro-layout",
60 | "version": "1.0.1-beta.6",
61 | "library": "AlifdProLayout",
62 | "urls": [
63 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.js",
64 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.css"
65 | ],
66 | "editUrls": [
67 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.js",
68 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.css"
69 | ]
70 | },
71 | {
72 | "package": "@alifd/fusion-ui",
73 | "version": "1.0.5",
74 | "library": "AlifdFusionUi",
75 | "urls": [
76 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.js",
77 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.css"
78 | ],
79 | "editUrls": [
80 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.js",
81 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.css"
82 | ]
83 | },
84 | {
85 | "package": "tdesign-vue-next",
86 | "version": "0.15.4",
87 | "urls": [
88 | "./tdesign/tdesign.min.css",
89 | "./tdesign/tdesign.min.js"
90 | ],
91 | "library": "TDesign"
92 | }
93 | ],
94 | "components": [
95 | {
96 | "exportName": "AlilcLowcodeMaterialsMeta",
97 | "npm": {
98 | "package": "@alilc/lowcode-materials"
99 | },
100 | "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
101 | "urls": {
102 | "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
103 | "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.design.js"
104 | }
105 | },
106 | {
107 | "exportName": "AlifdProLayoutMeta",
108 | "npm": {
109 | "package": "@alifd/pro-layout",
110 | "version": "1.0.1-beta.6"
111 | },
112 | "url": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js",
113 | "urls": {
114 | "default": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js",
115 | "design": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.design.js"
116 | }
117 | },
118 | {
119 | "exportName": "AlifdFusionUiMeta",
120 | "npm": {
121 | "package": "@alifd/fusion-ui"
122 | },
123 | "url": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js",
124 | "urls": {
125 | "default": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js",
126 | "design": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.design.js"
127 | }
128 | },
129 | {
130 | "componentName": "TButton",
131 | "title": "按钮",
132 | "npm": {
133 | "package": "tdesign-vue-next",
134 | "version": "0.15.4",
135 | "exportName": "Button",
136 | "destructuring": true,
137 | "devStack": "vue3"
138 | },
139 | "props": [
140 | {
141 | "name": "theme",
142 | "propType": "string"
143 | }
144 | ],
145 | "configure": {
146 | "component": {
147 | "isContainer": false
148 | },
149 | "supports": {
150 | "style": true,
151 | "events": [
152 | {
153 | "name": "onClick",
154 | "template": "onClick(e){\n// click\nconsole.log('click', e);}"
155 | }
156 | ]
157 | },
158 | "props": {
159 | "isExtends": true,
160 | "override": [
161 | {
162 | "name": "theme",
163 | "title": "主题",
164 | "setter": {
165 | "componentName": "StringSetter"
166 | }
167 | },
168 | {
169 | "name": "class",
170 | "setter": {
171 | "componentName": "ClassNameSetter"
172 | }
173 | }
174 | ]
175 | }
176 | },
177 | "group": "自定义",
178 | "category": "基础元素",
179 | "snippets": [
180 | {
181 | "title": "按钮",
182 | "screenshot": "https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_button.png",
183 | "schema": {
184 | "componentName": "TButton",
185 | "props": {
186 | "theme": "success"
187 | },
188 | "children": [
189 | {
190 | "componentName": "NextText",
191 | "props": {
192 | "children": "按钮"
193 | }
194 | }
195 | ]
196 | }
197 | }
198 | ]
199 | }
200 | ],
201 | "sort": {
202 | "groupList": [
203 | "精选组件",
204 | "原子组件"
205 | ],
206 | "categoryList": [
207 | "基础元素",
208 | "布局容器类",
209 | "表格类",
210 | "表单详情类",
211 | "帮助类",
212 | "对话框类",
213 | "业务类",
214 | "通用",
215 | "引导",
216 | "信息输入",
217 | "信息展示",
218 | "信息反馈"
219 | ]
220 | },
221 | "groupList": [
222 | "精选组件",
223 | "原子组件"
224 | ],
225 | "ignoreComponents": {}
226 | }
227 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/universal/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": [
3 | {
4 | "package": "moment",
5 | "version": "2.24.0",
6 | "urls": [
7 | "https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"
8 | ],
9 | "library": "moment"
10 | },
11 | {
12 | "package": "lodash",
13 | "library": "_",
14 | "urls": [
15 | "https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"
16 | ]
17 | },
18 | {
19 | "package": "vue",
20 | "library": "Vue",
21 | "urls": [
22 | "./vue/vue.js"
23 | ]
24 | },
25 | {
26 | "title": "fusion组件库",
27 | "package": "@alifd/next",
28 | "version": "1.24.18",
29 | "urls": [
30 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css",
31 | "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js"
32 | ],
33 | "library": "Next"
34 | },
35 | {
36 | "title": "NextTable",
37 | "package": "NextTable",
38 | "version": "1.0.1",
39 | "urls": [
40 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.js",
41 | "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.css"
42 | ],
43 | "library": "NextTable"
44 | },
45 | {
46 | "package": "@alilc/lowcode-materials",
47 | "version": "1.0.2",
48 | "library": "AlilcLowcodeMaterials",
49 | "urls": [
50 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.js",
51 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/dist/AlilcLowcodeMaterials.css"
52 | ],
53 | "editUrls": [
54 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.js",
55 | "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/view.css"
56 | ]
57 | },
58 | {
59 | "package": "@alifd/pro-layout",
60 | "version": "1.0.1-beta.6",
61 | "library": "AlifdProLayout",
62 | "urls": [
63 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.js",
64 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.css"
65 | ],
66 | "editUrls": [
67 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.js",
68 | "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.css"
69 | ]
70 | },
71 | {
72 | "package": "@alifd/fusion-ui",
73 | "version": "1.0.5",
74 | "library": "AlifdFusionUi",
75 | "urls": [
76 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.js",
77 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/dist/AlifdFusionUi.css"
78 | ],
79 | "editUrls": [
80 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.js",
81 | "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/view.css"
82 | ]
83 | },
84 | {
85 | "package": "element-ui",
86 | "version": "2.15.9",
87 | "urls": [
88 | "https://unpkg.com/element-ui/lib/theme-chalk/index.css",
89 | "https://unpkg.com/element-ui/lib/index.js"
90 | ],
91 | "library": "ELEMENT"
92 | }
93 | ],
94 | "components": [
95 | {
96 | "exportName": "AlilcLowcodeMaterialsMeta",
97 | "npm": {
98 | "package": "@alilc/lowcode-materials"
99 | },
100 | "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
101 | "urls": {
102 | "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.js",
103 | "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.2/build/lowcode/meta.design.js"
104 | }
105 | },
106 | {
107 | "exportName": "AlifdProLayoutMeta",
108 | "npm": {
109 | "package": "@alifd/pro-layout",
110 | "version": "1.0.1-beta.6"
111 | },
112 | "url": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js",
113 | "urls": {
114 | "default": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.js",
115 | "design": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/meta.design.js"
116 | }
117 | },
118 | {
119 | "exportName": "AlifdFusionUiMeta",
120 | "npm": {
121 | "package": "@alifd/fusion-ui"
122 | },
123 | "url": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js",
124 | "urls": {
125 | "default": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.js",
126 | "design": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5/build/lowcode/meta.design.js"
127 | }
128 | },
129 | {
130 | "componentName": "ELButton",
131 | "title": "按钮",
132 | "npm": {
133 | "package": "element-ui",
134 | "version": "2.15.9",
135 | "exportName": "Button",
136 | "destructuring": true,
137 | "devStack": "vue2"
138 | },
139 | "props": [
140 | {
141 | "name": "type",
142 | "propType": "string"
143 | }
144 | ],
145 | "configure": {
146 | "component": {
147 | "isContainer": false
148 | },
149 | "supports": {
150 | "style": true,
151 | "events": [
152 | {
153 | "name": "onClick",
154 | "template": "onClick(e){\n// click\nconsole.log('click', e);}"
155 | }
156 | ]
157 | },
158 | "props": {
159 | "isExtends": true,
160 | "override": [
161 | {
162 | "name": "type",
163 | "title": "类型",
164 | "setter": {
165 | "componentName": "StringSetter"
166 | }
167 | },
168 | {
169 | "name": "class",
170 | "setter": {
171 | "componentName": "ClassNameSetter"
172 | }
173 | }
174 | ]
175 | }
176 | },
177 | "group": "自定义",
178 | "category": "基础元素",
179 | "snippets": [
180 | {
181 | "title": "按钮",
182 | "screenshot": "https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_button.png",
183 | "schema": {
184 | "componentName": "ELButton",
185 | "props": {
186 | "type": "danger"
187 | },
188 | "children": [
189 | {
190 | "componentName": "NextText",
191 | "props": {
192 | "children": "按钮"
193 | }
194 | }
195 | ]
196 | }
197 | }
198 | ]
199 | }
200 | ],
201 | "sort": {
202 | "groupList": [
203 | "精选组件",
204 | "原子组件"
205 | ],
206 | "categoryList": [
207 | "基础元素",
208 | "布局容器类",
209 | "表格类",
210 | "表单详情类",
211 | "帮助类",
212 | "对话框类",
213 | "业务类",
214 | "通用",
215 | "引导",
216 | "信息输入",
217 | "信息展示",
218 | "信息反馈"
219 | ]
220 | },
221 | "groupList": [
222 | "精选组件",
223 | "原子组件"
224 | ],
225 | "ignoreComponents": {}
226 | }
227 |
--------------------------------------------------------------------------------
/examples/lowcode-vue2-demo/src/universal/plugin.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | ILowCodePluginContext,
4 | plugins,
5 | skeleton,
6 | project,
7 | setters,
8 | } from '@alilc/lowcode-engine';
9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext';
10 | import { Button } from '@alifd/next';
11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo';
12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane';
13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en';
14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator';
15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane';
16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema';
17 | import CodeEditor from '@alilc/lowcode-plugin-code-editor';
18 | import ManualPlugin from '@alilc/lowcode-plugin-manual';
19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select';
21 |
22 | // 注册到引擎
23 | import TitleSetter from '@alilc/lowcode-setter-title';
24 | import BehaviorSetter from '../setters/behavior-setter';
25 | import CustomSetter from '../setters/custom-setter';
26 | import Logo from '../sample-plugins/logo';
27 | import { deleteHiddenTransducer } from '../sample-plugins/delete-hidden-transducer';
28 |
29 | import {
30 | loadIncrementalAssets,
31 | getPageSchema,
32 | saveSchema,
33 | resetSchema,
34 | preview,
35 | } from './utils';
36 | import assets from './assets.json';
37 | import { registerRefProp } from 'src/sample-plugins/set-ref-prop';
38 |
39 | export default async function registerPlugins() {
40 | await plugins.register(ManualPlugin);
41 |
42 | await plugins.register(Inject);
43 |
44 | await plugins.register(registerRefProp);
45 |
46 | await plugins.register(deleteHiddenTransducer);
47 |
48 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh
49 | SchemaPlugin.pluginName = 'SchemaPlugin';
50 | await plugins.register(SchemaPlugin);
51 |
52 | SimulatorResizer.pluginName = 'SimulatorResizer';
53 | plugins.register(SimulatorResizer);
54 |
55 | const editorInit = (ctx: ILowCodePluginContext) => {
56 | return {
57 | name: 'editor-init',
58 | async init() {
59 | // 修改面包屑组件的分隔符属性setter
60 | // const assets = await (
61 | // await fetch(
62 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json`
63 | // )
64 | // ).json();
65 | // 设置物料描述
66 | const { material, project } = ctx;
67 |
68 | await material.setAssets(await injectAssets(assets));
69 |
70 | const schema = await getPageSchema();
71 |
72 | // 加载 schema
73 | project.openDocument(schema);
74 | },
75 | };
76 | };
77 | editorInit.pluginName = 'editorInit';
78 | await plugins.register(editorInit);
79 |
80 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
81 | return {
82 | name: 'builtin-plugin-registry',
83 | async init() {
84 | const { skeleton } = ctx;
85 | // 注册 logo 面板
86 | skeleton.add({
87 | area: 'topArea',
88 | type: 'Widget',
89 | name: 'logo',
90 | content: Logo,
91 | contentProps: {
92 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg',
93 | href: 'https://lowcode-engine.cn',
94 | },
95 | props: {
96 | align: 'left',
97 | },
98 | });
99 |
100 | // 注册组件面板
101 | const componentsPane = skeleton.add({
102 | area: 'leftArea',
103 | type: 'PanelDock',
104 | name: 'componentsPane',
105 | content: ComponentsPane,
106 | contentProps: {},
107 | props: {
108 | align: 'top',
109 | icon: 'zujianku',
110 | description: '组件库',
111 | },
112 | });
113 | componentsPane?.disable?.();
114 | project.onSimulatorRendererReady(() => {
115 | componentsPane?.enable?.();
116 | });
117 | },
118 | };
119 | };
120 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry';
121 | await plugins.register(builtinPluginRegistry);
122 |
123 | // 设置内置 setter 和事件绑定、插件绑定面板
124 | const setterRegistry = (ctx: ILowCodePluginContext) => {
125 | const { setterMap, pluginMap } = AliLowCodeEngineExt;
126 | return {
127 | name: 'ext-setters-registry',
128 | async init() {
129 | const { setters, skeleton } = ctx;
130 | // 注册setterMap
131 | setters.registerSetter(setterMap);
132 | // 注册插件
133 | // 注册事件绑定面板
134 | skeleton.add({
135 | area: 'centerArea',
136 | type: 'Widget',
137 | content: pluginMap.EventBindDialog,
138 | name: 'eventBindDialog',
139 | props: {},
140 | });
141 |
142 | // 注册变量绑定面板
143 | skeleton.add({
144 | area: 'centerArea',
145 | type: 'Widget',
146 | content: pluginMap.VariableBindDialog,
147 | name: 'variableBindDialog',
148 | props: {},
149 | });
150 | },
151 | };
152 | };
153 | setterRegistry.pluginName = 'setterRegistry';
154 | await plugins.register(setterRegistry);
155 |
156 | // 注册回退/前进
157 | await plugins.register(UndoRedoPlugin);
158 |
159 | // 注册中英文切换
160 | await plugins.register(ZhEnPlugin);
161 |
162 | const loadAssetsSample = (ctx: ILowCodePluginContext) => {
163 | return {
164 | name: 'loadAssetsSample',
165 | async init() {
166 | const { skeleton } = ctx;
167 |
168 | skeleton.add({
169 | name: 'loadAssetsSample',
170 | area: 'topArea',
171 | type: 'Widget',
172 | props: {
173 | align: 'right',
174 | width: 80,
175 | },
176 | content: (
177 |
180 | ),
181 | });
182 | },
183 | };
184 | };
185 | loadAssetsSample.pluginName = 'loadAssetsSample';
186 | await plugins.register(loadAssetsSample);
187 |
188 | // 注册保存面板
189 | const saveSample = (ctx: ILowCodePluginContext) => {
190 | return {
191 | name: 'saveSample',
192 | async init() {
193 | const { skeleton, hotkey } = ctx;
194 |
195 | skeleton.add({
196 | name: 'saveSample',
197 | area: 'topArea',
198 | type: 'Widget',
199 | props: {
200 | align: 'right',
201 | },
202 | content: (
203 |
206 | ),
207 | });
208 | skeleton.add({
209 | name: 'resetSchema',
210 | area: 'topArea',
211 | type: 'Widget',
212 | props: {
213 | align: 'right',
214 | },
215 | content: (
216 |
219 | ),
220 | });
221 | hotkey.bind('command+s', (e) => {
222 | e.preventDefault();
223 | saveSchema();
224 | });
225 | },
226 | };
227 | };
228 | saveSample.pluginName = 'saveSample';
229 | await plugins.register(saveSample);
230 |
231 | DataSourcePanePlugin.pluginName = 'DataSourcePane';
232 | await plugins.register(DataSourcePanePlugin);
233 |
234 | CodeEditor.pluginName = 'CodeEditor';
235 | await plugins.register(CodeEditor);
236 |
237 | // 注册出码插件
238 | CodeGenPlugin.pluginName = 'CodeGenPlugin';
239 | await plugins.register(CodeGenPlugin);
240 |
241 | const previewSample = (ctx: ILowCodePluginContext) => {
242 | return {
243 | name: 'previewSample',
244 | async init() {
245 | const { skeleton } = ctx;
246 | skeleton.add({
247 | name: 'previewSample',
248 | area: 'topArea',
249 | type: 'Widget',
250 | props: {
251 | align: 'right',
252 | },
253 | content: (
254 |
257 | ),
258 | });
259 | },
260 | };
261 | };
262 | previewSample.pluginName = 'previewSample';
263 | await plugins.register(previewSample);
264 |
265 | const customSetter = (ctx: ILowCodePluginContext) => {
266 | return {
267 | name: '___registerCustomSetter___',
268 | async init() {
269 | const { setters } = ctx;
270 |
271 | setters.registerSetter('TitleSetter', TitleSetter);
272 | setters.registerSetter('BehaviorSetter', BehaviorSetter);
273 | setters.registerSetter('CustomSetter', CustomSetter);
274 | },
275 | };
276 | };
277 | customSetter.pluginName = 'customSetter';
278 | await plugins.register(customSetter);
279 | }
280 |
--------------------------------------------------------------------------------
/examples/lowcode-vue3-demo/src/universal/plugin.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {
3 | ILowCodePluginContext,
4 | plugins,
5 | skeleton,
6 | project,
7 | setters,
8 | } from '@alilc/lowcode-engine';
9 | import AliLowCodeEngineExt from '@alilc/lowcode-engine-ext';
10 | import { Button } from '@alifd/next';
11 | import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo';
12 | import ComponentsPane from '@alilc/lowcode-plugin-components-pane';
13 | import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en';
14 | import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator';
15 | import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane';
16 | import SchemaPlugin from '@alilc/lowcode-plugin-schema';
17 | import CodeEditor from '@alilc/lowcode-plugin-code-editor';
18 | import ManualPlugin from '@alilc/lowcode-plugin-manual';
19 | import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
20 | import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select';
21 |
22 | // 注册到引擎
23 | import TitleSetter from '@alilc/lowcode-setter-title';
24 | import BehaviorSetter from '../setters/behavior-setter';
25 | import CustomSetter from '../setters/custom-setter';
26 | import Logo from '../sample-plugins/logo';
27 | import { deleteHiddenTransducer } from '../sample-plugins/delete-hidden-transducer';
28 |
29 | import {
30 | loadIncrementalAssets,
31 | getPageSchema,
32 | saveSchema,
33 | resetSchema,
34 | preview,
35 | } from './utils';
36 | import assets from './assets.json';
37 | import { registerRefProp } from 'src/sample-plugins/set-ref-prop';
38 |
39 | export default async function registerPlugins() {
40 | await plugins.register(ManualPlugin);
41 |
42 | await plugins.register(Inject);
43 |
44 | await plugins.register(registerRefProp);
45 |
46 | await plugins.register(deleteHiddenTransducer);
47 |
48 | // plugin API 见 https://lowcode-engine.cn/docV2/ibh9fh
49 | SchemaPlugin.pluginName = 'SchemaPlugin';
50 | await plugins.register(SchemaPlugin);
51 |
52 | SimulatorResizer.pluginName = 'SimulatorResizer';
53 | plugins.register(SimulatorResizer);
54 |
55 | const editorInit = (ctx: ILowCodePluginContext) => {
56 | return {
57 | name: 'editor-init',
58 | async init() {
59 | // 修改面包屑组件的分隔符属性setter
60 | // const assets = await (
61 | // await fetch(
62 | // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json`
63 | // )
64 | // ).json();
65 | // 设置物料描述
66 | const { material, project } = ctx;
67 |
68 | await material.setAssets(await injectAssets(assets));
69 |
70 | const schema = await getPageSchema();
71 |
72 | // 加载 schema
73 | project.openDocument(schema);
74 | },
75 | };
76 | };
77 | editorInit.pluginName = 'editorInit';
78 | await plugins.register(editorInit);
79 |
80 | const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
81 | return {
82 | name: 'builtin-plugin-registry',
83 | async init() {
84 | const { skeleton } = ctx;
85 | // 注册 logo 面板
86 | skeleton.add({
87 | area: 'topArea',
88 | type: 'Widget',
89 | name: 'logo',
90 | content: Logo,
91 | contentProps: {
92 | logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg',
93 | href: 'https://lowcode-engine.cn',
94 | },
95 | props: {
96 | align: 'left',
97 | },
98 | });
99 |
100 | // 注册组件面板
101 | const componentsPane = skeleton.add({
102 | area: 'leftArea',
103 | type: 'PanelDock',
104 | name: 'componentsPane',
105 | content: ComponentsPane,
106 | contentProps: {},
107 | props: {
108 | align: 'top',
109 | icon: 'zujianku',
110 | description: '组件库',
111 | },
112 | });
113 | componentsPane?.disable?.();
114 | project.onSimulatorRendererReady(() => {
115 | componentsPane?.enable?.();
116 | });
117 | },
118 | };
119 | };
120 | builtinPluginRegistry.pluginName = 'builtinPluginRegistry';
121 | await plugins.register(builtinPluginRegistry);
122 |
123 | // 设置内置 setter 和事件绑定、插件绑定面板
124 | const setterRegistry = (ctx: ILowCodePluginContext) => {
125 | const { setterMap, pluginMap } = AliLowCodeEngineExt;
126 | return {
127 | name: 'ext-setters-registry',
128 | async init() {
129 | const { setters, skeleton } = ctx;
130 | // 注册setterMap
131 | setters.registerSetter(setterMap);
132 | // 注册插件
133 | // 注册事件绑定面板
134 | skeleton.add({
135 | area: 'centerArea',
136 | type: 'Widget',
137 | content: pluginMap.EventBindDialog,
138 | name: 'eventBindDialog',
139 | props: {},
140 | });
141 |
142 | // 注册变量绑定面板
143 | skeleton.add({
144 | area: 'centerArea',
145 | type: 'Widget',
146 | content: pluginMap.VariableBindDialog,
147 | name: 'variableBindDialog',
148 | props: {},
149 | });
150 | },
151 | };
152 | };
153 | setterRegistry.pluginName = 'setterRegistry';
154 | await plugins.register(setterRegistry);
155 |
156 | // 注册回退/前进
157 | await plugins.register(UndoRedoPlugin);
158 |
159 | // 注册中英文切换
160 | await plugins.register(ZhEnPlugin);
161 |
162 | const loadAssetsSample = (ctx: ILowCodePluginContext) => {
163 | return {
164 | name: 'loadAssetsSample',
165 | async init() {
166 | const { skeleton } = ctx;
167 |
168 | skeleton.add({
169 | name: 'loadAssetsSample',
170 | area: 'topArea',
171 | type: 'Widget',
172 | props: {
173 | align: 'right',
174 | width: 80,
175 | },
176 | content: (
177 |
180 | ),
181 | });
182 | },
183 | };
184 | };
185 | loadAssetsSample.pluginName = 'loadAssetsSample';
186 | await plugins.register(loadAssetsSample);
187 |
188 | // 注册保存面板
189 | const saveSample = (ctx: ILowCodePluginContext) => {
190 | return {
191 | name: 'saveSample',
192 | async init() {
193 | const { skeleton, hotkey } = ctx;
194 |
195 | skeleton.add({
196 | name: 'saveSample',
197 | area: 'topArea',
198 | type: 'Widget',
199 | props: {
200 | align: 'right',
201 | },
202 | content: (
203 |
206 | ),
207 | });
208 | skeleton.add({
209 | name: 'resetSchema',
210 | area: 'topArea',
211 | type: 'Widget',
212 | props: {
213 | align: 'right',
214 | },
215 | content: (
216 |
219 | ),
220 | });
221 | hotkey.bind('command+s', (e) => {
222 | e.preventDefault();
223 | saveSchema();
224 | });
225 | },
226 | };
227 | };
228 | saveSample.pluginName = 'saveSample';
229 | await plugins.register(saveSample);
230 |
231 | DataSourcePanePlugin.pluginName = 'DataSourcePane';
232 | await plugins.register(DataSourcePanePlugin);
233 |
234 | CodeEditor.pluginName = 'CodeEditor';
235 | await plugins.register(CodeEditor);
236 |
237 | // 注册出码插件
238 | CodeGenPlugin.pluginName = 'CodeGenPlugin';
239 | await plugins.register(CodeGenPlugin);
240 |
241 | const previewSample = (ctx: ILowCodePluginContext) => {
242 | return {
243 | name: 'previewSample',
244 | async init() {
245 | const { skeleton } = ctx;
246 | skeleton.add({
247 | name: 'previewSample',
248 | area: 'topArea',
249 | type: 'Widget',
250 | props: {
251 | align: 'right',
252 | },
253 | content: (
254 |
257 | ),
258 | });
259 | },
260 | };
261 | };
262 | previewSample.pluginName = 'previewSample';
263 | await plugins.register(previewSample);
264 |
265 | const customSetter = (ctx: ILowCodePluginContext) => {
266 | return {
267 | name: '___registerCustomSetter___',
268 | async init() {
269 | const { setters } = ctx;
270 |
271 | setters.registerSetter('TitleSetter', TitleSetter);
272 | setters.registerSetter('BehaviorSetter', BehaviorSetter);
273 | setters.registerSetter('CustomSetter', CustomSetter);
274 | },
275 | };
276 | };
277 | customSetter.pluginName = 'customSetter';
278 | await plugins.register(customSetter);
279 | }
280 |
--------------------------------------------------------------------------------
/packages/vue2-simulator-renderer/src/builtin-components/builtin-components.ts:
--------------------------------------------------------------------------------
1 | import { ReactElement, createElement, ReactType } from 'react';
2 | import classNames from 'classnames';
3 |
4 | const supportedEvents = [
5 | // MouseEvents
6 | {
7 | name: 'onClick',
8 | description: '点击时',
9 | },
10 | {
11 | name: 'onDoubleClick',
12 | description: '双击时',
13 | },
14 | {
15 | name: 'onMouseDown',
16 | description: '鼠标按下',
17 | },
18 | {
19 | name: 'onMouseEnter',
20 | description: '鼠标进入',
21 | },
22 | {
23 | name: 'onMouseMove',
24 | description: '鼠标移动',
25 | },
26 | {
27 | name: 'onMouseOut',
28 | description: '鼠标移出',
29 | },
30 | {
31 | name: 'onMouseOver',
32 | description: '鼠标悬停',
33 | },
34 | {
35 | name: 'onMouseUp',
36 | description: '鼠标松开',
37 | },
38 | // Focus Events
39 | {
40 | name: 'onFocus',
41 | description: '获得焦点',
42 | snippet: '',
43 | },
44 | {
45 | name: 'onBlur',
46 | description: '失去焦点',
47 | snippet: '',
48 | },
49 | // Form Events
50 | {
51 | name: 'onChange',
52 | description: '值改变时',
53 | snippet: '',
54 | },
55 | {
56 | name: 'onSelect',
57 | description: '选择',
58 | },
59 | {
60 | name: 'onInput',
61 | description: '输入',
62 | snippet: '',
63 | },
64 | {
65 | name: 'onReset',
66 | description: '重置',
67 | snippet: '',
68 | },
69 | {
70 | name: 'onSubmit',
71 | description: '提交',
72 | snippet: '',
73 | },
74 | // Clipboard Events
75 | {
76 | name: 'onCopy',
77 | description: '复制',
78 | snippet: '',
79 | },
80 | {
81 | name: 'onCut',
82 | description: '剪切',
83 | snippet: '',
84 | },
85 | {
86 | name: 'onPaste',
87 | description: '粘贴',
88 | snippet: '',
89 | },
90 |
91 | // Keyboard Events
92 | {
93 | name: 'onKeyDown',
94 | description: '键盘按下',
95 | snippet: '',
96 | },
97 | {
98 | name: 'onKeyPress',
99 | description: '键盘按下并释放',
100 | snippet: '',
101 | },
102 | {
103 | name: 'onKeyUp',
104 | description: '键盘松开',
105 | snippet: '',
106 | },
107 | // Touch Events
108 | {
109 | name: 'onTouchCancel',
110 | description: '触摸退出',
111 | snippet: '',
112 | },
113 | {
114 | name: 'onTouchEnd',
115 | description: '触摸结束',
116 | snippet: '',
117 | },
118 | {
119 | name: 'onTouchMove',
120 | description: '触摸移动',
121 | snippet: '',
122 | },
123 | {
124 | name: 'onTouchStart',
125 | description: '触摸开始',
126 | snippet: '',
127 | },
128 | // UI Events
129 | {
130 | name: 'onScroll',
131 | description: '滚动',
132 | snippet: '',
133 | },
134 | {
135 | name: 'onLoad',
136 | description: '加载完毕',
137 | snippet: '',
138 | },
139 | {
140 | name: 'onWheel',
141 | description: '滚轮事件',
142 | snippet: '',
143 | },
144 | // Animation Events
145 | {
146 | name: 'onAnimationStart',
147 | description: '动画开始',
148 | },
149 | {
150 | name: 'onAnimationEnd',
151 | description: '动画结束',
152 | },
153 | ];
154 |
155 | // eslint-disable-next-line func-call-spacing
156 | const builtinComponents = new Map ReactElement>();
157 | function getBlockElement(tag: string): (props: any) => ReactElement {
158 | if (builtinComponents.has(tag)) {
159 | return builtinComponents.get(tag)!;
160 | }
161 | const mock = ({ className, children, ...rest }: any = {}) => {
162 | const props = {
163 | ...rest,
164 | className: classNames('lc-block-container', className),
165 | };
166 | return createElement(tag, props, children);
167 | };
168 |
169 | mock.metadata = {
170 | componentName: tag,
171 | // selfControlled: true,
172 | configure: {
173 | props: [],
174 | events: {
175 | supportedEvents,
176 | },
177 | styles: {
178 | supportClassName: true,
179 | supportInlineStyle: true,
180 | },
181 | component: {
182 | ...metasMap[tag],
183 | },
184 | },
185 | };
186 |
187 | builtinComponents.set(tag, mock);
188 | return mock;
189 | }
190 |
191 | const HTMLBlock = [
192 | 'div',
193 | 'p',
194 | 'article',
195 | 'h1',
196 | 'h2',
197 | 'h3',
198 | 'h4',
199 | 'h5',
200 | 'h6',
201 | 'aside',
202 | 'blockquote',
203 | 'footer',
204 | 'form',
205 | 'header',
206 | 'table',
207 | 'tbody',
208 | 'section',
209 | 'ul',
210 | 'li',
211 | ];
212 |
213 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
214 | const HTMLInlineBlock = ['a', 'b', 'span', 'em'];
215 | export function getIntrinsicMock(tag: string): ReactType {
216 | if (HTMLBlock.indexOf(tag) > -1) {
217 | return getBlockElement(tag);
218 | }
219 |
220 | return tag as any;
221 | }
222 |
223 | const metasMap: any = {
224 | div: {
225 | isContainer: true,
226 | nesting: {
227 | ancestorBlacklist: 'p',
228 | },
229 | },
230 | ul: {
231 | isContainer: true,
232 | nesting: {
233 | childWhitelist: 'li',
234 | },
235 | },
236 | p: {
237 | isContainer: true,
238 | nesting: {
239 | ancestorBlacklist: 'button,p',
240 | },
241 | },
242 | li: {
243 | isContainer: true,
244 | nesting: {
245 | parentWhitelist: 'ui,ol',
246 | },
247 | },
248 | span: {
249 | isContainer: true,
250 | selfControlled: true,
251 | },
252 | a: {
253 | isContainer: true,
254 | nesting: {
255 | ancestorBlacklist: 'a',
256 | },
257 | },
258 | b: {
259 | isContainer: true,
260 | },
261 | strong: {
262 | isContainer: true,
263 | },
264 | em: {
265 | isContainer: true,
266 | },
267 | i: {
268 | isContainer: true,
269 | },
270 | form: {
271 | isContainer: true,
272 | nestingRule: {
273 | ancestorBlacklist: 'form,button',
274 | },
275 | },
276 | table: {
277 | isContainer: true,
278 | nestingRule: {
279 | ancestorBlacklist: 'button',
280 | },
281 | },
282 | caption: {
283 | isContainer: true,
284 | selfControlled: true,
285 | nestingRule: {
286 | ancestorBlacklist: 'button',
287 | },
288 | },
289 | select: {
290 | isContainer: true,
291 | selfControlled: true,
292 | nestingRule: {
293 | ancestorBlacklist: 'button',
294 | },
295 | },
296 | button: {
297 | isContainer: true,
298 | nestingRule: {
299 | ancestorBlacklist: 'button',
300 | },
301 | },
302 | input: {
303 | isContainer: false,
304 | nestingRule: {
305 | ancestorBlacklist: 'button,h1,h2,h3,h4,h5,h6',
306 | },
307 | },
308 | textarea: {
309 | isContainer: false,
310 | nestingRule: {
311 | ancestorBlacklist: 'button',
312 | },
313 | },
314 | image: {
315 | isContainer: false,
316 | },
317 | canvas: {
318 | isContainer: false,
319 | },
320 | br: {
321 | isContainer: false,
322 | },
323 | h1: {
324 | isContainer: true,
325 | nestingRule: {
326 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
327 | },
328 | },
329 | h2: {
330 | isContainer: true,
331 | nestingRule: {
332 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
333 | },
334 | },
335 | h3: {
336 | isContainer: true,
337 | nestingRule: {
338 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
339 | },
340 | },
341 | h4: {
342 | isContainer: true,
343 | nestingRule: {
344 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
345 | },
346 | },
347 | h5: {
348 | isContainer: true,
349 | nestingRule: {
350 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
351 | },
352 | },
353 | h6: {
354 | isContainer: true,
355 | nestingRule: {
356 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
357 | },
358 | },
359 | article: {
360 | isContainer: true,
361 | nestingRule: {
362 | ancestorBlacklist: 'button',
363 | },
364 | },
365 | aside: {
366 | isContainer: true,
367 | nestingRule: {
368 | ancestorBlacklist: 'button',
369 | },
370 | },
371 | footer: {
372 | isContainer: true,
373 | nestingRule: {
374 | ancestorBlacklist: 'button',
375 | },
376 | },
377 | header: {
378 | isContainer: true,
379 | nestingRule: {
380 | ancestorBlacklist: 'button',
381 | },
382 | },
383 | blockquote: {
384 | isContainer: true,
385 | nestingRule: {
386 | ancestorBlacklist: 'button',
387 | },
388 | },
389 | address: {
390 | isContainer: true,
391 | nestingRule: {
392 | ancestorBlacklist: 'button',
393 | },
394 | },
395 | section: {
396 | isContainer: true,
397 | nestingRule: {
398 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
399 | },
400 | },
401 | summary: {
402 | isContainer: true,
403 | nestingRule: {
404 | ancestorBlacklist: 'button',
405 | },
406 | },
407 | nav: {
408 | isContainer: true,
409 | nestingRule: {
410 | ancestorBlacklist: 'button',
411 | },
412 | },
413 | };
414 |
--------------------------------------------------------------------------------
/packages/vue3-simulator-renderer/src/builtin-components/builtin-components.ts:
--------------------------------------------------------------------------------
1 | import { ReactElement, createElement, ReactType } from 'react';
2 | import classNames from 'classnames';
3 |
4 | const supportedEvents = [
5 | // MouseEvents
6 | {
7 | name: 'onClick',
8 | description: '点击时',
9 | },
10 | {
11 | name: 'onDoubleClick',
12 | description: '双击时',
13 | },
14 | {
15 | name: 'onMouseDown',
16 | description: '鼠标按下',
17 | },
18 | {
19 | name: 'onMouseEnter',
20 | description: '鼠标进入',
21 | },
22 | {
23 | name: 'onMouseMove',
24 | description: '鼠标移动',
25 | },
26 | {
27 | name: 'onMouseOut',
28 | description: '鼠标移出',
29 | },
30 | {
31 | name: 'onMouseOver',
32 | description: '鼠标悬停',
33 | },
34 | {
35 | name: 'onMouseUp',
36 | description: '鼠标松开',
37 | },
38 | // Focus Events
39 | {
40 | name: 'onFocus',
41 | description: '获得焦点',
42 | snippet: '',
43 | },
44 | {
45 | name: 'onBlur',
46 | description: '失去焦点',
47 | snippet: '',
48 | },
49 | // Form Events
50 | {
51 | name: 'onChange',
52 | description: '值改变时',
53 | snippet: '',
54 | },
55 | {
56 | name: 'onSelect',
57 | description: '选择',
58 | },
59 | {
60 | name: 'onInput',
61 | description: '输入',
62 | snippet: '',
63 | },
64 | {
65 | name: 'onReset',
66 | description: '重置',
67 | snippet: '',
68 | },
69 | {
70 | name: 'onSubmit',
71 | description: '提交',
72 | snippet: '',
73 | },
74 | // Clipboard Events
75 | {
76 | name: 'onCopy',
77 | description: '复制',
78 | snippet: '',
79 | },
80 | {
81 | name: 'onCut',
82 | description: '剪切',
83 | snippet: '',
84 | },
85 | {
86 | name: 'onPaste',
87 | description: '粘贴',
88 | snippet: '',
89 | },
90 |
91 | // Keyboard Events
92 | {
93 | name: 'onKeyDown',
94 | description: '键盘按下',
95 | snippet: '',
96 | },
97 | {
98 | name: 'onKeyPress',
99 | description: '键盘按下并释放',
100 | snippet: '',
101 | },
102 | {
103 | name: 'onKeyUp',
104 | description: '键盘松开',
105 | snippet: '',
106 | },
107 | // Touch Events
108 | {
109 | name: 'onTouchCancel',
110 | description: '触摸退出',
111 | snippet: '',
112 | },
113 | {
114 | name: 'onTouchEnd',
115 | description: '触摸结束',
116 | snippet: '',
117 | },
118 | {
119 | name: 'onTouchMove',
120 | description: '触摸移动',
121 | snippet: '',
122 | },
123 | {
124 | name: 'onTouchStart',
125 | description: '触摸开始',
126 | snippet: '',
127 | },
128 | // UI Events
129 | {
130 | name: 'onScroll',
131 | description: '滚动',
132 | snippet: '',
133 | },
134 | {
135 | name: 'onLoad',
136 | description: '加载完毕',
137 | snippet: '',
138 | },
139 | {
140 | name: 'onWheel',
141 | description: '滚轮事件',
142 | snippet: '',
143 | },
144 | // Animation Events
145 | {
146 | name: 'onAnimationStart',
147 | description: '动画开始',
148 | },
149 | {
150 | name: 'onAnimationEnd',
151 | description: '动画结束',
152 | },
153 | ];
154 |
155 | // eslint-disable-next-line func-call-spacing
156 | const builtinComponents = new Map ReactElement>();
157 | function getBlockElement(tag: string): (props: any) => ReactElement {
158 | if (builtinComponents.has(tag)) {
159 | return builtinComponents.get(tag)!;
160 | }
161 | const mock = ({ className, children, ...rest }: any = {}) => {
162 | const props = {
163 | ...rest,
164 | className: classNames('lc-block-container', className),
165 | };
166 | return createElement(tag, props, children);
167 | };
168 |
169 | mock.metadata = {
170 | componentName: tag,
171 | // selfControlled: true,
172 | configure: {
173 | props: [],
174 | events: {
175 | supportedEvents,
176 | },
177 | styles: {
178 | supportClassName: true,
179 | supportInlineStyle: true,
180 | },
181 | component: {
182 | ...metasMap[tag],
183 | },
184 | },
185 | };
186 |
187 | builtinComponents.set(tag, mock);
188 | return mock;
189 | }
190 |
191 | const HTMLBlock = [
192 | 'div',
193 | 'p',
194 | 'article',
195 | 'h1',
196 | 'h2',
197 | 'h3',
198 | 'h4',
199 | 'h5',
200 | 'h6',
201 | 'aside',
202 | 'blockquote',
203 | 'footer',
204 | 'form',
205 | 'header',
206 | 'table',
207 | 'tbody',
208 | 'section',
209 | 'ul',
210 | 'li',
211 | ];
212 |
213 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
214 | const HTMLInlineBlock = ['a', 'b', 'span', 'em'];
215 | export function getIntrinsicMock(tag: string): ReactType {
216 | if (HTMLBlock.indexOf(tag) > -1) {
217 | return getBlockElement(tag);
218 | }
219 |
220 | return tag as any;
221 | }
222 |
223 | const metasMap: any = {
224 | div: {
225 | isContainer: true,
226 | nesting: {
227 | ancestorBlacklist: 'p',
228 | },
229 | },
230 | ul: {
231 | isContainer: true,
232 | nesting: {
233 | childWhitelist: 'li',
234 | },
235 | },
236 | p: {
237 | isContainer: true,
238 | nesting: {
239 | ancestorBlacklist: 'button,p',
240 | },
241 | },
242 | li: {
243 | isContainer: true,
244 | nesting: {
245 | parentWhitelist: 'ui,ol',
246 | },
247 | },
248 | span: {
249 | isContainer: true,
250 | selfControlled: true,
251 | },
252 | a: {
253 | isContainer: true,
254 | nesting: {
255 | ancestorBlacklist: 'a',
256 | },
257 | },
258 | b: {
259 | isContainer: true,
260 | },
261 | strong: {
262 | isContainer: true,
263 | },
264 | em: {
265 | isContainer: true,
266 | },
267 | i: {
268 | isContainer: true,
269 | },
270 | form: {
271 | isContainer: true,
272 | nestingRule: {
273 | ancestorBlacklist: 'form,button',
274 | },
275 | },
276 | table: {
277 | isContainer: true,
278 | nestingRule: {
279 | ancestorBlacklist: 'button',
280 | },
281 | },
282 | caption: {
283 | isContainer: true,
284 | selfControlled: true,
285 | nestingRule: {
286 | ancestorBlacklist: 'button',
287 | },
288 | },
289 | select: {
290 | isContainer: true,
291 | selfControlled: true,
292 | nestingRule: {
293 | ancestorBlacklist: 'button',
294 | },
295 | },
296 | button: {
297 | isContainer: true,
298 | nestingRule: {
299 | ancestorBlacklist: 'button',
300 | },
301 | },
302 | input: {
303 | isContainer: false,
304 | nestingRule: {
305 | ancestorBlacklist: 'button,h1,h2,h3,h4,h5,h6',
306 | },
307 | },
308 | textarea: {
309 | isContainer: false,
310 | nestingRule: {
311 | ancestorBlacklist: 'button',
312 | },
313 | },
314 | image: {
315 | isContainer: false,
316 | },
317 | canvas: {
318 | isContainer: false,
319 | },
320 | br: {
321 | isContainer: false,
322 | },
323 | h1: {
324 | isContainer: true,
325 | nestingRule: {
326 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
327 | },
328 | },
329 | h2: {
330 | isContainer: true,
331 | nestingRule: {
332 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
333 | },
334 | },
335 | h3: {
336 | isContainer: true,
337 | nestingRule: {
338 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
339 | },
340 | },
341 | h4: {
342 | isContainer: true,
343 | nestingRule: {
344 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
345 | },
346 | },
347 | h5: {
348 | isContainer: true,
349 | nestingRule: {
350 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
351 | },
352 | },
353 | h6: {
354 | isContainer: true,
355 | nestingRule: {
356 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
357 | },
358 | },
359 | article: {
360 | isContainer: true,
361 | nestingRule: {
362 | ancestorBlacklist: 'button',
363 | },
364 | },
365 | aside: {
366 | isContainer: true,
367 | nestingRule: {
368 | ancestorBlacklist: 'button',
369 | },
370 | },
371 | footer: {
372 | isContainer: true,
373 | nestingRule: {
374 | ancestorBlacklist: 'button',
375 | },
376 | },
377 | header: {
378 | isContainer: true,
379 | nestingRule: {
380 | ancestorBlacklist: 'button',
381 | },
382 | },
383 | blockquote: {
384 | isContainer: true,
385 | nestingRule: {
386 | ancestorBlacklist: 'button',
387 | },
388 | },
389 | address: {
390 | isContainer: true,
391 | nestingRule: {
392 | ancestorBlacklist: 'button',
393 | },
394 | },
395 | section: {
396 | isContainer: true,
397 | nestingRule: {
398 | ancestorBlacklist: 'p,h1,h2,h3,h4,h5,h6,button',
399 | },
400 | },
401 | summary: {
402 | isContainer: true,
403 | nestingRule: {
404 | ancestorBlacklist: 'button',
405 | },
406 | },
407 | nav: {
408 | isContainer: true,
409 | nestingRule: {
410 | ancestorBlacklist: 'button',
411 | },
412 | },
413 | };
414 |
--------------------------------------------------------------------------------