From 6a26531007e79ed83ec074ec515f38db2a676756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 22 Feb 2022 09:40:57 +0800 Subject: [PATCH] feat: first commit - genesis --- .gitignore | 95 +++++++++ .prettierrc.js | 7 + README.md | 9 + build.json | 38 ++++ build.plugin.js | 58 ++++++ package.json | 45 +++++ public/assets.json | 139 ++++++++++++++ public/favicon.png | Bin 0 -> 3612 bytes public/index.html | 41 ++++ public/mock-pages.json | 1 + public/mock/info.json | 3 + public/preview.html | 25 +++ public/schema.json | 291 ++++++++++++++++++++++++++++ scripts/watchdog.js | 15 ++ src/index.ts | 35 ++++ src/preview.tsx | 63 ++++++ src/sample-plugins/logo/index.scss | 11 ++ src/sample-plugins/logo/index.tsx | 18 ++ src/setters/behavior-setter.tsx | 27 +++ src/setters/custom-setter.tsx | 12 ++ src/universal/global.scss | 55 ++++++ src/universal/plugin.tsx | 272 ++++++++++++++++++++++++++ src/universal/utils.ts | 298 +++++++++++++++++++++++++++++ tsconfig.json | 44 +++++ 24 files changed, 1602 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc.js create mode 100644 README.md create mode 100644 build.json create mode 100644 build.plugin.js create mode 100644 package.json create mode 100644 public/assets.json create mode 100644 public/favicon.png create mode 100644 public/index.html create mode 100644 public/mock-pages.json create mode 100644 public/mock/info.json create mode 100644 public/preview.html create mode 100644 public/schema.json create mode 100755 scripts/watchdog.js create mode 100644 src/index.ts create mode 100644 src/preview.tsx create mode 100644 src/sample-plugins/logo/index.scss create mode 100644 src/sample-plugins/logo/index.tsx create mode 100644 src/setters/behavior-setter.tsx create mode 100644 src/setters/custom-setter.tsx create mode 100644 src/universal/global.scss create mode 100644 src/universal/plugin.tsx create mode 100644 src/universal/utils.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa58d70 --- /dev/null +++ b/.gitignore @@ -0,0 +1,95 @@ +# project custom +build +dist + + +# IDE +.vscode +.idea + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release +lib + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# mac config files +.DS_Store diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..24c5859 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + printWidth: 100, + tabWidth: 2, + semi: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4ab67e --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +## Low-Code Engine Demo + +本 demo 是一个组合内核、setter、插件、物料的示范工程,因为未经长期生产环境打磨,可能还会有一些各个模块间结合的 bug,希望大家理解~ + +更多参考资料: + +- [马上玩一下](https://alifd.alicdn.com/npm/@alilc/lowcode-demo@1.0.0/build/index.html) +- [低代码引擎官网](http://lowcode-engine.cn) +- [引擎主包](https://github.com/alibaba/lowcode-engine) \ No newline at end of file diff --git a/build.json b/build.json new file mode 100644 index 0000000..97f03d4 --- /dev/null +++ b/build.json @@ -0,0 +1,38 @@ +{ + "entry": { + "index": "src/index" + }, + "vendor": false, + "devServer": { + "hot": false + }, + "publicPath": "/", + "externals": { + "react": "var window.React", + "react-dom": "var window.ReactDOM", + "prop-types": "var window.PropTypes", + "@alifd/next": "var window.Next", + "@alilc/lowcode-engine": "var window.AliLowCodeEngine", + "@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin", + "@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin", + "@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin", + "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", + "@ali/lowcode-engine": "var window.AliLowCodeEngine", + "moment": "var window.moment", + "lodash": "var window._" + }, + "plugins": [ + [ + "build-plugin-react-app" + ], + [ + "build-plugin-moment-locales", + { + "locales": [ + "zh-cn" + ] + } + ], + "./build.plugin.js" + ] +} diff --git a/build.plugin.js b/build.plugin.js new file mode 100644 index 0000000..12882de --- /dev/null +++ b/build.plugin.js @@ -0,0 +1,58 @@ +const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); + +const HtmlWebpackPlugin = require('html-webpack-plugin'); + +module.exports = ({ onGetWebpackConfig }) => { + onGetWebpackConfig((config) => { + config.resolve.plugin('tsconfigpaths').use(TsconfigPathsPlugin, [ + { + configFile: './tsconfig.json', + }, + ]); + + config.merge({ + node: { + fs: 'empty', + }, + }); + config.merge({ + entry: { + index: require.resolve('./src/index.ts'), + preview: require.resolve('./src/preview.tsx'), + }, + }); + config + .plugin('index') + .use(HtmlWebpackPlugin, [ + { + inject: false, + templateParameters: { + }, + template: require.resolve('./public/index.html'), + filename: 'index.html', + }, + ]); + config + .plugin('preview') + .use(HtmlWebpackPlugin, [ + { + inject: false, + templateParameters: { + }, + template: require.resolve('./public/preview.html'), + filename: 'preview.html', + }, + ]); + + config.plugins.delete('hot'); + config.devServer.hot(false); + + config.module // fixes https://github.com/graphql/graphql-js/issues/1272 + .rule('mjs$') + .test(/\.mjs$/) + .include + .add(/node_modules/) + .end() + .type('javascript/auto'); + }); +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..33ac6c4 --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "@alilc/lowcode-demo", + "version": "1.0.0-beta.1", + "description": "Low-Code Engine 低代码搭建引擎 Demo 项目", + "repository": "git@github.com:alibaba/lowcode-demo.git", + "license": "MIT", + "main": "index.js", + "scripts": { + "start": "build-scripts start --disable-reload", + "build": "build-scripts build", + "pub": "node ./scripts/watchdog.js && npm pub" + }, + "files": [ + "build" + ], + "config": {}, + "dependencies": { + "@alilc/lowcode-plugin-code-editor": "^1.0.1", + "@alilc/lowcode-plugin-code-generator": "^1.0.0", + "@alilc/lowcode-plugin-components-pane": "^1.0.2", + "@alilc/lowcode-plugin-datasource-pane": "^1.0.0", + "@alilc/lowcode-plugin-inject": "^1.0.0", + "@alilc/lowcode-plugin-manual": "^1.0.0", + "@alilc/lowcode-plugin-schema": "^1.0.0", + "@alilc/lowcode-plugin-simulator-select": "^1.0.0", + "@alilc/lowcode-plugin-undo-redo": "^1.0.0", + "@alilc/lowcode-plugin-zh-en": "^1.0.0", + "@alilc/lowcode-react-renderer": "^1.0.0", + "@alilc/lowcode-setter-behavior": "^1.0.0", + "@alilc/lowcode-setter-title": "^1.0.2" + }, + "devDependencies": { + "@alilc/lowcode-engine": "^1.0.0", + "@alilc/lowcode-types": "^1.0.0", + "@alib/build-scripts": "^0.1.18", + "@types/events": "^3.0.0", + "@types/react": "^16.8.3", + "@types/react-dom": "^16.8.2", + "@types/streamsaver": "^2.0.0", + "build-plugin-fusion": "^0.1.0", + "build-plugin-moment-locales": "^0.1.0", + "build-plugin-react-app": "^1.1.2", + "tsconfig-paths-webpack-plugin": "^3.2.0" + } +} diff --git a/public/assets.json b/public/assets.json new file mode 100644 index 0000000..1584ef9 --- /dev/null +++ b/public/assets.json @@ -0,0 +1,139 @@ +{ + "packages": [ + { + "package": "moment", + "version": "2.24.0", + "urls": [ + "https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js" + ], + "library": "moment" + }, + { + "package": "lodash", + "library": "_", + "urls": [ + "https://g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js" + ] + }, + { + "title": "fusion组件库", + "package": "@alifd/next", + "version": "1.24.18", + "urls": [ + "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next.min.css", + "https://g.alicdn.com/code/lib/alifd__next/1.24.18/next-with-locales.min.js" + ], + "library": "Next" + }, + { + "title": "NextTable", + "package": "NextTable", + "version": "1.0.1", + "urls": [ + "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.js", + "https://g.alicdn.com/fusion-platform/pro-table/1.0.1/next-table.css" + ], + "library": "NextTable" + }, + { + "package": "@alilc/lowcode-materials", + "version": "1.0.1", + "library": "AlilcLowcodeMaterials", + "urls": [ + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/dist/AlilcLowcodeMaterials.js", + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/dist/AlilcLowcodeMaterials.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/build/lowcode/view.css" + ] + }, + { + "package": "@alifd/pro-layout", + "version": "1.0.1-beta.5", + "library": "AlifdProLayout", + "urls": [ + "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/dist/AlifdProLayout.js", + "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/dist/AlifdProLayout.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/view.css" + ] + }, + { + "package": "@alifd/fusion-ui", + "version": "1.0.5-beta.1", + "library": "AlifdFusionUi", + "urls": [ + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/dist/AlifdFusionUi.js", + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/dist/AlifdFusionUi.css" + ], + "editUrls": [ + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/build/lowcode/view.js", + "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/build/lowcode/view.css" + ] + } + ], + "components": [ + { + "exportName": "AlilcLowcodeMaterialsMeta", + "npm": { + "package": "@alilc/lowcode-materials" + }, + "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.1/build/lowcode/meta.design.js" + } + }, + { + "exportName": "AlifdProLayoutMeta", + "npm": { + "package": "@alifd/pro-layout", + "version": "1.0.1-beta.5" + }, + "url": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.design.js" + } + }, + { + "exportName": "AlifdFusionUiMeta", + "npm": { + "package": "@alifd/fusion-ui" + }, + "url": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/build/lowcode/meta.js", + "urls": { + "default": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/build/lowcode/meta.js", + "design": "https://alifd.alicdn.com/npm/@alifd/fusion-ui@1.0.5-beta.1/build/lowcode/meta.design.js" + } + } + ], + "sort": { + "groupList": [ + "精选组件", + "原子组件" + ], + "categoryList": [ + "基础元素", + "布局容器类", + "表格类", + "表单详情类", + "帮助类", + "对话框类", + "业务类", + "通用", + "引导", + "信息输入", + "信息展示", + "信息反馈" + ] + }, + "groupList": [ + "精选组件", + "原子组件" + ], + "ignoreComponents": {} +} diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..307ffbd82dba398d6db6459102bff331eef7df6b GIT binary patch literal 3612 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 + + + + + + 阿里低代码引擎 Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/public/mock-pages.json b/public/mock-pages.json new file mode 100644 index 0000000..8e20f2f --- /dev/null +++ b/public/mock-pages.json @@ -0,0 +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}]} \ No newline at end of file diff --git a/public/mock/info.json b/public/mock/info.json new file mode 100644 index 0000000..006209b --- /dev/null +++ b/public/mock/info.json @@ -0,0 +1,3 @@ +{ + "info": "Hello AliLowCode!!" +} \ No newline at end of file diff --git a/public/preview.html b/public/preview.html new file mode 100644 index 0000000..798b156 --- /dev/null +++ b/public/preview.html @@ -0,0 +1,25 @@ + + + + + + 预览低代码 + + + + +
+ + + + + + + + + + diff --git a/public/schema.json b/public/schema.json new file mode 100644 index 0000000..4d95a15 --- /dev/null +++ b/public/schema.json @@ -0,0 +1,291 @@ +{ + "componentName": "Page", + "id": "node_dockcviv8fo1", + "props": { + "ref": "outerView", + "style": { + "height": "100%" + } + }, + "fileName": "/", + "dataSource": { + "list": [ + { + "type": "fetch", + "isInit": true, + "options": { + "params": {}, + "method": "GET", + "isCors": true, + "timeout": 5000, + "headers": {}, + "uri": "mock/info.json" + }, + "id": "info" + } + ] + }, + "state": { + "text": { + "type": "JSExpression", + "value": "\"outer\"" + }, + "isShowDialog": { + "type": "JSExpression", + "value": "false" + } + }, + "css": "body {\n font-size: 12px;\n}\n\n.button {\n width: 100px;\n color: #ff00ff\n}", + "lifeCycles": { + "componentDidMount": { + "type": "JSFunction", + "value": "function componentDidMount() {\n console.log('did mount');\n}" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function componentWillUnmount() {\n console.log('will unmount');\n}" + } + }, + "methods": { + "testFunc": { + "type": "JSFunction", + "value": "function testFunc() {\n console.log('test func');\n}" + }, + "onClick": { + "type": "JSFunction", + "value": "function onClick() {\n this.setState({\n isShowDialog: true\n });\n}" + }, + "closeDialog": { + "type": "JSFunction", + "value": "function closeDialog() {\n this.setState({\n isShowDialog: false\n });\n}" + } + }, + "originCode": "class LowcodeComponent extends Component {\n state = {\n \"text\": \"outer\",\n \"isShowDialog\": false\n }\n componentDidMount() {\n console.log('did mount');\n }\n componentWillUnmount() {\n console.log('will unmount');\n }\n testFunc() {\n console.log('test func');\n }\n onClick() {\n this.setState({\n isShowDialog: true\n })\n }\n closeDialog() {\n this.setState({\n isShowDialog: false\n })\n }\n}", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextPage", + "id": "node_ockzs2vw431", + "props": { + "headerDivider": true, + "minHeight": "100vh", + "presetNav": true, + "presetAside": true, + "footer": false, + "nav": false, + "aside": false, + "placeholderStyle": { + "gridRowEnd": "span 1", + "gridColumnEnd": "span 12" + }, + "headerProps": { + "background": "surface" + }, + "header": { + "type": "JSSlot", + "value": [ + { + "componentName": "NextPageHeader", + "id": "node_ockzs2vw433", + "props": {}, + "title": "页面头部", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRowColContainer", + "id": "node_ockzs2vw434", + "props": { + "rowGap": 20, + "colGap": 20 + }, + "title": "行列容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRow", + "id": "node_ockzs2vw435", + "props": {}, + "title": "行", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextCol", + "id": "node_ockzs2vw436", + "props": { + "colSpan": 1 + }, + "title": "列", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextP", + "id": "node_ockzvfoetv17", + "props": { + "wrap": false, + "type": "body2", + "verAlign": "middle", + "textSpacing": true, + "align": "left" + }, + "docId": "dockzvfoetv", + "title": "段落", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextText", + "id": "node_ockzvfoetv18", + "props": { + "type": "h5", + "children": { + "type": "JSExpression", + "value": "this.state.info.info", + "mock": "标题标题" + }, + "mark": false, + "code": false, + "delete": false, + "underline": false, + "strong": false + }, + "docId": "dockzvfoetv", + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ], + "title": "header" + }, + "isTab": false, + "contentAlignCenter": false, + "contentProps": { + "style": { + "background": "rgba(255,255,255,0)" + } + } + }, + "title": "页面", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextBlock", + "id": "node_ockzs2vw437", + "props": { + "placeholderStyle": { + "height": "100%" + }, + "noPadding": false, + "noBorder": false, + "title": "区域标题", + "rowGap": 20, + "colGap": 20, + "background": "surface", + "layoutmode": "O", + "strict": true, + "colSpan": 12, + "rowSpan": 1, + "mode": "transparent", + "childTotalColumns": 12 + }, + "title": "区域", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextBlockCell", + "id": "node_ockzs2vw438", + "props": { + "colSpan": 12, + "rowSpan": 1, + "mode": "procard", + "isAutoContainer": true, + "title": "区块标题" + }, + "hidden": false, + "title": "", + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRowColContainer", + "id": "node_ockzs2vw439", + "props": { + "rowGap": 20, + "colGap": 20 + }, + "title": "行列容器", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextRow", + "id": "node_ockzs2vw43a", + "props": {}, + "title": "行", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "", + "children": [ + { + "componentName": "NextCol", + "id": "node_ockzs2vw43b", + "props": { + "colSpan": 1 + }, + "title": "列", + "hidden": false, + "isLocked": false, + "condition": true, + "conditionGroup": "" + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/scripts/watchdog.js b/scripts/watchdog.js new file mode 100755 index 0000000..57964a5 --- /dev/null +++ b/scripts/watchdog.js @@ -0,0 +1,15 @@ +#!/usr/bin/env node +const fs = require('fs'); +const { join } = require('path'); + +const workingDir = process.cwd(); + +const pkg = JSON.parse(fs.readFileSync(join(workingDir, 'package.json'), 'utf-8')); +if (pkg.private) return; +const { files } = pkg; +files.forEach(file => { + const fileDir = join(workingDir, file); + if (!fs.existsSync(fileDir)) { + throw new Error(`${fileDir} does not exist, plz run build`); + } +}); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..1ee60d1 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,35 @@ +import { init } from '@alilc/lowcode-engine'; +import registerPlugins from './universal/plugin'; +import './universal/global.scss'; + +const preference = new Map(); +preference.set('DataSourcePane', { + importPlugins: [], + dataSourceTypes: [ + { + type: 'fetch', + }, + { + type: 'jsonp', + } + ] +}); + +(async function main() { + await registerPlugins(); + + init(document.getElementById('lce-container')!, { + // designMode: 'live', + // locale: 'zh-CN', + enableCondition: true, + enableCanvasLock: true, + // 默认绑定变量 + supportVariableGlobally: true, + // simulatorUrl 在当 engine-core.js 同一个路径下时是不需要配置的!!! + // 这里因为用的是 unpkg,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 + simulatorUrl: [ + 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@beta/dist/css/react-simulator-renderer.css', + 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@beta/dist/js/react-simulator-renderer.js' + ] + }, preference); +})(); diff --git a/src/preview.tsx b/src/preview.tsx new file mode 100644 index 0000000..27627ff --- /dev/null +++ b/src/preview.tsx @@ -0,0 +1,63 @@ +import ReactDOM from 'react-dom'; +import React, { useState } from 'react'; +import { Loading } from '@alifd/next'; +import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import { injectComponents } from '@alilc/lowcode-plugin-inject'; + +const SamplePreview = () => { + const [data, setData] = useState({}); + + async function init() { + const packages = JSON.parse(window.localStorage.getItem('packages') || ''); + const projectSchema = JSON.parse(window.localStorage.getItem('projectSchema') || ''); + const { componentsMap: componentsMapArray, componentsTree } = projectSchema; + const componentsMap: any = {}; + componentsMapArray.forEach((component: any) => { + componentsMap[component.componentName] = component; + }); + const schema = componentsTree[0]; + + const libraryMap = {}; + const libraryAsset = []; + packages.forEach(({ package: _package, library, urls, renderUrls }) => { + libraryMap[_package] = library; + if (renderUrls) { + libraryAsset.push(renderUrls); + } else if (urls) { + libraryAsset.push(urls); + } + }); + + const vendors = [assetBundle(libraryAsset, AssetLevel.Library)]; + + // TODO asset may cause pollution + const assetLoader = new AssetLoader(); + await assetLoader.load(libraryAsset); + const components = await injectComponents(buildComponents(libraryMap, componentsMap)); + + setData({ + schema, + components, + }); + } + + const { schema, components } = data; + + if (!schema || !components) { + init(); + return ; + } + + return ( +
+ +
+ ); +}; + +ReactDOM.render(, document.getElementById('ice-container')); diff --git a/src/sample-plugins/logo/index.scss b/src/sample-plugins/logo/index.scss new file mode 100644 index 0000000..3140ac3 --- /dev/null +++ b/src/sample-plugins/logo/index.scss @@ -0,0 +1,11 @@ +.lowcode-plugin-logo { + .logo { + display: block; + width: 139px; + height: 26px; + cursor: pointer; + background-size: contain; + background-position: center; + background-repeat: no-repeat; + } +} diff --git a/src/sample-plugins/logo/index.tsx b/src/sample-plugins/logo/index.tsx new file mode 100644 index 0000000..ff4bbe2 --- /dev/null +++ b/src/sample-plugins/logo/index.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import './index.scss'; +import { PluginProps } from '@alilc/lowcode-types'; + +export interface IProps { + logo?: string; + href?: string; +} + +const Logo: React.FC = (props): React.ReactElement => { + return ( +
+ +
+ ); +}; + +export default Logo; diff --git a/src/setters/behavior-setter.tsx b/src/setters/behavior-setter.tsx new file mode 100644 index 0000000..34e9be5 --- /dev/null +++ b/src/setters/behavior-setter.tsx @@ -0,0 +1,27 @@ +import * as React from 'react'; +import BehaviorSetter from '@alilc/lowcode-setter-behavior'; + + +const defaultExtraBehaviorActions: any[] = []; +class LocalBehaviorSetter extends React.Component { + render() { + // ignore url && responseFormatter props, use default ones + const { url: propsUrl, responseFormatter: propsFormatter, extraBehaviorActions: propsExtraBehaviorActions = [], ...otherProps } = this.props; + const url = 'https://hn.algolia.com/api/v1/search?query'; + const responseFormatter = (response) => response.hits.map((item) => ({ + label: item.title, + value: item.author + })); + const extraBehaviorActions = propsExtraBehaviorActions.concat(defaultExtraBehaviorActions); + return ( + + ); + } +} + +export default LocalBehaviorSetter; \ No newline at end of file diff --git a/src/setters/custom-setter.tsx b/src/setters/custom-setter.tsx new file mode 100644 index 0000000..0383473 --- /dev/null +++ b/src/setters/custom-setter.tsx @@ -0,0 +1,12 @@ +import React, { Component } from 'react'; // import classNames from 'classnames'; + +class CustomSetter extends Component { + render() { + const { defaultValue, value, onChange } = this.props; + const { editor } = this.props.field; + + return
hello world
; + } +} + +export default CustomSetter; diff --git a/src/universal/global.scss b/src/universal/global.scss new file mode 100644 index 0000000..02906a3 --- /dev/null +++ b/src/universal/global.scss @@ -0,0 +1,55 @@ +body { + font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma, Arial, PingFang SC-Light, Microsoft YaHei; + font-size: 12px; + * { + box-sizing: border-box; + } +} + +body, #lce-container { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + box-sizing: border-box; + padding: 0; + margin: 0; + overflow: hidden; + text-rendering: optimizeLegibility; + -webkit-user-select: none; + -webkit-user-drag: none; + -webkit-text-size-adjust: none; + -webkit-touch-callout: none; + -webkit-font-smoothing: antialiased; + #engine { + width: 100%; + height: 100%; + } +} + +html { + min-width: 1024px; +} + +.save-sample { + width: 80px; + height: 30px; + background-color: #5584FF; + border: none; + outline: none; + border-radius: 4px; + color: white; + cursor: pointer; +} + +.load-assets { + width: 100px; + height: 30px; + background-color: #5584FF; + border: none; + outline: none; + border-radius: 4px; + color: white; + cursor: pointer; +} diff --git a/src/universal/plugin.tsx b/src/universal/plugin.tsx new file mode 100644 index 0000000..12e7d9f --- /dev/null +++ b/src/universal/plugin.tsx @@ -0,0 +1,272 @@ +import React from 'react'; +import { + ILowCodePluginContext, + plugins, + skeleton, + project, + setters, +} from '@alilc/lowcode-engine'; +import { Button } from '@alifd/next'; +import UndoRedoPlugin from '@alilc/lowcode-plugin-undo-redo'; +import ComponentsPane from '@alilc/lowcode-plugin-components-pane'; +import ZhEnPlugin from '@alilc/lowcode-plugin-zh-en'; +import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; +import DataSourcePanePlugin from '@alilc/lowcode-plugin-datasource-pane'; +import SchemaPlugin from '@alilc/lowcode-plugin-schema'; +import CodeEditor from "@alilc/lowcode-plugin-code-editor"; +import ManualPlugin from "@alilc/lowcode-plugin-manual"; +import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; +import SimulatorResizer from '@alilc/lowcode-plugin-simulator-select'; + +// 注册到引擎 +import TitleSetter from '@alilc/lowcode-setter-title'; +import BehaviorSetter from '../setters/behavior-setter'; +import CustomSetter from '../setters/custom-setter'; +import Logo from '../sample-plugins/logo'; + +import { + loadIncrementalAssets, + getPageSchema, + saveSchema, + resetSchema, + preview, +} from './utils'; +import assets from '../../public/assets.json' + +export default async function registerPlugins() { + await plugins.register(ManualPlugin); + + await plugins.register(Inject); + + // plugin API 见 https://yuque.antfin.com/ali-lowcode/docs/cdukce + SchemaPlugin.pluginName = 'SchemaPlugin'; + await plugins.register(SchemaPlugin); + + SimulatorResizer.pluginName = 'SimulatorResizer'; + plugins.register(SimulatorResizer); + + const editorInit = (ctx: ILowCodePluginContext) => { + return { + name: 'editor-init', + async init() { + // 修改面包屑组件的分隔符属性setter + // const assets = await ( + // await fetch( + // `https://alifd.alicdn.com/npm/@alilc/lowcode-materials/build/lowcode/assets-prod.json` + // ) + // ).json(); + // 设置物料描述 + const { material, project } = ctx; + + material.setAssets(await injectAssets(assets)); + + const schema = await getPageSchema(); + + // 加载 schema + project.openDocument(schema); + }, + }; + } + editorInit.pluginName = 'editorInit'; + await plugins.register(editorInit); + + const builtinPluginRegistry = (ctx: ILowCodePluginContext) => { + return { + name: 'builtin-plugin-registry', + async init() { + const { skeleton } = ctx; + // 注册 logo 面板 + skeleton.add({ + area: 'topArea', + type: 'Widget', + name: 'logo', + content: Logo, + contentProps: { + logo: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', + href: '/', + }, + props: { + align: 'left', + }, + }); + + // 注册组件面板 + const componentsPane = skeleton.add({ + area: 'leftArea', + type: 'PanelDock', + name: 'componentsPane', + content: ComponentsPane, + contentProps: {}, + props: { + align: 'top', + icon: 'zujianku', + description: '组件库', + }, + }); + componentsPane?.disable?.(); + project.onSimulatorRendererReady(() => { + componentsPane?.enable?.(); + }) + }, + }; + } + builtinPluginRegistry.pluginName = 'builtinPluginRegistry'; + await plugins.register(builtinPluginRegistry); + + // 设置内置 setter 和事件绑定、插件绑定面板 + const setterRegistry = (ctx: ILowCodePluginContext) => { + const { setterMap, pluginMap } = window.AliLowCodeEngineExt; + return { + name: 'ext-setters-registry', + async init() { + const { setters, skeleton } = ctx; + // 注册setterMap + setters.registerSetter(setterMap); + // 注册插件 + // 注册事件绑定面板 + skeleton.add({ + area: 'centerArea', + type: 'Widget', + content: pluginMap.EventBindDialog, + name: 'eventBindDialog', + props: {}, + }); + + // 注册变量绑定面板 + skeleton.add({ + area: 'centerArea', + type: 'Widget', + content: pluginMap.VariableBindDialog, + name: 'variableBindDialog', + props: {}, + }); + }, + }; + } + setterRegistry.pluginName = 'setterRegistry'; + await plugins.register(setterRegistry); + + // 注册回退/前进 + await plugins.register(UndoRedoPlugin); + + // 注册中英文切换 + await plugins.register(ZhEnPlugin); + + const loadAssetsSample = (ctx: ILowCodePluginContext) => { + return { + name: 'loadAssetsSample', + async init() { + const { skeleton } = ctx; + + skeleton.add({ + name: 'loadAssetsSample', + area: 'topArea', + type: 'Widget', + props: { + align: 'right', + width: 80, + }, + content: ( + + ), + }); + }, + }; + }; + loadAssetsSample.pluginName = 'loadAssetsSample'; + await plugins.register(loadAssetsSample); + + // 注册保存面板 + const saveSample = (ctx: ILowCodePluginContext) => { + return { + name: 'saveSample', + async init() { + const { skeleton, hotkey } = ctx; + + skeleton.add({ + name: 'saveSample', + area: 'topArea', + type: 'Widget', + props: { + align: 'right', + }, + content: ( + + ), + }); + skeleton.add({ + name: 'resetSchema', + area: 'topArea', + type: 'Widget', + props: { + align: 'right', + }, + content: ( + + ), + }); + hotkey.bind('command+s', (e) => { + e.preventDefault(); + saveSchema(); + }); + }, + }; + } + saveSample.pluginName = 'saveSample'; + await plugins.register(saveSample); + + DataSourcePanePlugin.pluginName = 'DataSourcePane'; + await plugins.register(DataSourcePanePlugin); + + CodeEditor.pluginName = 'CodeEditor'; + await plugins.register(CodeEditor); + + // 注册出码插件 + CodeGenPlugin.pluginName = 'CodeGenPlugin'; + await plugins.register(CodeGenPlugin); + + const previewSample = (ctx: ILowCodePluginContext) => { + return { + name: 'previewSample', + async init() { + const { skeleton } = ctx; + skeleton.add({ + name: 'previewSample', + area: 'topArea', + type: 'Widget', + props: { + align: 'right', + }, + content: ( + + ), + }); + }, + }; + }; + previewSample.pluginName = 'previewSample'; + await plugins.register(previewSample); + + const customSetter = (ctx: ILowCodePluginContext) => { + return { + name: '___registerCustomSetter___', + async init() { + const { setters } = ctx; + + setters.registerSetter('TitleSetter', TitleSetter); + setters.registerSetter('BehaviorSetter', BehaviorSetter); + setters.registerSetter('CustomSetter', CustomSetter); + }, + }; + } + customSetter.pluginName = 'customSetter'; + await plugins.register(customSetter); +}; diff --git a/src/universal/utils.ts b/src/universal/utils.ts new file mode 100644 index 0000000..9baf0f8 --- /dev/null +++ b/src/universal/utils.ts @@ -0,0 +1,298 @@ +import { material, project } from '@alilc/lowcode-engine'; +import { filterPackages } from '@alilc/lowcode-plugin-inject' +import { Message, Dialog } from '@alifd/next'; + +export const loadIncrementalAssets = () => { + material?.onChangeAssets(() => { + Message.success('[MCBreadcrumb] 物料加载成功'); + }); + + material.loadIncrementalAssets({ + packages: [ + { + title: 'MCBreadcrumb', + package: 'mc-breadcrumb', + version: '1.0.0', + urls: [ + 'https://unpkg.alibaba-inc.com/mc-breadcrumb@1.0.0/dist/MCBreadcrumb.js', + 'https://unpkg.alibaba-inc.com/mc-breadcrumb@1.0.0/dist/MCBreadcrumb.css', + ], + library: 'MCBreadcrumb', + }, + ], + components: [ + { + componentName: 'MCBreadcrumb', + title: 'MCBreadcrumb', + docUrl: '', + screenshot: '', + npm: { + package: 'mc-breadcrumb', + version: '1.0.0', + exportName: 'MCBreadcrumb', + main: 'lib/index.js', + destructuring: false, + subName: '', + }, + props: [ + { + name: 'prefix', + propType: 'string', + description: '样式类名的品牌前缀', + defaultValue: 'next-', + }, + { + name: 'title', + propType: 'string', + description: '标题', + defaultValue: 'next-', + }, + { + name: 'rtl', + propType: 'bool', + }, + { + name: 'children', + propType: { + type: 'instanceOf', + value: 'node', + }, + description: '面包屑子节点,需传入 Breadcrumb.Item', + }, + { + name: 'maxNode', + propType: { + type: 'oneOfType', + value: [ + 'number', + { + type: 'oneOf', + value: ['auto'], + }, + ], + }, + description: + '面包屑最多显示个数,超出部分会被隐藏, 设置为 auto 会自动根据父元素的宽度适配。', + defaultValue: 100, + }, + { + name: 'separator', + propType: { + type: 'instanceOf', + value: 'node', + }, + description: '分隔符,可以是文本或 Icon', + }, + { + name: 'component', + propType: { + type: 'oneOfType', + value: ['string', 'func'], + }, + description: '设置标签类型', + defaultValue: 'nav', + }, + { + name: 'className', + propType: 'any', + }, + { + name: 'style', + propType: 'object', + }, + ], + configure: { + component: { + isContainer: true, + isModel: true, + rootSelector: 'div.MCBreadcrumb', + }, + }, + }, + ], + + componentList: [ + { + title: '常用', + icon: '', + children: [ + { + componentName: 'MCBreadcrumb', + title: 'MC面包屑', + icon: '', + package: 'mc-breadcrumb', + library: 'MCBreadcrumb', + snippets: [ + { + title: 'MC面包屑', + screenshot: + 'https://alifd.oss-cn-hangzhou.aliyuncs.com/fusion-cool/icons/icon-light/ic_light_breadcrumb.png', + schema: { + componentName: 'MCBreadcrumb', + props: { + title: '物料中心', + prefix: 'next-', + maxNode: 100, + }, + }, + }, + ], + }, + ], + }, + ], + }); +}; + +export const preview = () => { + saveSchema(); + setTimeout(() => { + window.open(`./preview.html${location.search}`); + }, 500); +}; + +export const saveSchema = async () => { + window.localStorage.setItem( + 'projectSchema', + JSON.stringify(project.exportSchema()) + ); + const packages = await filterPackages(material.getAssets().packages); + window.localStorage.setItem( + 'packages', + JSON.stringify(packages) + ); + Message.success('成功保存到本地'); +}; + +export const resetSchema = async () => { + try { + await new Promise((resolve, reject) => { + Dialog.confirm({ + content: '确定要重置吗?您所有的修改都将消失!', + onOk: () => { + resolve(); + }, + onCancel: () => { + reject() + }, + }) + }) + } catch(err) { + return + } + + let schema + try { + schema = await request('./schema.json') + } catch(err) { + schema = { + componentName: 'Page', + fileName: 'sample', + } + } + + window.localStorage.setItem( + 'projectSchema', + JSON.stringify({ + componentsTree: [schema], + componentsMap: material.componentsMap, + version: '1.0.0', + i18n: {}, + }) + ); + + project.getCurrentDocument()?.importSchema(schema); + project.simulatorHost?.rerender(); + Message.success('成功重置页面'); +} + +export const getPageSchema = async () => { + const schema = JSON.parse( + window.localStorage.getItem('projectSchema') || '{}' + ); + + const pageSchema = schema?.componentsTree?.[0]; + + if (pageSchema) { + return pageSchema; + } + return await request('./schema.json'); +}; + +function request( + dataAPI: string, + method = 'GET', + data?: object | string, + headers?: object, + otherProps?: any, +): Promise { + return new Promise((resolve, reject): void => { + if (otherProps && otherProps.timeout) { + setTimeout((): void => { + reject(new Error('timeout')); + }, otherProps.timeout); + } + fetch(dataAPI, { + method, + credentials: 'include', + headers, + body: data, + ...otherProps, + }) + .then((response: Response): any => { + switch (response.status) { + case 200: + case 201: + case 202: + return response.json(); + case 204: + if (method === 'DELETE') { + return { + success: true, + }; + } else { + return { + __success: false, + code: response.status, + }; + } + case 400: + case 401: + case 403: + case 404: + case 406: + case 410: + case 422: + case 500: + return response + .json() + .then((res: object): any => { + return { + __success: false, + code: response.status, + data: res, + }; + }) + .catch((): object => { + return { + __success: false, + code: response.status, + }; + }); + default: + return null; + } + }) + .then((json: any): void => { + if (json && json.__success !== false) { + resolve(json); + } else { + delete json.__success; + reject(json); + } + }) + .catch((err: Error): void => { + reject(err); + }); + }); +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..23314ab --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,44 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "declaration": true, + "lib": ["es2015", "dom"], + // Target latest version of ECMAScript. + "target": "esnext", + // Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. + "module": "esnext", + // Search under node_modules for non-relative imports. + "moduleResolution": "node", + // Process & infer types from .js files. + "allowJs": true, + // Report errors in .js files. + "checkJs": false, + // Don't emit; allow Babel to transform files. + // "noEmit": true, + // Enable strictest settings like strictNullChecks & noImplicitAny. + "strict": true, + // Allow default imports from modules with no default export. This does not affect code emit, just typechecking. + "allowSyntheticDefaultImports": true, + // Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. + "esModuleInterop": true, + // Specify JSX code generation: 'preserve', 'react-native', or 'react'. + "jsx": "preserve", + // Import emit helpers (e.g. __extends, __rest, etc..) from tslib + "importHelpers": true, + // Enables experimental support for ES7 decorators. + "experimentalDecorators": true, + // Generates corresponding .map file. + "sourceMap": true, + // Disallow inconsistently-cased references to the same file. + "forceConsistentCasingInFileNames": true, + // Allow json import + "resolveJsonModule": true, + // skip type checking of declaration files + "skipLibCheck": true, + "outDir": "lib" + }, + "include": [ + "./src/" + ], + "exclude": ["**/test", "**/lib", "**/es", "node_modules"] +}