Repository: alibaba/lowcode-engine Branch: main Commit: f6305c228495 Files: 2530 Total size: 5.4 MB Directory structure: gitextract_4erw24n6/ ├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github/ │ ├── CODEOWNERS │ ├── ISSUE_TEMPLATE/ │ │ └── bug-report.md │ └── workflows/ │ ├── check base branch.yml │ ├── ci.yml │ ├── cov packages.yml │ ├── help wanted.yml │ ├── insufficient information.yml │ ├── pr comment by chatgpt.yml │ ├── pre build.yml │ ├── publish docs.yml │ ├── publish engine beta.yml │ ├── publish engine.yml │ ├── stale.yml │ ├── test modules.yml │ └── test packages.yml ├── .gitignore ├── .prettierrc.js ├── .stylelintignore ├── .stylelintrc.js ├── CONTRIBUTOR.md ├── LICENSE ├── abc.json ├── babel.config.js ├── commitlint.config.js ├── deploy-space/ │ ├── lerna.json │ ├── package.json │ ├── static/ │ │ ├── index.html │ │ └── preview.html │ └── tsconfig.json ├── docs/ │ ├── .gitignore │ ├── README.md │ ├── babel.config.js │ ├── community/ │ │ └── issue.md │ ├── config/ │ │ ├── navbar.js │ │ ├── sidebars.js │ │ └── sidebarsCommunity.js │ ├── docs/ │ │ ├── api/ │ │ │ ├── canvas.md │ │ │ ├── command.md │ │ │ ├── common.md │ │ │ ├── commonUI.md │ │ │ ├── config.md │ │ │ ├── configOptions.md │ │ │ ├── event.md │ │ │ ├── hotkey.md │ │ │ ├── index.md │ │ │ ├── init.md │ │ │ ├── logger.md │ │ │ ├── material.md │ │ │ ├── model/ │ │ │ │ ├── _category_.json │ │ │ │ ├── clipboard.md │ │ │ │ ├── component-meta.md │ │ │ │ ├── detecting.md │ │ │ │ ├── document-model.md │ │ │ │ ├── dragon.md │ │ │ │ ├── drop-location.md │ │ │ │ ├── editor-view.md │ │ │ │ ├── history.md │ │ │ │ ├── modal-nodes-manager.md │ │ │ │ ├── node-children.md │ │ │ │ ├── node.md │ │ │ │ ├── plugin-instance.md │ │ │ │ ├── prop.md │ │ │ │ ├── props.md │ │ │ │ ├── resource.md │ │ │ │ ├── selection.md │ │ │ │ ├── setting-field.md │ │ │ │ ├── setting-top-entry.md │ │ │ │ ├── simulatorRender.md │ │ │ │ └── window.md │ │ │ ├── plugins.md │ │ │ ├── project.md │ │ │ ├── setters.md │ │ │ ├── simulatorHost.md │ │ │ ├── skeleton.md │ │ │ └── workspace.md │ │ ├── article/ │ │ │ └── index.md │ │ ├── demoUsage/ │ │ │ ├── advanced/ │ │ │ │ ├── _category_.json │ │ │ │ └── hotkey.md │ │ │ ├── appendix/ │ │ │ │ ├── _category_.json │ │ │ │ ├── api.md │ │ │ │ └── loop.md │ │ │ ├── intro.md │ │ │ ├── makeStuff/ │ │ │ │ ├── _category_.json │ │ │ │ ├── dialog.md │ │ │ │ └── table.md │ │ │ └── panels/ │ │ │ ├── _category_.json │ │ │ ├── canvas.md │ │ │ ├── code.md │ │ │ ├── component.md │ │ │ ├── datasource.md │ │ │ └── settings.md │ │ ├── faq/ │ │ │ ├── faq001.md │ │ │ ├── faq002.md │ │ │ ├── faq003.md │ │ │ ├── faq004.md │ │ │ ├── faq005.md │ │ │ ├── faq006.md │ │ │ ├── faq007.md │ │ │ ├── faq008.md │ │ │ ├── faq009.md │ │ │ ├── faq010.md │ │ │ ├── faq011.md │ │ │ ├── faq012.md │ │ │ ├── faq013.md │ │ │ ├── faq014.md │ │ │ ├── faq015.md │ │ │ ├── faq016.md │ │ │ ├── faq017.md │ │ │ ├── faq018.md │ │ │ ├── faq019.md │ │ │ ├── faq020.md │ │ │ ├── faq021.md │ │ │ ├── faq022.md │ │ │ ├── faq023.md │ │ │ ├── faq024.md │ │ │ └── index.md │ │ ├── guide/ │ │ │ ├── appendix/ │ │ │ │ ├── _category_.json │ │ │ │ ├── glossary.md │ │ │ │ ├── metaSpec.md │ │ │ │ ├── npms.md │ │ │ │ ├── repos.md │ │ │ │ ├── setterDetails/ │ │ │ │ │ ├── _category_.json │ │ │ │ │ ├── array.md │ │ │ │ │ ├── behavior.md │ │ │ │ │ ├── bool.md │ │ │ │ │ ├── color.md │ │ │ │ │ ├── event.md │ │ │ │ │ ├── function.md │ │ │ │ │ ├── icon.md │ │ │ │ │ ├── mixed.md │ │ │ │ │ ├── number.md │ │ │ │ │ ├── radioGroup.md │ │ │ │ │ ├── select.md │ │ │ │ │ ├── slot.md │ │ │ │ │ ├── string.md │ │ │ │ │ ├── style.md │ │ │ │ │ ├── textArea.md │ │ │ │ │ └── variable.md │ │ │ │ └── setters.md │ │ │ ├── create/ │ │ │ │ ├── _category_.json │ │ │ │ ├── useEditor.md │ │ │ │ └── useRenderer.md │ │ │ ├── design/ │ │ │ │ ├── _category_.json │ │ │ │ ├── datasourceEngine.md │ │ │ │ ├── editor.md │ │ │ │ ├── generator.md │ │ │ │ ├── materialParser.md │ │ │ │ ├── renderer.md │ │ │ │ ├── setter.md │ │ │ │ ├── specs.md │ │ │ │ └── summary.md │ │ │ ├── expand/ │ │ │ │ ├── _category_.json │ │ │ │ ├── editor/ │ │ │ │ │ ├── _category_.json │ │ │ │ │ ├── cli.md │ │ │ │ │ ├── graph.md │ │ │ │ │ ├── material.md │ │ │ │ │ ├── metaSpec.md │ │ │ │ │ ├── parts/ │ │ │ │ │ │ ├── _category_.json │ │ │ │ │ │ ├── partsIntro.md │ │ │ │ │ │ ├── partsassets.md │ │ │ │ │ │ ├── partslcc.md │ │ │ │ │ │ └── prototype.md │ │ │ │ │ ├── pluginContextMenu.md │ │ │ │ │ ├── pluginWidget.md │ │ │ │ │ ├── setter.md │ │ │ │ │ ├── summary.md │ │ │ │ │ └── theme.md │ │ │ │ └── runtime/ │ │ │ │ ├── _category_.json │ │ │ │ ├── codeGeneration.md │ │ │ │ └── renderer.md │ │ │ └── quickStart/ │ │ │ ├── _category_.json │ │ │ ├── demo.md │ │ │ ├── intro.md │ │ │ └── start.md │ │ ├── participate/ │ │ │ ├── code-specification.md │ │ │ ├── flow.md │ │ │ ├── index.md │ │ │ └── meet.md │ │ ├── specs/ │ │ │ ├── assets-spec.md │ │ │ ├── lowcode-spec.md │ │ │ └── material-spec.md │ │ └── video/ │ │ └── index.md │ ├── docusaurus.config.js │ ├── package.json │ ├── scripts/ │ │ ├── getDocsFromDir.js │ │ └── sync-oss.js │ ├── src/ │ │ ├── css/ │ │ │ └── custom.css │ │ └── pages/ │ │ ├── index-old.tsx │ │ ├── index.module.css │ │ ├── index.tsx │ │ └── markdown-page.md │ └── tsconfig.json ├── index.ts ├── lerna.json ├── modules/ │ ├── code-generator/ │ │ ├── .gitignore │ │ ├── .prettierrc.js │ │ ├── .versionrc │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTING.md │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── bin/ │ │ │ └── lowcode-code-generator.js │ │ ├── example-schema.json │ │ ├── example-schema.json5 │ │ ├── jest.config.js │ │ ├── jest.setup.js │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── build-cli.js │ │ │ ├── build-standalone-loader.js │ │ │ ├── build-standalone-worker.js │ │ │ ├── build-standalone.js │ │ │ ├── build-template-static-files.js │ │ │ ├── build-types │ │ │ ├── build.js │ │ │ ├── move-files-to-build-dest.js │ │ │ ├── run-demo-project │ │ │ └── test-standalone.js │ │ ├── src/ │ │ │ ├── analyzer/ │ │ │ │ └── componentAnalyzer.ts │ │ │ ├── cli/ │ │ │ │ ├── index.ts │ │ │ │ ├── init-solution.ts │ │ │ │ ├── run.ts │ │ │ │ └── solutions/ │ │ │ │ └── example-solution.ts │ │ │ ├── config/ │ │ │ │ └── env.ts │ │ │ ├── const/ │ │ │ │ ├── file.ts │ │ │ │ ├── generator.ts │ │ │ │ └── index.ts │ │ │ ├── core/ │ │ │ │ └── jsx/ │ │ │ │ ├── handlers/ │ │ │ │ │ ├── transformJsExpression.ts │ │ │ │ │ └── transformThis2Context.ts │ │ │ │ └── util/ │ │ │ │ ├── isLiteralAtomicExpr.ts │ │ │ │ └── isSimpleStraightLiteral.ts │ │ │ ├── generator/ │ │ │ │ ├── ChunkBuilder.ts │ │ │ │ ├── CodeBuilder.ts │ │ │ │ ├── ModuleBuilder.ts │ │ │ │ └── ProjectBuilder.ts │ │ │ ├── index.ts │ │ │ ├── parser/ │ │ │ │ └── SchemaParser.ts │ │ │ ├── plugins/ │ │ │ │ ├── common/ │ │ │ │ │ ├── esmodule.ts │ │ │ │ │ ├── requireUtils.ts │ │ │ │ │ └── styleImport.ts │ │ │ │ ├── component/ │ │ │ │ │ ├── rax/ │ │ │ │ │ │ ├── commonDeps.ts │ │ │ │ │ │ ├── const.ts │ │ │ │ │ │ ├── containerClass.ts │ │ │ │ │ │ ├── containerInitState.ts │ │ │ │ │ │ ├── containerInjectContext.ts │ │ │ │ │ │ ├── containerInjectDataSourceEngine.ts │ │ │ │ │ │ ├── containerInjectUtils.ts │ │ │ │ │ │ ├── containerLifeCycle.ts │ │ │ │ │ │ ├── containerMethods.ts │ │ │ │ │ │ └── jsx.ts │ │ │ │ │ ├── react/ │ │ │ │ │ │ ├── const.ts │ │ │ │ │ │ ├── containerClass.ts │ │ │ │ │ │ ├── containerInitState.ts │ │ │ │ │ │ ├── containerInjectConstants.ts │ │ │ │ │ │ ├── containerInjectContext.ts │ │ │ │ │ │ ├── containerInjectDataSourceEngine.ts │ │ │ │ │ │ ├── containerInjectI18n.ts │ │ │ │ │ │ ├── containerInjectUtils.ts │ │ │ │ │ │ ├── containerLifeCycle.ts │ │ │ │ │ │ ├── containerMethod.ts │ │ │ │ │ │ ├── jsx.ts │ │ │ │ │ │ └── reactCommonDeps.ts │ │ │ │ │ └── style/ │ │ │ │ │ └── css.ts │ │ │ │ └── project/ │ │ │ │ ├── constants.ts │ │ │ │ ├── framework/ │ │ │ │ │ ├── icejs/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── plugins/ │ │ │ │ │ │ │ ├── entry.ts │ │ │ │ │ │ │ ├── entryHtml.ts │ │ │ │ │ │ │ ├── globalStyle.ts │ │ │ │ │ │ │ ├── packageJSON.ts │ │ │ │ │ │ │ └── router.ts │ │ │ │ │ │ └── template/ │ │ │ │ │ │ ├── files/ │ │ │ │ │ │ │ ├── README.md.ts │ │ │ │ │ │ │ ├── abc.json.ts │ │ │ │ │ │ │ ├── build.json.ts │ │ │ │ │ │ │ ├── editorconfig.ts │ │ │ │ │ │ │ ├── eslintignore.ts │ │ │ │ │ │ │ ├── eslintrc.js.ts │ │ │ │ │ │ │ ├── gitignore.ts │ │ │ │ │ │ │ ├── jsconfig.json.ts │ │ │ │ │ │ │ ├── prettierignore.ts │ │ │ │ │ │ │ ├── prettierrc.js.ts │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ └── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ │ │ └── index.style.ts │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ │ │ └── index.style.ts │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx.ts │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ └── menuConfig.js.ts │ │ │ │ │ │ │ ├── stylelintignore.ts │ │ │ │ │ │ │ ├── stylelintrc.js.ts │ │ │ │ │ │ │ └── tsconfig.json.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── static-files.ts │ │ │ │ │ ├── icejs3/ │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── plugins/ │ │ │ │ │ │ │ ├── appConfig.ts │ │ │ │ │ │ │ ├── buildConfig.ts │ │ │ │ │ │ │ ├── globalStyle.ts │ │ │ │ │ │ │ ├── layout.ts │ │ │ │ │ │ │ └── packageJSON.ts │ │ │ │ │ │ └── template/ │ │ │ │ │ │ ├── files/ │ │ │ │ │ │ │ ├── README.md.ts │ │ │ │ │ │ │ ├── browserslistrc.ts │ │ │ │ │ │ │ ├── document.ts │ │ │ │ │ │ │ ├── gitignore.ts │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ └── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ │ │ └── index.style.ts │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ │ │ └── index.style.ts │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx.ts │ │ │ │ │ │ │ │ ├── index.jsx.ts │ │ │ │ │ │ │ │ └── menuConfig.js.ts │ │ │ │ │ │ │ ├── tsconfig.ts │ │ │ │ │ │ │ └── typings.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── static-files.ts │ │ │ │ │ └── rax/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── plugins/ │ │ │ │ │ │ ├── appConfig.ts │ │ │ │ │ │ ├── buildConfig.ts │ │ │ │ │ │ ├── entry.ts │ │ │ │ │ │ ├── entryDocument.ts │ │ │ │ │ │ ├── globalStyle.ts │ │ │ │ │ │ └── packageJSON.ts │ │ │ │ │ ├── template/ │ │ │ │ │ │ ├── files/ │ │ │ │ │ │ │ ├── .eslintignore.ts │ │ │ │ │ │ │ ├── .eslintrc.js.ts │ │ │ │ │ │ │ ├── .gitignore.ts │ │ │ │ │ │ │ ├── .prettierignore.ts │ │ │ │ │ │ │ ├── .prettierrc.js.ts │ │ │ │ │ │ │ ├── .stylelintignore.ts │ │ │ │ │ │ │ ├── .stylelintrc.js.ts │ │ │ │ │ │ │ ├── README.md.ts │ │ │ │ │ │ │ ├── jsconfig.json.ts │ │ │ │ │ │ │ └── tsconfig.json.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── static-files.ts │ │ │ │ │ └── types/ │ │ │ │ │ └── RaxFrameworkOptions.ts │ │ │ │ ├── i18n.ts │ │ │ │ └── utils.ts │ │ │ ├── polyfills/ │ │ │ │ └── buffer.ts │ │ │ ├── postprocessor/ │ │ │ │ ├── index.ts │ │ │ │ └── prettier/ │ │ │ │ └── index.ts │ │ │ ├── publisher/ │ │ │ │ ├── disk/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── utils.ts │ │ │ │ └── zip/ │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ ├── solutions/ │ │ │ │ ├── icejs.ts │ │ │ │ ├── icejs3.ts │ │ │ │ └── rax-app.ts │ │ │ ├── standalone-loader.ts │ │ │ ├── standalone-worker.ts │ │ │ ├── standalone.ts │ │ │ ├── types/ │ │ │ │ ├── analyze.ts │ │ │ │ ├── core.ts │ │ │ │ ├── deps.ts │ │ │ │ ├── error.ts │ │ │ │ ├── file.ts │ │ │ │ ├── index.ts │ │ │ │ ├── intermediate.ts │ │ │ │ ├── jsx.ts │ │ │ │ └── publisher.ts │ │ │ ├── typings.d.ts │ │ │ └── utils/ │ │ │ ├── OrderedSet.ts │ │ │ ├── Scope.ts │ │ │ ├── ScopeBindings.ts │ │ │ ├── aopHelper.ts │ │ │ ├── common.ts │ │ │ ├── compositeType.ts │ │ │ ├── dataSource.ts │ │ │ ├── debug.ts │ │ │ ├── encodeJsxAttrString.ts │ │ │ ├── errors.ts │ │ │ ├── expressionParser.ts │ │ │ ├── format.ts │ │ │ ├── index.ts │ │ │ ├── jsExpression.ts │ │ │ ├── jsSlot.ts │ │ │ ├── jsxHelpers.ts │ │ │ ├── nodeToJSX.ts │ │ │ ├── pathHelper.ts │ │ │ ├── resultHelper.ts │ │ │ ├── schema.ts │ │ │ ├── templateHelper.ts │ │ │ ├── theme.ts │ │ │ ├── validate.ts │ │ │ └── version.ts │ │ ├── standalone/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── standalone-loader/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── standalone-worker/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── static-files/ │ │ │ └── rax/ │ │ │ ├── .eslintignore.template │ │ │ ├── .eslintrc.js.template │ │ │ ├── .gitignore.template │ │ │ ├── .prettierignore.template │ │ │ ├── .prettierrc.js.template │ │ │ ├── .stylelintignore.template │ │ │ ├── .stylelintrc.js.template │ │ │ ├── README.md.template │ │ │ ├── jsconfig.json.template │ │ │ └── tsconfig.json.template │ │ ├── tests/ │ │ │ ├── bugfix/ │ │ │ │ ├── .gitignore │ │ │ │ ├── i18n-with-params.schema.json │ │ │ │ ├── i18n-with-params.test.ts │ │ │ │ ├── icejs-import-wrong-naming.schema.json │ │ │ │ ├── icejs-import-wrong-naming.test.ts │ │ │ │ ├── icejs-js-function1.schema.json │ │ │ │ ├── icejs-js-function1.test.ts │ │ │ │ ├── icejs-missing-imports-1.schema.json │ │ │ │ ├── icejs-missing-imports-1.test.ts │ │ │ │ ├── icejs-package-json-dependencies.schema.json │ │ │ │ ├── icejs-package-json-dependencies.test.ts │ │ │ │ ├── icejs-page-map1.schema.json │ │ │ │ ├── icejs-page-map1.test.ts │ │ │ │ ├── page-element1.schema.json │ │ │ │ ├── page-element1.test.ts │ │ │ │ ├── page-element2.schema.json │ │ │ │ ├── page-element2.test.ts │ │ │ │ ├── strict-mode-context-1.schema.json │ │ │ │ ├── strict-mode-context-1.test.ts │ │ │ │ ├── tolerate-eval-errors-1-loop.schema.json │ │ │ │ ├── tolerate-eval-errors-1-loop.test.ts │ │ │ │ ├── tolerate-eval-errors-2-nested-loop.schema.json │ │ │ │ └── tolerate-eval-errors-2-nested-loop.test.ts │ │ │ ├── cli.test.ts │ │ │ ├── fixtures/ │ │ │ │ └── test-cases/ │ │ │ │ ├── .gitignore │ │ │ │ ├── icejs3-app/ │ │ │ │ │ ├── demo1/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo2/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo2-utils-name-alias/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Aaaa/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo3/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo4/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo5/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo6-literal-condition/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo7-literal-condition2/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo8-datasource-prop/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Example/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo9-datasource-engine/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── $/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo_10-jsslot/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ └── src/ │ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ └── demo_11-jsslot-2/ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ ├── .browserslistrc │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── ice.config.mts │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ └── src/ │ │ │ │ │ │ ├── app.ts │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ ├── document.tsx │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ ├── Test/ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ └── layout.jsx │ │ │ │ │ │ ├── typings.d.ts │ │ │ │ │ │ └── utils.js │ │ │ │ │ └── schema.json5 │ │ │ │ ├── rax-app/ │ │ │ │ │ ├── demo01/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo02/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo03/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ ├── Detail/ │ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── Home/ │ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ └── List/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo04/ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo05/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo06-jsslot/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo07-newline-in-props/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo08-jsslot-with-multiple-children/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo09-jsslot-with-conditional-children/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo10-jsslot-with-loop-children/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo11-utils-name-alias/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Aaaa/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo12-refs/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Home/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ └── demo13-datasource-prop/ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ ├── app.json │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── document/ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── global.css │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ └── Example/ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ └── schema.json5 │ │ │ │ ├── react-app/ │ │ │ │ │ ├── demo1/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo2/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo2-utils-name-alias/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Aaaa/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo3/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo4/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo5/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo6-literal-condition/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo7-literal-condition2/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo8-datasource-prop/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Example/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo9-datasource-engine/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── $/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ ├── demo_10-jsslot/ │ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ │ └── schema.json5 │ │ │ │ │ └── demo_11-jsslot-2/ │ │ │ │ │ ├── expected/ │ │ │ │ │ │ └── demo-project/ │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ ├── .eslintignore │ │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── .prettierignore │ │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── abc.json │ │ │ │ │ │ ├── build.json │ │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ │ ├── package.json │ │ │ │ │ │ ├── public/ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── src/ │ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ │ └── utils.js │ │ │ │ │ │ └── tsconfig.json │ │ │ │ │ └── schema.json5 │ │ │ │ └── react-module/ │ │ │ │ └── demo1/ │ │ │ │ ├── expected/ │ │ │ │ │ └── demo-project/ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ ├── .eslintignore │ │ │ │ │ ├── .eslintrc.js │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .prettierignore │ │ │ │ │ ├── .prettierrc.js │ │ │ │ │ ├── .stylelintignore │ │ │ │ │ ├── .stylelintrc.js │ │ │ │ │ ├── README.md │ │ │ │ │ ├── abc.json │ │ │ │ │ ├── build.json │ │ │ │ │ ├── jsconfig.json │ │ │ │ │ ├── package.json │ │ │ │ │ ├── public/ │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── src/ │ │ │ │ │ │ ├── app.js │ │ │ │ │ │ ├── constants.js │ │ │ │ │ │ ├── global.scss │ │ │ │ │ │ ├── i18n.js │ │ │ │ │ │ ├── layouts/ │ │ │ │ │ │ │ └── BasicLayout/ │ │ │ │ │ │ │ ├── components/ │ │ │ │ │ │ │ │ ├── Footer/ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ ├── Logo/ │ │ │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ │ │ └── index.module.scss │ │ │ │ │ │ │ │ └── PageNav/ │ │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ │ ├── index.jsx │ │ │ │ │ │ │ └── menuConfig.js │ │ │ │ │ │ ├── pages/ │ │ │ │ │ │ │ └── Test/ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ └── index.jsx │ │ │ │ │ │ ├── routes.js │ │ │ │ │ │ └── utils.js │ │ │ │ │ └── tsconfig.json │ │ │ │ └── schema.json5 │ │ │ ├── helpers/ │ │ │ │ └── solutionHelper.ts │ │ │ ├── plugins/ │ │ │ │ ├── common/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── requireUtils.test.ts.snap │ │ │ │ │ └── requireUtils.test.ts │ │ │ │ └── jsx/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── p0-condition-at-root.test.ts.snap │ │ │ │ └── p0-condition-at-root.test.ts │ │ │ ├── postprocessor/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── prettier.test.ts.snap │ │ │ │ └── prettier.test.ts │ │ │ ├── public/ │ │ │ │ ├── README.md │ │ │ │ ├── SchemaParser/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── p0-basic.test.ts.snap │ │ │ │ │ ├── data/ │ │ │ │ │ │ └── schema-with-slot.json │ │ │ │ │ └── p0-basic.test.ts │ │ │ │ ├── cli.test.ts │ │ │ │ ├── publisher/ │ │ │ │ │ ├── disk/ │ │ │ │ │ │ └── disk.test.ts │ │ │ │ │ └── zip/ │ │ │ │ │ └── zip.test.ts │ │ │ │ └── solutions/ │ │ │ │ ├── icejs3-app.test.ts │ │ │ │ ├── rax-app.test.ts │ │ │ │ └── react-app.test.ts │ │ │ └── utils/ │ │ │ ├── compositeType.test.ts │ │ │ ├── errors.test.ts │ │ │ ├── expressionParser/ │ │ │ │ ├── jsExpression.test.ts │ │ │ │ ├── parseExpressionConvertThis2Context.test.ts │ │ │ │ ├── parseExpressionGetGlobalVariables.test.ts │ │ │ │ └── parseExpressionGetKeywords.test.ts │ │ │ ├── flattenResult.test.ts │ │ │ ├── resultHelper/ │ │ │ │ ├── example-result.json │ │ │ │ ├── findFile.test.ts │ │ │ │ ├── globFiles.test.ts │ │ │ │ ├── removeDirsFromResult.test.ts │ │ │ │ ├── removeFilesFromResult.test.ts │ │ │ │ └── scanFiles.test.ts │ │ │ ├── schema/ │ │ │ │ ├── data/ │ │ │ │ │ └── schema-with-slot.json │ │ │ │ └── handleSubNodes.test.ts │ │ │ ├── validate.test.ts │ │ │ └── version.test.ts │ │ └── tsconfig.json │ └── material-parser/ │ ├── README.md │ ├── build.test.json │ ├── demo/ │ │ ├── component.jsx │ │ ├── component.tsx │ │ ├── parse-jsx.js │ │ └── parse-tsx.js │ ├── jest.config.js │ ├── package.json │ ├── schemas/ │ │ ├── schema.json │ │ └── schema.yml │ ├── scripts/ │ │ └── transform.js │ ├── src/ │ │ ├── core/ │ │ │ ├── index.ts │ │ │ └── schema/ │ │ │ └── types.ts │ │ ├── generate.ts │ │ ├── index.ts │ │ ├── localize.ts │ │ ├── parse/ │ │ │ ├── dynamic/ │ │ │ │ ├── index.ts │ │ │ │ └── requireInSandbox.ts │ │ │ ├── index.ts │ │ │ ├── js/ │ │ │ │ ├── handlers/ │ │ │ │ │ ├── defaultPropsHandler.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── preProcessHandler.ts │ │ │ │ │ ├── propTypeHandler.ts │ │ │ │ │ └── propTypeJsDocHandler.ts │ │ │ │ ├── index.ts │ │ │ │ ├── resolver/ │ │ │ │ │ ├── checkIsIIFE.ts │ │ │ │ │ ├── findAssignedMethods.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── isReactComponentStaticMember.ts │ │ │ │ │ ├── isStaticMethod.ts │ │ │ │ │ ├── resolveExportDeclaration.ts │ │ │ │ │ ├── resolveHOC.ts │ │ │ │ │ ├── resolveIIFE.ts │ │ │ │ │ ├── resolveImport.ts │ │ │ │ │ └── resolveTranspiledClass.ts │ │ │ │ └── utils/ │ │ │ │ ├── cache.ts │ │ │ │ ├── evaluate.ts │ │ │ │ ├── findJSFilePath.ts │ │ │ │ ├── getComposedPath.ts │ │ │ │ ├── getName.ts │ │ │ │ ├── getRoot.ts │ │ │ │ └── makeProxy.ts │ │ │ ├── transform.ts │ │ │ └── ts/ │ │ │ ├── generateDTS.ts │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ ├── scan.ts │ │ ├── types/ │ │ │ ├── Basic.ts │ │ │ ├── ChannelType.ts │ │ │ ├── DSLType.ts │ │ │ ├── IAccesser.ts │ │ │ ├── IExtensionConfigManifest.ts │ │ │ ├── IMaterialParsedModel.ts │ │ │ ├── IMaterialScanModel.ts │ │ │ ├── IMaterializeOptions.ts │ │ │ ├── Meta.ts │ │ │ └── index.ts │ │ ├── utils.ts │ │ └── validate/ │ │ ├── index.ts │ │ └── schema.json │ ├── test/ │ │ ├── __snapshots__/ │ │ │ ├── dynamic.test.ts.snap │ │ │ ├── index.test.ts.snap │ │ │ └── online.test.ts.snap │ │ ├── dynamic.test.ts │ │ ├── fixtures/ │ │ │ ├── dts-component/ │ │ │ │ ├── index.d.ts │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── data.js │ │ │ │ ├── i18n.js │ │ │ │ ├── index.jsx │ │ │ │ ├── main.scss │ │ │ │ └── scss/ │ │ │ │ └── variable.scss │ │ │ ├── multiple-exported-component/ │ │ │ │ ├── es/ │ │ │ │ │ ├── basic/ │ │ │ │ │ │ ├── AIMakeBlank/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── AIMakeIcon/ │ │ │ │ │ │ │ ├── IconFont.js │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── AIMakeImage/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── AIMakeLink/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── AIMakePlaceholder/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── AIMakeText/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── Root/ │ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── style/ │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ │ └── index.less │ │ │ │ │ │ └── utils/ │ │ │ │ │ │ ├── HOCBackgroundProps.js │ │ │ │ │ │ ├── HOCBoxModelProps.js │ │ │ │ │ │ ├── HOCFlexLayoutProps.js │ │ │ │ │ │ ├── HOCLayoutProps.js │ │ │ │ │ │ └── HOCTextProps.js │ │ │ │ │ └── index.js │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── basic/ │ │ │ │ │ ├── AIMakeBlank/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── AIMakeIcon/ │ │ │ │ │ │ ├── IconFont.js │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── AIMakeImage/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── AIMakeLink/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── AIMakePlaceholder/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── AIMakeText/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── Root/ │ │ │ │ │ │ ├── amContainer.js │ │ │ │ │ │ ├── amManifest.js │ │ │ │ │ │ ├── container.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── manifest.js │ │ │ │ │ │ └── manifest.json │ │ │ │ │ ├── style/ │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ └── index.less │ │ │ │ │ └── utils/ │ │ │ │ │ ├── HOCBackgroundProps.js │ │ │ │ │ ├── HOCBoxModelProps.js │ │ │ │ │ ├── HOCFlexLayoutProps.js │ │ │ │ │ ├── HOCLayoutProps.js │ │ │ │ │ └── HOCTextProps.js │ │ │ │ └── index.js │ │ │ ├── rax-component/ │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── single-exported-component/ │ │ │ │ ├── es/ │ │ │ │ │ ├── container.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── main.css │ │ │ │ │ ├── main.scss │ │ │ │ │ ├── manifest.js │ │ │ │ │ └── manifest.json │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── index.js │ │ │ │ └── main.scss │ │ │ ├── transpiled-component/ │ │ │ │ └── package.json │ │ │ ├── ts-component/ │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── index.tsx │ │ │ │ ├── main-module.tsx │ │ │ │ └── sub-module.tsx │ │ │ ├── ts-component2/ │ │ │ │ ├── package.json │ │ │ │ └── src/ │ │ │ │ ├── empty.tsx │ │ │ │ ├── index.scss │ │ │ │ └── index.tsx │ │ │ └── without-display-name/ │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── helpers/ │ │ │ └── index.ts │ │ ├── index.test.ts │ │ ├── localize.test.ts │ │ ├── online.test.ts │ │ └── validate/ │ │ ├── __snapshots__/ │ │ │ └── index.test.ts.snap │ │ ├── fixtures/ │ │ │ ├── basic-error/ │ │ │ │ └── schema.json │ │ │ ├── basic-success/ │ │ │ │ └── schema.json │ │ │ ├── configure/ │ │ │ │ └── schema.json │ │ │ ├── props-basic-type/ │ │ │ │ └── schema.json │ │ │ └── props-complex-type/ │ │ │ └── schema.json │ │ └── index.test.ts │ ├── tsconfig.json │ └── webpack.config.js ├── package.json ├── packages/ │ ├── designer/ │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── build.json │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── builtin-simulator/ │ │ │ │ ├── README.md │ │ │ │ ├── bem-tools/ │ │ │ │ │ ├── bem-tools.less │ │ │ │ │ ├── border-container.tsx │ │ │ │ │ ├── border-detecting.tsx │ │ │ │ │ ├── border-resizing.tsx │ │ │ │ │ ├── border-selecting.tsx │ │ │ │ │ ├── borders.less │ │ │ │ │ ├── drag-resize-engine.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── insertion.less │ │ │ │ │ ├── insertion.tsx │ │ │ │ │ └── manager.ts │ │ │ │ ├── context.ts │ │ │ │ ├── create-simulator.ts │ │ │ │ ├── host-view.tsx │ │ │ │ ├── host.less │ │ │ │ ├── host.ts │ │ │ │ ├── index.ts │ │ │ │ ├── live-editing/ │ │ │ │ │ └── live-editing.ts │ │ │ │ ├── node-selector/ │ │ │ │ │ ├── index.less │ │ │ │ │ └── index.tsx │ │ │ │ ├── renderer.ts │ │ │ │ ├── resource-consumer.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── clickable.ts │ │ │ │ │ ├── parse-metadata.ts │ │ │ │ │ ├── path.ts │ │ │ │ │ └── throttle.ts │ │ │ │ └── viewport.ts │ │ │ ├── component-actions.ts │ │ │ ├── component-meta.ts │ │ │ ├── context-menu-actions.scss │ │ │ ├── context-menu-actions.ts │ │ │ ├── designer/ │ │ │ │ ├── active-tracker.ts │ │ │ │ ├── clipboard.ts │ │ │ │ ├── designer-view.tsx │ │ │ │ ├── designer.less │ │ │ │ ├── designer.ts │ │ │ │ ├── detecting.ts │ │ │ │ ├── drag-ghost/ │ │ │ │ │ ├── README.md │ │ │ │ │ ├── ghost.less │ │ │ │ │ └── index.tsx │ │ │ │ ├── dragon.ts │ │ │ │ ├── index.ts │ │ │ │ ├── location.ts │ │ │ │ ├── offset-observer.ts │ │ │ │ ├── scroller.ts │ │ │ │ └── setting/ │ │ │ │ ├── index.ts │ │ │ │ ├── setting-entry-type.ts │ │ │ │ ├── setting-field.ts │ │ │ │ ├── setting-prop-entry.ts │ │ │ │ ├── setting-top-entry.ts │ │ │ │ └── utils.ts │ │ │ ├── document/ │ │ │ │ ├── document-model.ts │ │ │ │ ├── document-view.tsx │ │ │ │ ├── history.ts │ │ │ │ ├── index.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── exclusive-group.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── modal-nodes-manager.ts │ │ │ │ │ ├── node-children.ts │ │ │ │ │ ├── node.ts │ │ │ │ │ ├── props/ │ │ │ │ │ │ ├── prop.ts │ │ │ │ │ │ ├── props.ts │ │ │ │ │ │ └── value-to-source.ts │ │ │ │ │ └── transform-stage.ts │ │ │ │ └── selection.ts │ │ │ ├── icons/ │ │ │ │ ├── clone.tsx │ │ │ │ ├── component.tsx │ │ │ │ ├── container.tsx │ │ │ │ ├── hidden.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── lock.tsx │ │ │ │ ├── page.tsx │ │ │ │ ├── remove.tsx │ │ │ │ ├── setting.tsx │ │ │ │ └── unlock.tsx │ │ │ ├── index.ts │ │ │ ├── less-variables.less │ │ │ ├── locale/ │ │ │ │ ├── en-US.json │ │ │ │ ├── index.ts │ │ │ │ └── zh-CN.json │ │ │ ├── plugin/ │ │ │ │ ├── index.ts │ │ │ │ ├── plugin-context.ts │ │ │ │ ├── plugin-manager.ts │ │ │ │ ├── plugin-types.ts │ │ │ │ ├── plugin-utils.ts │ │ │ │ ├── plugin.ts │ │ │ │ └── sequencify.ts │ │ │ ├── project/ │ │ │ │ ├── index.ts │ │ │ │ ├── project-view.tsx │ │ │ │ ├── project.less │ │ │ │ └── project.ts │ │ │ ├── simulator.ts │ │ │ ├── transducers/ │ │ │ │ └── index.ts │ │ │ ├── types/ │ │ │ │ └── index.ts │ │ │ └── utils/ │ │ │ ├── index.ts │ │ │ ├── invariant.ts │ │ │ ├── misc.ts │ │ │ ├── slot.ts │ │ │ └── tree.ts │ │ ├── tests/ │ │ │ ├── __mocks__/ │ │ │ │ ├── document-model.ts │ │ │ │ └── node.ts │ │ │ ├── bugs/ │ │ │ │ ├── misc.ts.bak │ │ │ │ ├── prop-variable-jse.test.ts │ │ │ │ └── why.md │ │ │ ├── builtin-simulator/ │ │ │ │ ├── bem-tools/ │ │ │ │ │ ├── drag-resize-engine.test.ts │ │ │ │ │ └── manager.test.tsx │ │ │ │ ├── host.test.ts │ │ │ │ ├── renderer.test.tsx │ │ │ │ ├── resource-consumer.test.ts │ │ │ │ ├── utils/ │ │ │ │ │ ├── parse-metadata.test.ts │ │ │ │ │ ├── path.test.ts │ │ │ │ │ └── throttle.test.ts │ │ │ │ └── viewport.test.ts │ │ │ ├── designer/ │ │ │ │ ├── active-tracker.test.ts │ │ │ │ ├── builtin-hotkey.test.ts │ │ │ │ ├── designer.test.ts │ │ │ │ ├── detecting.test.ts │ │ │ │ ├── dragon.test.ts │ │ │ │ ├── location.test.ts │ │ │ │ ├── scroller.test.ts │ │ │ │ └── setting/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── setting-field.test.ts.snap │ │ │ │ ├── setting-field.test.ts │ │ │ │ ├── setting-prop-entry.test.ts │ │ │ │ └── setting-top-entry.test.ts │ │ │ ├── document/ │ │ │ │ ├── document-model/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── document-model.test.ts.snap │ │ │ │ │ └── document-model.test.ts │ │ │ │ ├── history/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── history.test.ts.snap │ │ │ │ │ ├── history.test.ts │ │ │ │ │ └── session.test.ts │ │ │ │ ├── node/ │ │ │ │ │ ├── modal-nodes-manager.test.ts │ │ │ │ │ ├── node-children.test.ts │ │ │ │ │ ├── node.add.test.ts │ │ │ │ │ ├── node.dragdrop.test.ts │ │ │ │ │ ├── node.modify.test.ts │ │ │ │ │ ├── node.remove.test.ts │ │ │ │ │ ├── node.test.ts │ │ │ │ │ └── props/ │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── value-to-source.test.ts.snap │ │ │ │ │ ├── prop.test.ts │ │ │ │ │ ├── props.test.ts │ │ │ │ │ └── value-to-source.test.ts │ │ │ │ └── selection.test.ts │ │ │ ├── fixtures/ │ │ │ │ ├── component-metadata/ │ │ │ │ │ ├── abcgroup.ts │ │ │ │ │ ├── abcitem.ts │ │ │ │ │ ├── abcnode.ts │ │ │ │ │ ├── abcoption.ts │ │ │ │ │ ├── button.ts │ │ │ │ │ ├── dialog.ts │ │ │ │ │ ├── div.ts │ │ │ │ │ ├── div10.ts │ │ │ │ │ ├── div2.ts │ │ │ │ │ ├── div3.ts │ │ │ │ │ ├── div4.ts │ │ │ │ │ ├── div5.ts │ │ │ │ │ ├── div6.ts │ │ │ │ │ ├── div7.ts │ │ │ │ │ ├── div8.ts │ │ │ │ │ ├── div9.ts │ │ │ │ │ ├── form.ts │ │ │ │ │ ├── other.ts │ │ │ │ │ ├── page.ts │ │ │ │ │ ├── page2.ts │ │ │ │ │ ├── root-content.ts │ │ │ │ │ ├── root-footer.ts │ │ │ │ │ └── root-header.ts │ │ │ │ ├── disable-raf.ts │ │ │ │ ├── schema/ │ │ │ │ │ ├── form-with-modal.ts │ │ │ │ │ ├── form.ts │ │ │ │ │ └── setting.ts │ │ │ │ ├── silent-console.ts │ │ │ │ ├── unhandled-rejection.ts │ │ │ │ └── window.ts │ │ │ ├── main/ │ │ │ │ ├── meta/ │ │ │ │ │ └── component-meta.test.ts │ │ │ │ └── simulator.test.ts │ │ │ ├── plugin/ │ │ │ │ ├── plugin-manager.test.ts │ │ │ │ ├── plugin-utils.test.ts │ │ │ │ └── sequencify.test.ts │ │ │ ├── project/ │ │ │ │ ├── project-methods.test.ts │ │ │ │ └── project.test.ts │ │ │ ├── utils/ │ │ │ │ ├── bom.ts │ │ │ │ ├── event.ts │ │ │ │ ├── index.ts │ │ │ │ ├── misc.ts │ │ │ │ └── renderer.ts │ │ │ └── utils-ut/ │ │ │ ├── invariant.test.ts │ │ │ ├── misc.test.ts │ │ │ └── slot.test.ts │ │ └── tsconfig.json │ ├── editor-core/ │ │ ├── build.json │ │ ├── build.plugin.js │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── command.ts │ │ │ ├── config.ts │ │ │ ├── di/ │ │ │ │ ├── index.ts │ │ │ │ ├── ioc-context.ts │ │ │ │ └── setter.ts │ │ │ ├── editor.ts │ │ │ ├── event-bus.ts │ │ │ ├── hotkey.ts │ │ │ ├── index.ts │ │ │ ├── intl/ │ │ │ │ ├── global-locale.ts │ │ │ │ └── index.ts │ │ │ ├── utils/ │ │ │ │ ├── app-preset.ts │ │ │ │ ├── assets-transform.ts │ │ │ │ ├── control.ts │ │ │ │ ├── focus-tracker.ts │ │ │ │ ├── get-public-path.ts │ │ │ │ ├── index.ts │ │ │ │ ├── logger.ts │ │ │ │ ├── obx.ts │ │ │ │ ├── preference.ts │ │ │ │ └── request.ts │ │ │ └── widgets/ │ │ │ ├── index.ts │ │ │ ├── tip/ │ │ │ │ ├── help-tips.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── style.less │ │ │ │ ├── tip-container.tsx │ │ │ │ ├── tip-handler.ts │ │ │ │ ├── tip-item.tsx │ │ │ │ ├── tip.tsx │ │ │ │ └── utils.ts │ │ │ └── title/ │ │ │ ├── index.tsx │ │ │ └── title.less │ │ ├── test/ │ │ │ └── command.test.ts │ │ └── tsconfig.json │ ├── editor-skeleton/ │ │ ├── build.json │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── area.ts │ │ │ ├── components/ │ │ │ │ ├── draggable-line/ │ │ │ │ │ ├── index.less │ │ │ │ │ └── index.tsx │ │ │ │ ├── field/ │ │ │ │ │ ├── fields.tsx │ │ │ │ │ ├── index.less │ │ │ │ │ ├── index.ts │ │ │ │ │ └── inlinetip.tsx │ │ │ │ ├── popup/ │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── style.less │ │ │ │ ├── settings/ │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── main.ts │ │ │ │ │ ├── settings-pane.tsx │ │ │ │ │ ├── settings-primary-pane.tsx │ │ │ │ │ ├── style.less │ │ │ │ │ └── utils.ts │ │ │ │ ├── stage-box/ │ │ │ │ │ ├── index.less │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── stage-box.tsx │ │ │ │ │ ├── stage-chain.ts │ │ │ │ │ └── stage.tsx │ │ │ │ └── widget-views/ │ │ │ │ ├── index.less │ │ │ │ ├── index.tsx │ │ │ │ └── panel-operation-row.tsx │ │ │ ├── context.ts │ │ │ ├── icons/ │ │ │ │ ├── arrow.tsx │ │ │ │ ├── clear.tsx │ │ │ │ ├── convert.tsx │ │ │ │ ├── exit.tsx │ │ │ │ ├── fix.tsx │ │ │ │ ├── float.tsx │ │ │ │ ├── slot.tsx │ │ │ │ └── variable.tsx │ │ │ ├── index.ts │ │ │ ├── layouts/ │ │ │ │ ├── bottom-area.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── left-area.tsx │ │ │ │ ├── left-fixed-pane.tsx │ │ │ │ ├── left-float-pane.tsx │ │ │ │ ├── main-area.tsx │ │ │ │ ├── right-area.tsx │ │ │ │ ├── sub-top-area.tsx │ │ │ │ ├── theme.less │ │ │ │ ├── toolbar.tsx │ │ │ │ ├── top-area.tsx │ │ │ │ ├── workbench.less │ │ │ │ └── workbench.tsx │ │ │ ├── less-variables.less │ │ │ ├── locale/ │ │ │ │ ├── en-US.json │ │ │ │ ├── index.ts │ │ │ │ └── zh-CN.json │ │ │ ├── register-defaults.ts │ │ │ ├── skeleton.ts │ │ │ ├── transducers/ │ │ │ │ ├── addon-combine.ts │ │ │ │ ├── parse-func.ts │ │ │ │ └── parse-props.ts │ │ │ ├── types.ts │ │ │ └── widget/ │ │ │ ├── dialog-dock.ts │ │ │ ├── dock.ts │ │ │ ├── index.ts │ │ │ ├── panel-dock.ts │ │ │ ├── panel.ts │ │ │ ├── stage.ts │ │ │ ├── utils.ts │ │ │ ├── widget-container.ts │ │ │ └── widget.ts │ │ ├── tests/ │ │ │ └── widget/ │ │ │ └── utils.test.ts │ │ └── tsconfig.json │ ├── engine/ │ │ ├── README-zh_CN.md │ │ ├── README.md │ │ ├── babel.config.js │ │ ├── build.json │ │ ├── build.plugin.js │ │ ├── build.test.json │ │ ├── build.umd.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── engine-core.ts │ │ │ ├── index.ts │ │ │ ├── inner-plugins/ │ │ │ │ ├── builtin-hotkey.ts │ │ │ │ ├── component-meta-parser.ts │ │ │ │ ├── default-context-menu.ts │ │ │ │ ├── default-panel-registry.tsx │ │ │ │ └── setter-registry.ts │ │ │ ├── locale/ │ │ │ │ ├── en-US.json │ │ │ │ ├── index.ts │ │ │ │ └── zh-CN.json │ │ │ └── modules/ │ │ │ ├── classes.ts │ │ │ ├── designer-types.ts │ │ │ ├── live-editing.ts │ │ │ ├── lowcode-types.ts │ │ │ ├── shell-model-factory.ts │ │ │ ├── skeleton-types.ts │ │ │ └── symbols.ts │ │ └── tsconfig.json │ ├── ignitor/ │ │ ├── babel.config.js │ │ ├── build.json │ │ ├── build.plugin.js │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── public/ │ │ │ └── index.html │ │ └── tsconfig.json │ ├── plugin-command/ │ │ ├── README.md │ │ ├── __tests__/ │ │ │ └── node-command.test.ts │ │ ├── build.json │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── package.json │ │ └── src/ │ │ ├── history-command.ts │ │ ├── index.ts │ │ └── node-command.ts │ ├── plugin-designer/ │ │ ├── .gitignore │ │ ├── build.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.scss │ │ │ └── index.tsx │ │ └── tsconfig.json │ ├── plugin-outline-pane/ │ │ ├── .gitignore │ │ ├── build.json │ │ ├── package.json │ │ └── src/ │ │ ├── README.md │ │ ├── controllers/ │ │ │ ├── pane-controller.ts │ │ │ ├── ric-shim.d.ts │ │ │ ├── tree-master.ts │ │ │ ├── tree-node.ts │ │ │ └── tree.ts │ │ ├── helper/ │ │ │ ├── consts.ts │ │ │ ├── dwell-timer.ts │ │ │ └── indent-track.ts │ │ ├── icons/ │ │ │ ├── arrow-right.tsx │ │ │ ├── cond.tsx │ │ │ ├── delete.tsx │ │ │ ├── eye-close.tsx │ │ │ ├── eye.tsx │ │ │ ├── filter.tsx │ │ │ ├── index.ts │ │ │ ├── lock.tsx │ │ │ ├── loop.tsx │ │ │ ├── outline.tsx │ │ │ ├── radio-active.tsx │ │ │ ├── radio.tsx │ │ │ ├── setting.tsx │ │ │ └── unlock.tsx │ │ ├── index.tsx │ │ ├── locale/ │ │ │ ├── en-US.json │ │ │ ├── index.ts │ │ │ └── zh-CN.json │ │ └── views/ │ │ ├── filter-tree.ts │ │ ├── filter.tsx │ │ ├── pane.tsx │ │ ├── style.less │ │ ├── tree-branches.tsx │ │ ├── tree-node.tsx │ │ ├── tree-title.tsx │ │ └── tree.tsx │ ├── react-renderer/ │ │ ├── README.md │ │ ├── build.json │ │ ├── build.test.json │ │ ├── build.umd.json │ │ ├── demo/ │ │ │ ├── compose.md │ │ │ ├── config/ │ │ │ │ ├── components/ │ │ │ │ │ ├── A.jsx │ │ │ │ │ ├── Div.jsx │ │ │ │ │ ├── Image.jsx │ │ │ │ │ ├── Text.jsx │ │ │ │ │ └── index.js │ │ │ │ ├── constants.js │ │ │ │ └── utils.js │ │ │ ├── dataSource.md │ │ │ ├── i18n.md │ │ │ ├── list.md │ │ │ ├── schemas/ │ │ │ │ ├── compose.js │ │ │ │ ├── dataSource.js │ │ │ │ ├── i18n.js │ │ │ │ ├── list.js │ │ │ │ └── table.js │ │ │ └── table.md │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── tests/ │ │ │ ├── __snapshots__/ │ │ │ │ └── index.test.tsx.snap │ │ │ ├── fixtures/ │ │ │ │ └── schema/ │ │ │ │ └── basic.ts │ │ │ └── index.test.tsx │ │ └── tsconfig.json │ ├── react-simulator-renderer/ │ │ ├── .babelrc │ │ ├── babel.config.js │ │ ├── build.json │ │ ├── build.plugin.js │ │ ├── build.test.json │ │ ├── build.umd.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── README.md │ │ │ ├── builtin-components/ │ │ │ │ ├── builtin-components.ts │ │ │ │ ├── leaf.tsx │ │ │ │ └── slot.tsx │ │ │ ├── host.ts │ │ │ ├── index.ts │ │ │ ├── locale/ │ │ │ │ ├── en-US.json │ │ │ │ ├── index.ts │ │ │ │ └── zh-CN.json │ │ │ ├── renderer-view.tsx │ │ │ ├── renderer.less │ │ │ ├── renderer.ts │ │ │ └── utils/ │ │ │ ├── get-client-rects.ts │ │ │ ├── is-dom-node.ts │ │ │ ├── misc.ts │ │ │ ├── react-find-dom-nodes.ts │ │ │ └── url.ts │ │ ├── test/ │ │ │ ├── schema/ │ │ │ │ └── basic.ts │ │ │ ├── src/ │ │ │ │ └── renderer/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── demo.test.tsx.snap │ │ │ │ └── demo.test.tsx │ │ │ └── utils/ │ │ │ ├── components.tsx │ │ │ └── host.ts │ │ └── tsconfig.json │ ├── renderer-core/ │ │ ├── babel.config.js │ │ ├── build.json │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── adapter/ │ │ │ │ └── index.ts │ │ │ ├── components/ │ │ │ │ ├── Div.tsx │ │ │ │ └── VisualDom/ │ │ │ │ ├── index.css │ │ │ │ └── index.tsx │ │ │ ├── context/ │ │ │ │ └── index.ts │ │ │ ├── hoc/ │ │ │ │ ├── index.tsx │ │ │ │ └── leaf.tsx │ │ │ ├── index.ts │ │ │ ├── renderer/ │ │ │ │ ├── addon.tsx │ │ │ │ ├── base.tsx │ │ │ │ ├── block.tsx │ │ │ │ ├── component.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── page.tsx │ │ │ │ ├── renderer.tsx │ │ │ │ └── temp.tsx │ │ │ ├── types/ │ │ │ │ └── index.ts │ │ │ └── utils/ │ │ │ ├── common.ts │ │ │ ├── data-helper.ts │ │ │ ├── index.ts │ │ │ ├── is-use-loop.ts │ │ │ ├── logger.ts │ │ │ └── request.ts │ │ ├── tests/ │ │ │ ├── adapter/ │ │ │ │ └── adapter.test.ts │ │ │ ├── fixtures/ │ │ │ │ ├── schema/ │ │ │ │ │ └── basic.ts │ │ │ │ └── unhandled-rejection.ts │ │ │ ├── hoc/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── leaf.test.tsx.snap │ │ │ │ └── leaf.test.tsx │ │ │ ├── mock/ │ │ │ │ ├── loop.ts │ │ │ │ ├── sample.ts │ │ │ │ └── styleMock.js │ │ │ ├── renderer/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── renderer.test.tsx.snap │ │ │ │ ├── base.test.tsx │ │ │ │ └── renderer.test.tsx │ │ │ ├── setup.ts │ │ │ └── utils/ │ │ │ ├── common.test.ts │ │ │ ├── components.tsx │ │ │ ├── data-helper.test.ts │ │ │ ├── is-use-loop.test.ts │ │ │ ├── node.ts │ │ │ ├── react-env-init.ts │ │ │ └── request.test.ts │ │ └── tsconfig.json │ ├── shell/ │ │ ├── build.json │ │ ├── build.test.json │ │ ├── package.json │ │ └── src/ │ │ ├── api/ │ │ │ ├── canvas.ts │ │ │ ├── command.ts │ │ │ ├── common.tsx │ │ │ ├── commonUI.tsx │ │ │ ├── config.ts │ │ │ ├── event.ts │ │ │ ├── hotkey.ts │ │ │ ├── index.ts │ │ │ ├── logger.ts │ │ │ ├── material.ts │ │ │ ├── plugins.ts │ │ │ ├── project.ts │ │ │ ├── setters.ts │ │ │ ├── simulator-host.ts │ │ │ ├── skeleton.ts │ │ │ └── workspace.ts │ │ ├── components/ │ │ │ └── context-menu.tsx │ │ ├── index.ts │ │ ├── model/ │ │ │ ├── active-tracker.ts │ │ │ ├── clipboard.ts │ │ │ ├── component-meta.ts │ │ │ ├── condition-group.ts │ │ │ ├── detecting.ts │ │ │ ├── document-model.ts │ │ │ ├── drag-object.ts │ │ │ ├── dragon.ts │ │ │ ├── drop-location.ts │ │ │ ├── editor-view.ts │ │ │ ├── history.ts │ │ │ ├── index.ts │ │ │ ├── locate-event.ts │ │ │ ├── modal-nodes-manager.ts │ │ │ ├── node-children.ts │ │ │ ├── node.ts │ │ │ ├── plugin-instance.ts │ │ │ ├── prop.ts │ │ │ ├── props.ts │ │ │ ├── resource.ts │ │ │ ├── selection.ts │ │ │ ├── setting-field.ts │ │ │ ├── setting-top-entry.ts │ │ │ ├── simulator-render.ts │ │ │ ├── skeleton-item.ts │ │ │ └── window.ts │ │ └── symbols.ts │ ├── types/ │ │ ├── .eslintignore │ │ ├── .prettierrc.js │ │ ├── CHANGELOG.md │ │ ├── build.json │ │ ├── package.json │ │ ├── src/ │ │ │ ├── activity.ts │ │ │ ├── assets.ts │ │ │ ├── code-intermediate.ts │ │ │ ├── code-result.ts │ │ │ ├── deprecated/ │ │ │ │ ├── index.ts │ │ │ │ ├── isActionContentObject.ts │ │ │ │ ├── isCustomView.ts │ │ │ │ ├── isDOMText.ts │ │ │ │ ├── isDynamicSetter.ts │ │ │ │ ├── isI18nData.ts │ │ │ │ ├── isJSBlock.ts │ │ │ │ ├── isJSExpression.ts │ │ │ │ ├── isJSFunction.ts │ │ │ │ ├── isJSSlot.ts │ │ │ │ ├── isLowCodeComponentType.ts │ │ │ │ ├── isNodeSchema.ts │ │ │ │ ├── isPlainObject.ts │ │ │ │ ├── isProCodeComponentType.ts │ │ │ │ ├── isProjectSchema.ts │ │ │ │ ├── isReactClass.ts │ │ │ │ ├── isReactComponent.ts │ │ │ │ ├── isSetterConfig.ts │ │ │ │ └── isTitleConfig.ts │ │ │ ├── editor.ts │ │ │ ├── event/ │ │ │ │ ├── index.ts │ │ │ │ ├── node.ts │ │ │ │ └── prop.ts │ │ │ ├── index.ts │ │ │ ├── shell/ │ │ │ │ ├── api/ │ │ │ │ │ ├── canvas.ts │ │ │ │ │ ├── command.ts │ │ │ │ │ ├── common.ts │ │ │ │ │ ├── commonUI.ts │ │ │ │ │ ├── event.ts │ │ │ │ │ ├── hotkey.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── logger.ts │ │ │ │ │ ├── material.ts │ │ │ │ │ ├── plugins.ts │ │ │ │ │ ├── project.ts │ │ │ │ │ ├── setters.ts │ │ │ │ │ ├── simulator-host.ts │ │ │ │ │ ├── skeleton.ts │ │ │ │ │ └── workspace.ts │ │ │ │ ├── enum/ │ │ │ │ │ ├── context-menu.ts │ │ │ │ │ ├── drag-object-type.ts │ │ │ │ │ ├── event-names.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── plugin-register-level.ts │ │ │ │ │ ├── prop-value-changed-type.ts │ │ │ │ │ ├── transform-stage.ts │ │ │ │ │ └── transition-type.ts │ │ │ │ ├── index.ts │ │ │ │ ├── model/ │ │ │ │ │ ├── active-tracker.ts │ │ │ │ │ ├── clipboard.ts │ │ │ │ │ ├── component-meta.ts │ │ │ │ │ ├── detecting.ts │ │ │ │ │ ├── document-model.ts │ │ │ │ │ ├── drag-object.ts │ │ │ │ │ ├── dragon.ts │ │ │ │ │ ├── drop-location.ts │ │ │ │ │ ├── editor-view.ts │ │ │ │ │ ├── editor.ts │ │ │ │ │ ├── engine-config.ts │ │ │ │ │ ├── exclusive-group.ts │ │ │ │ │ ├── history.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── locate-event.ts │ │ │ │ │ ├── modal-nodes-manager.ts │ │ │ │ │ ├── node-children.ts │ │ │ │ │ ├── node.ts │ │ │ │ │ ├── plugin-context.ts │ │ │ │ │ ├── plugin-instance.ts │ │ │ │ │ ├── preference.ts │ │ │ │ │ ├── prop.ts │ │ │ │ │ ├── props.ts │ │ │ │ │ ├── resource.ts │ │ │ │ │ ├── scroll-target.ts │ │ │ │ │ ├── scroller.ts │ │ │ │ │ ├── selection.ts │ │ │ │ │ ├── sensor.ts │ │ │ │ │ ├── setting-field.ts │ │ │ │ │ ├── setting-prop-entry.ts │ │ │ │ │ ├── setting-target.ts │ │ │ │ │ ├── setting-top-entry.ts │ │ │ │ │ ├── simulator-render.ts │ │ │ │ │ ├── skeleton-item.ts │ │ │ │ │ └── window.ts │ │ │ │ └── type/ │ │ │ │ ├── action-content-object.ts │ │ │ │ ├── active-target.ts │ │ │ │ ├── advanced.ts │ │ │ │ ├── app-config.ts │ │ │ │ ├── assets-json.ts │ │ │ │ ├── block-schema.ts │ │ │ │ ├── command.ts │ │ │ │ ├── component-action.ts │ │ │ │ ├── component-description.ts │ │ │ │ ├── component-instance.ts │ │ │ │ ├── component-metadata.ts │ │ │ │ ├── component-schema.ts │ │ │ │ ├── component-sort.ts │ │ │ │ ├── composite-value.ts │ │ │ │ ├── config-transducer.ts │ │ │ │ ├── configure.ts │ │ │ │ ├── container-schema.ts │ │ │ │ ├── context-menu.ts │ │ │ │ ├── custom-view.ts │ │ │ │ ├── disposable.ts │ │ │ │ ├── dom-text.ts │ │ │ │ ├── drag-any-object.ts │ │ │ │ ├── drag-node-data-object.ts │ │ │ │ ├── drag-node-object.ts │ │ │ │ ├── drag-object.ts │ │ │ │ ├── dynamic-props.ts │ │ │ │ ├── dynamic-setter.ts │ │ │ │ ├── editor-get-options.ts │ │ │ │ ├── editor-get-result.ts │ │ │ │ ├── editor-register-options.ts │ │ │ │ ├── editor-value-key.ts │ │ │ │ ├── editor-view-config.ts │ │ │ │ ├── editor-view.ts │ │ │ │ ├── engine-options.ts │ │ │ │ ├── field-config.ts │ │ │ │ ├── field-extra-props.ts │ │ │ │ ├── hotkey-callback-config.ts │ │ │ │ ├── hotkey-callback.ts │ │ │ │ ├── hotkey-callbacks.ts │ │ │ │ ├── i18n-map.ts │ │ │ │ ├── i8n-data.ts │ │ │ │ ├── icon-config.ts │ │ │ │ ├── icon-type.ts │ │ │ │ ├── index.ts │ │ │ │ ├── location.ts │ │ │ │ ├── metadata-transducer.ts │ │ │ │ ├── metadata.ts │ │ │ │ ├── node-data-type.ts │ │ │ │ ├── node-data.ts │ │ │ │ ├── node-instance.ts │ │ │ │ ├── node-schema.ts │ │ │ │ ├── npm-info.ts │ │ │ │ ├── npm.ts │ │ │ │ ├── on-change-options.ts │ │ │ │ ├── package.ts │ │ │ │ ├── page-schema.ts │ │ │ │ ├── plugin-config.ts │ │ │ │ ├── plugin-creater.ts │ │ │ │ ├── plugin-declaration-property.ts │ │ │ │ ├── plugin-declaration.ts │ │ │ │ ├── plugin-meta.ts │ │ │ │ ├── plugin-register-options.ts │ │ │ │ ├── plugin.ts │ │ │ │ ├── preference-value-type.ts │ │ │ │ ├── project-schema.ts │ │ │ │ ├── prop-change-options.ts │ │ │ │ ├── prop-config.ts │ │ │ │ ├── prop-types.ts │ │ │ │ ├── props-list.ts │ │ │ │ ├── props-map.ts │ │ │ │ ├── props-transducer.ts │ │ │ │ ├── reference.ts │ │ │ │ ├── registered-setter.ts │ │ │ │ ├── remote-component-description.ts │ │ │ │ ├── resource-list.ts │ │ │ │ ├── resource-type-config.ts │ │ │ │ ├── resource-type.ts │ │ │ │ ├── root-schema.ts │ │ │ │ ├── scrollable.ts │ │ │ │ ├── set-value-options.ts │ │ │ │ ├── setter-config.ts │ │ │ │ ├── setter-type.ts │ │ │ │ ├── simulator-renderer.ts │ │ │ │ ├── slot-schema.ts │ │ │ │ ├── snippet.ts │ │ │ │ ├── tip-config.ts │ │ │ │ ├── tip-content.ts │ │ │ │ ├── title-config.ts │ │ │ │ ├── title-content.ts │ │ │ │ ├── transformed-component-metadata.ts │ │ │ │ ├── value-type.ts │ │ │ │ ├── widget-base-config.ts │ │ │ │ └── widget-config-area.ts │ │ │ ├── shell-model-factory.ts │ │ │ └── utils.ts │ │ └── tsconfig.json │ ├── utils/ │ │ ├── build.json │ │ ├── build.test.json │ │ ├── jest.config.js │ │ ├── jest.setup.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── app-helper.ts │ │ │ ├── asset.ts │ │ │ ├── build-components.ts │ │ │ ├── check-prop-types.ts │ │ │ ├── check-types/ │ │ │ │ ├── index.ts │ │ │ │ ├── is-action-content-object.ts │ │ │ │ ├── is-basic-prop-type.ts │ │ │ │ ├── is-component-schema.ts │ │ │ │ ├── is-custom-view.ts │ │ │ │ ├── is-dom-text.ts │ │ │ │ ├── is-drag-any-object.ts │ │ │ │ ├── is-drag-node-data-object.ts │ │ │ │ ├── is-drag-node-object.ts │ │ │ │ ├── is-dynamic-setter.ts │ │ │ │ ├── is-function.ts │ │ │ │ ├── is-i18n-data.ts │ │ │ │ ├── is-isfunction.ts │ │ │ │ ├── is-jsblock.ts │ │ │ │ ├── is-jsexpression.ts │ │ │ │ ├── is-jsslot.ts │ │ │ │ ├── is-location-children-detail.ts │ │ │ │ ├── is-location-data.ts │ │ │ │ ├── is-lowcode-component-type.ts │ │ │ │ ├── is-lowcode-project-schema.ts │ │ │ │ ├── is-node-schema.ts │ │ │ │ ├── is-node.ts │ │ │ │ ├── is-object.ts │ │ │ │ ├── is-procode-component-type.ts │ │ │ │ ├── is-project-schema.ts │ │ │ │ ├── is-required-prop-type.ts │ │ │ │ ├── is-setter-config.ts │ │ │ │ ├── is-setting-field.ts │ │ │ │ └── is-title-config.ts │ │ │ ├── clone-deep.ts │ │ │ ├── clone-enumerable-property.ts │ │ │ ├── context-menu.scss │ │ │ ├── context-menu.tsx │ │ │ ├── create-content.ts │ │ │ ├── create-defer.ts │ │ │ ├── create-icon.tsx │ │ │ ├── css-helper.ts │ │ │ ├── cursor.css │ │ │ ├── cursor.ts │ │ │ ├── env.ts │ │ │ ├── get-prototype-of.ts │ │ │ ├── has-own-property.ts │ │ │ ├── index.ts │ │ │ ├── is-css-url.ts │ │ │ ├── is-element.ts │ │ │ ├── is-es-module.ts │ │ │ ├── is-form-event.ts │ │ │ ├── is-function.ts │ │ │ ├── is-object.ts │ │ │ ├── is-plain-object.ts │ │ │ ├── is-plugin-event-name.ts │ │ │ ├── is-react.ts │ │ │ ├── is-shaken.ts │ │ │ ├── logger.ts │ │ │ ├── misc.ts │ │ │ ├── navtive-selection.ts │ │ │ ├── node-helper.ts │ │ │ ├── schema.ts │ │ │ ├── script.ts │ │ │ ├── set-prototype-of.ts │ │ │ ├── shallow-equal.ts │ │ │ ├── svg-icon.tsx │ │ │ ├── transaction-manager.ts │ │ │ ├── unique-id.ts │ │ │ └── workspace.tsx │ │ ├── test/ │ │ │ └── src/ │ │ │ ├── __snapshots__/ │ │ │ │ ├── is-react.test.tsx.snap │ │ │ │ └── schema.test.ts.snap │ │ │ ├── build-components/ │ │ │ │ ├── buildComponents.test.tsx │ │ │ │ ├── getProjectUtils.test.ts │ │ │ │ └── getSubComponent.test.ts │ │ │ ├── check-prop-types.test.ts │ │ │ ├── check-types/ │ │ │ │ ├── is-action-content-object.test.ts │ │ │ │ ├── is-basic-prop-type.test.ts │ │ │ │ ├── is-custom-view.test.tsx │ │ │ │ ├── is-dom-text.test.ts │ │ │ │ ├── is-drag-any-object.test.ts │ │ │ │ ├── is-drag-node-data-object.test.ts │ │ │ │ ├── is-drag-node-object.test.ts │ │ │ │ ├── is-dynamic-setter.test.ts │ │ │ │ ├── is-i18n-data.test.ts │ │ │ │ ├── is-isfunction.test.ts │ │ │ │ ├── is-jsblock.test.ts │ │ │ │ ├── is-jsexpression.test.ts │ │ │ │ ├── is-jsslot.test.ts │ │ │ │ ├── is-location-children-detail.test.ts │ │ │ │ ├── is-location-data.test.ts │ │ │ │ ├── is-lowcode-component-type.test.ts │ │ │ │ ├── is-lowcode-project-schema.test.ts │ │ │ │ ├── is-node-schema.test.ts │ │ │ │ ├── is-node.test.ts │ │ │ │ ├── is-procode-component-type.test.ts │ │ │ │ ├── is-project-schema.test.ts │ │ │ │ ├── is-required-prop-type.test.ts │ │ │ │ ├── is-setter-config.test.ts │ │ │ │ ├── is-setting-field.test.ts │ │ │ │ └── is-title-config.test.ts │ │ │ ├── clone-deep.test.ts │ │ │ ├── clone-enumerable-property.test.ts │ │ │ ├── create-content.test.tsx │ │ │ ├── create-defer.test.ts │ │ │ ├── is-object.test.ts │ │ │ ├── is-react.test.tsx │ │ │ ├── is-shaken.test.ts │ │ │ ├── misc.test.ts │ │ │ ├── navtive-selection.test.ts │ │ │ ├── schema.test.ts │ │ │ ├── script.test.ts │ │ │ ├── svg-icon.test.tsx │ │ │ ├── transaction-manager.test.ts │ │ │ └── unique-id.test.ts │ │ └── tsconfig.json │ └── workspace/ │ ├── build.json │ ├── build.test.json │ ├── jest.config.js │ ├── package.json │ ├── src/ │ │ ├── context/ │ │ │ ├── base-context.ts │ │ │ └── view-context.ts │ │ ├── index.ts │ │ ├── inner-plugins/ │ │ │ └── webview.tsx │ │ ├── layouts/ │ │ │ └── workbench.tsx │ │ ├── less-variables.less │ │ ├── resource-type.ts │ │ ├── resource.ts │ │ ├── skeleton-context.ts │ │ ├── view/ │ │ │ ├── editor-view.tsx │ │ │ ├── resource-view.less │ │ │ ├── resource-view.tsx │ │ │ └── window-view.tsx │ │ ├── window.ts │ │ └── workspace.ts │ └── tsconfig.json ├── scripts/ │ ├── build.sh │ ├── create.sh │ ├── set-repo.js │ ├── setup-for-test.sh │ ├── setup-skip-build.sh │ ├── setup.js │ ├── setup.sh │ ├── start-server.sh │ ├── start.js │ ├── start.sh │ ├── sync-oss.js │ ├── sync.sh │ └── watchdog.js └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true quote_type = single [*.md] trim_trailing_whitespace = false ================================================ FILE: .eslintignore ================================================ # 忽略目录 node_modules test-cases test output build dist demo es lib tests .* ~* # 忽略文件 **/*.min.js **/*-min.js **/*.bundle.js ================================================ FILE: .eslintrc.js ================================================ module.exports = { extends: 'eslint-config-ali/typescript/react', parserOptions: { project: [], // for lint performance createDefaultProgram: false, // for lint performance }, rules: { 'react/no-multi-comp': 0, 'no-unused-expressions': 0, 'implicit-arrow-linebreak': 1, 'no-nested-ternary': 1, 'no-mixed-operators': 1, '@typescript-eslint/ban-types': 1, 'no-shadow': 1, 'no-prototype-builtins': 1, 'no-useless-constructor': 1, 'no-empty-function': 1, 'lines-between-class-members': 0, 'no-await-in-loop': 0, 'no-plusplus': 0, '@typescript-eslint/no-parameter-properties': 0, 'no-restricted-exports': ['error'], 'no-multi-assign': 1, 'no-dupe-class-members': 1, 'react/no-deprecated': 1, 'no-useless-escape': 1, 'brace-style': 1, '@typescript-eslint/no-inferrable-types': 0, 'no-proto': 0, 'prefer-const': 0, 'eol-last': 0, 'react/no-find-dom-node': 0, 'no-case-declarations': 0, '@typescript-eslint/indent': 0, 'import/no-cycle': 0, '@typescript-eslint/no-shadow': 0, '@typescript-eslint/method-signature-style': 0, '@typescript-eslint/consistent-type-assertions': 0, '@typescript-eslint/no-useless-constructor': 0, '@typescript-eslint/dot-notation': 0, // for lint performance '@typescript-eslint/restrict-plus-operands': 0, // for lint performance 'no-unexpected-multiline': 1, 'no-multiple-empty-lines': ['error', { max: 1 }], 'lines-around-comment': ['error', { beforeBlockComment: true, afterBlockComment: false, afterLineComment: false, allowBlockStart: true, }], 'comma-dangle': ['error', 'always-multiline'], '@typescript-eslint/member-ordering': [ 'error', { default: ['signature', 'field', 'constructor', 'method'] } ], '@typescript-eslint/no-unused-vars': ['error'], 'no-redeclare': 0, '@typescript-eslint/no-redeclare': 1, }, }; ================================================ FILE: .github/CODEOWNERS ================================================ # ref: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners # These owners will be the default owners for everything in # the repo. Unless a later match takes precedence * @liujuping @1ncounter /modules/material-parser @akirakai /modules/code-generator @qingniaotonghua ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report.md ================================================ --- name: Bug report / 提交 bug about: Create a report to help us improve / 提交一个好的 issue 帮助我们优化引擎,[引擎的 issue 说明](https://lowcode-engine.cn/site/community/issue) title: '' labels: '' assignees: '' --- ## **Describe the bug (required)** / **详细描述 bug(必填)** A clear and concise description of what the bug is. / 请提供清晰且精确的 bug 描述 --- ## **To Reproduce (required)** / **如何复现 bug?(必填,非常重要)** Steps to reproduce the behavior: / 详细复现步骤: --- English version example: 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error 中文版示例: 1. 打开 [demo](http://lowcode-engine.cn/demo); 2. 点击标题; 3. 在右侧修改标题内容为「修改后的标题」; 4. 渲染画布标题组件没有更新显示为「修改后的标题」; ## **Expected behavior (required)** / **预期行为(必填,非常重要)** A clear and concise description of what did you expect to happen. / 请清晰和精确的描述你预期的行为 --- ## **Screenshots (optional)** / **bug 截图(可选)** Sceenshots for further information. (If applicable.) / 一些有用的截图将会帮助我们更好的明确以及定位问题 --- ## **Environments (please complete the following information) (required):** / **请提供如下信息(必填)** - AliLowCodeEngine version: [e.g. 1.0.0] / 低代码引擎版本 - AliLowCodeEngineExt version: [e.g. 1.0.0] / 低代码引擎扩展包版本 - Browser [e.g. chrome, safari] / 浏览器版本 - materials / plugins / tools / 其他物料 / 插件 / 工具链版本 > (this information can be collected via [the manual plugin](https://img.alicdn.com/imgextra/i1/O1CN0115zonY1IsgbkZ2ir7_!!6000000000949-2-tps-3066-1650.png) / 版本信息可[通过低代码用户手册插件收集](https://img.alicdn.com/imgextra/i1/O1CN0115zonY1IsgbkZ2ir7_!!6000000000949-2-tps-3066-1650.png)) ## **Additional context (optional)** / **更多额外信息(可选)** Any other context of the problem here. / 可以追加更多的额外信息,帮助定位问题 ================================================ FILE: .github/workflows/check base branch.yml ================================================ name: Check Base Branch on: pull_request: types: [opened] jobs: code-review: name: Check runs-on: ubuntu-latest steps: # 判断用户是否有写仓库权限 - name: 'Check User Permission' uses: 'lannonbr/repo-permission-check-action@2.0.0' with: permission: 'write' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: 'Check base branch name is develop or not' if: github.event.pull_request.base.ref != 'develop' # check the target branch if it's master uses: actions-cool/issues-helper@v2 with: actions: 'create-comment' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.pull_request.number }} body: | 感谢你的 PR,根据引擎的 [研发协作流程](https://lowcode-engine.cn/site/docs/participate/flow),请将目标合入分支设置为 **develop**。 Thanks in advance, according to the [Contribution Guideline](https://lowcode-engine.cn/site/docs/participate/flow), please set the base branch to **develop**. @${{ github.event.pull_request.user.login }} ================================================ FILE: .github/workflows/ci.yml ================================================ name: Node CI on: push: branches: - main pull_request: branches: - main jobs: upload-designer-codecov: runs-on: ubuntu-latest # if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test designer run: cd packages/designer && npm run test:cov && cd ../.. - name: Upload designer coverage to Codecov uses: codecov/codecov-action@v3 with: # working-directory: packages/designer directory: ./packages/designer/coverage token: ${{ secrets.CODECOV_TOKEN }} name: designer fail_ci_if_error: true verbose: true upload-renderer-core: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test renderer-core run: cd packages/renderer-core && npm run test:cov && cd ../.. - name: Upload renderer-core coverage to Codecov uses: codecov/codecov-action@v3 with: # working-directory: packages/designer directory: ./packages/renderer-core/coverage token: ${{ secrets.CODECOV_TOKEN }} name: renderer-core fail_ci_if_error: true verbose: true upload-react-simulator-renderer: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test react-simulator-renderer run: cd packages/react-simulator-renderer && npm run test:cov && cd ../.. - name: Upload react-simulator-renderer coverage to Codecov uses: codecov/codecov-action@v3 with: # working-directory: packages/designer directory: ./packages/react-simulator-renderer/coverage token: ${{ secrets.CODECOV_TOKEN }} name: react-simulator-renderer fail_ci_if_error: true verbose: true upload-code-generator: runs-on: ubuntu-latest # if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test code-generator run: cd modules/code-generator && npm i && npm run build && npm run test:cov && cd ../.. - name: Upload code-generator coverage to Codecov uses: codecov/codecov-action@v3 with: # working-directory: packages/designer directory: ./modules/code-generator/coverage token: ${{ secrets.CODECOV_TOKEN }} name: code-generator fail_ci_if_error: true verbose: true ================================================ FILE: .github/workflows/cov packages.yml ================================================ name: coverage on: pull_request: paths: - 'packages/**' - '!packages/**.md' jobs: cov-designer: runs-on: ubuntu-latest # skip fork's PR, otherwise it fails while making a comment if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - uses: ArtiomTr/jest-coverage-report-action@v2 with: working-directory: packages/designer test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json package-manager: yarn annotations: none cov-renderer-core: runs-on: ubuntu-latest # skip fork's PR, otherwise it fails while making a comment if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - uses: ArtiomTr/jest-coverage-report-action@v2 with: working-directory: packages/renderer-core test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json package-manager: yarn annotations: none cov-react-simulator-renderer: runs-on: ubuntu-latest # skip fork's PR, otherwise it fails while making a comment if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - uses: ArtiomTr/jest-coverage-report-action@v2 with: working-directory: packages/react-simulator-renderer test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json package-manager: yarn annotations: none cov-utils: runs-on: ubuntu-latest # skip fork's PR, otherwise it fails while making a comment if: ${{ github.event.pull_request.head.repo.full_name == 'alibaba/lowcode-engine' }} steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - uses: ArtiomTr/jest-coverage-report-action@v2 with: working-directory: packages/utils test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json package-manager: yarn annotations: none ================================================ FILE: .github/workflows/help wanted.yml ================================================ name: Help Wanted on: issues: types: [labeled] jobs: reply-helper: runs-on: ubuntu-latest steps: - name: help wanted if: github.event.label.name == 'help wanted' uses: actions-cool/issues-helper@v2 with: actions: 'create-comment' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | Hello @${{ github.event.issue.user.login }}. We totally like your proposal/feedback, PR wanted。 你好 @${{ github.event.issue.user.login }},我们完全同意你的提议/反馈,欢迎 PR。 ================================================ FILE: .github/workflows/insufficient information.yml ================================================ name: Insufficient Info on: issues: types: [labeled] jobs: reply-helper: runs-on: ubuntu-latest steps: - name: insufficient information if: github.event.label.name == 'insufficient information' uses: actions-cool/issues-helper@v2 with: actions: 'create-comment' token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | 你好 @${{ github.event.issue.user.login }},由于缺乏必要的信息(如 bug 重现步骤、引擎版本信息 等),无法定位问题,请按照 [issue bug 模板](https://github.com/alibaba/lowcode-engine/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) 补全信息,也可以通过阅读 [引擎的 issue 说明](https://lowcode-engine.cn/site/community/issue) 了解什么类型的 issue 可以获得更好、更快的支持。 ================================================ FILE: .github/workflows/pr comment by chatgpt.yml ================================================ name: Pull Request Review By ChatGPT on: pull_request: types: [opened, synchronize, reopened] jobs: code-review: name: Code Review runs-on: ubuntu-latest steps: # 判断用户是否有写仓库权限 - name: 'Check User Permission' uses: 'lannonbr/repo-permission-check-action@2.0.0' with: permission: 'write' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: opensumi/actions/.github/actions/code-review@main env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} ================================================ FILE: .github/workflows/pre build.yml ================================================ name: Pre Build on: push: paths: - 'packages/**' - '!packages/**.md' pull_request: paths: - 'packages/**' - '!packages/**.md' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Install dependencies and setup run: npm install && npm run setup - name: Build run: npm run build - name: Check build status run: | if [ $? -eq 0 ]; then echo "Build succeeded!" else echo "Build failed!" exit 1 fi ================================================ FILE: .github/workflows/publish docs.yml ================================================ name: Update and Publish Docs on: push: branches: - develop paths: - 'docs/docs/**' workflow_dispatch: jobs: publish-docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: ref: 'develop' node-version: '16' registry-url: 'https://registry.npmjs.org' - run: cd docs && npm install - run: | cd docs npm version patch git config --local user.email "action@github.com" git config --local user.name "GitHub Action" git add package.json git commit -m "chore(docs): publish documentation" git push - run: cd docs && npm run build && npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version run: echo "version=$(node -p "require('./docs/package.json').version")" >> $GITHUB_OUTPUT comment-pr: needs: publish-docs runs-on: ubuntu-latest steps: - name: Comment on PR if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true uses: actions/github-script@v4 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | github.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: '🚀 New version has been released: ' + '${{ needs.publish-docs.outputs.version }}' }) ================================================ FILE: .github/workflows/publish engine beta.yml ================================================ name: Publish Engine Beta on: push: branches: - 'release/[0-9]+.[0-9]+.[0-9]+-beta' paths: - 'packages/**' jobs: publish-engine: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '14' registry-url: 'https://registry.npmjs.org' - run: npm install && npm run setup - run: | npm run build git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - run: npm run pub:prerelease env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT ================================================ FILE: .github/workflows/publish engine.yml ================================================ name: Publish Engine on: workflow_dispatch: inputs: publishCommand: description: 'publish command' required: true jobs: publish-engine: runs-on: ubuntu-latest if: >- contains(github.ref, 'refs/heads/release/') && (github.actor == '1ncounter' || github.actor == 'liujuping') steps: - uses: actions/checkout@v2 - name: Setup Node.js uses: actions/setup-node@v2 with: node-version: '16' registry-url: 'https://registry.npmjs.org' - run: npm install && npm run setup - run: | npm run build git config --local user.email "action@github.com" git config --local user.name "GitHub Action" - run: npm run ${{ github.event.inputs.publishCommand }} env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Get version id: get_version run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT ================================================ FILE: .github/workflows/stale.yml ================================================ name: 'Close stale issues and PRs' on: schedule: - cron: '30 1 * * *' jobs: stale: runs-on: ubuntu-latest steps: - uses: actions/stale@v4 with: stale-issue-message: 'This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 2 days.' stale-pr-message: 'This PR is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 2 days.' close-issue-message: 'This issue was closed because it has been stalled for 10 days with no activity.' close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.' days-before-issue-stale: 10 days-before-issue-close: 10 days-before-pr-stale: 10 days-before-pr-close: 10 exempt-issue-labels: 'bug,enhancement,good first issue,help wanted,WIP,discussion,documentation,later,material' stale-issue-label: 'stale' stale-pr-label: 'stale' exempt-all-assignee: true ================================================ FILE: .github/workflows/test modules.yml ================================================ name: Lint & Test (Mods) on: push: paths: - 'modules/**' - '!modules/**.md' pull_request: paths: - 'modules/**' - '!modules/**.md' jobs: lint: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i - name: lint run: npm run lint:modules test-code-generator: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd modules/code-generator && npm i && npm run build && npm test ================================================ FILE: .github/workflows/test packages.yml ================================================ name: Lint & Test (Pkgs) on: push: paths: - 'packages/**' - '!packages/**.md' pull_request: paths: - 'packages/**' - '!packages/**.md' jobs: lint: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: lint run: npm run lint test-designer: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/designer && npm test test-editor-skeleton: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/editor-skeleton && npm test test-renderer-core: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/renderer-core && npm test test-react-simulator-renderer: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/react-simulator-renderer && npm test test-utils: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/utils && npm test test-editor-core: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/editor-core && npm test test-plugin-command: runs-on: ubuntu-latest steps: - name: checkout uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: '14' - name: install run: npm i && npm run setup:skip-build - name: test run: cd packages/plugin-command && npm test ================================================ FILE: .gitignore ================================================ # project custom build dist packages/*/lib/ packages/*/es/ packages/*/dist/ packages/*/output/ packages/demo/ package-lock.json yarn.lock pnpm-lock.yaml deploy-space/packages deploy-space/.env # 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 coverage-all # 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 # codealike codealike.json .node .must.config.js ================================================ FILE: .prettierrc.js ================================================ module.exports = { printWidth: 100, tabWidth: 2, semi: true, singleQuote: true, trailingComma: 'all', }; ================================================ FILE: .stylelintignore ================================================ # 忽略目录 node_modules/ build/ dist/ # 忽略文件 **/*.min.css **/*-min.css **/*.bundle.css ================================================ FILE: .stylelintrc.js ================================================ module.exports = { extends: 'stylelint-config-ali', rules: { "selector-max-id": 2 } }; ================================================ FILE: CONTRIBUTOR.md ================================================ 十分感谢参与贡献过低代码引擎的小伙伴们,下面名单按字母排序: - [albertxiao1994](https://github.com/albertxiao1994) - [alex-mm](https://github.com/alex-mm) - [alvarto](https://github.com/alvarto) - [alvinhui](https://github.com/alvinhui) - [boycgit](https://github.com/boycgit) - [chenmingjia](https://github.com/chenmingjia) - [Clarence-pan](https://github.com/Clarence-pan) - [hujiulong](https://github.com/hujiulong) - [hzd822](https://github.com/hzd822) - [JackLian](https://github.com/JackLian) - [jayjliang](https://github.com/jayjliang) - [Jeffery-Young](https://github.com/Jeffery-Young) - [jinggk](https://github.com/jinggk) - [junlonghuo](https://github.com/junlonghuo) - [leoyuan](https://github.com/leoyuan) - [liujuping](https://github.com/liujuping) - [lqy978599280](https://github.com/lqy978599280) - [markyun](https://github.com/markyun) - [mark-ck](https://github.com/mark-ck) - [mochen666](https://github.com/mochen666) - [tsy77](https://github.com/tsy77) - [yanbingbing](https://github.com/yanbingbing) - [Ychangqing](https://github.com/Ychangqing) - [yize](https://github.com/yize) - [youluna](https://github.com/youluna) - [ibreathebsb](https://github.com/ibreathebsb) 如果您贡献过低代码引擎,但是没有看到您的名字,为我们的疏忽感到抱歉。欢迎您通过 PR 补充上自己的名字。 ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2021 Alibaba Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: abc.json ================================================ { "name": "lowcode-engine", "assets": { "type": "command", "command": { "cmd": [ "./scripts/deploy.sh $BUILD_DEST" ] } } } ================================================ FILE: babel.config.js ================================================ module.exports = { plugins: [ ['@babel/plugin-proposal-decorators', { legacy: true }], [require.resolve('@babel/plugin-proposal-class-properties'), { loose: true }], ], }; ================================================ FILE: commitlint.config.js ================================================ module.exports = { extends: ['ali'], }; ================================================ FILE: deploy-space/lerna.json ================================================ { "version": "independent", "npmClient": "yarn", "registry": "http://registry.npm.alibaba-inc.com", "useWorkspaces": true, "packages": [ "packages/*" ] } ================================================ FILE: deploy-space/package.json ================================================ { "private": true, "workspaces": { "packages": [ "packages/*" ], "nohoist": [ "**/css-modules-typescript-loader", "**/@alife/theme-lowcode-*" ] }, "dependencies": { "tslib": "^1.11.1", "typescript": "^3.8.3" } } ================================================ FILE: deploy-space/static/index.html ================================================ LowCodeEngine Editor DEMO
================================================ FILE: deploy-space/static/preview.html ================================================ LowCodeEngine Editor DEMO
================================================ FILE: deploy-space/tsconfig.json ================================================ { "compilerOptions": { "declaration": false, "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": false, // 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": false, // 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" }, "exclude": ["**/test", "**/lib", "**/es", "node_modules"] } ================================================ FILE: docs/.gitignore ================================================ # Dependencies /node_modules # Production /build # Generated files .docusaurus .cache-loader # Misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log* ================================================ FILE: docs/README.md ================================================ # Low-Code Engine 文档中心(site) This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator. ### 安装 ``` $ yarn ``` ### 本地开发 ``` $ yarn start ``` This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. ### 构建 ``` $ yarn build ``` ### 部署 ```bash 1. npm run build 2. npm publish # 记得改下版本号,比如 1.0.1 # 发布完后执行 tnpm syncOss 同步到 uipaas CDN 3. tnpm syncOss 4. 更新 diamond 版本 1.0.1 5. lowcode-engine.cn 站点生效 ``` ## 功能 - [x] 支持本地离线搜搜 - [x] 版本化文档管理 - [x] 离线静态部署 - [x] 主题(fork 宜搭开发者中心) ## 使用文档 https://docusaurus.io/zh-CN/docs/docs-introduction ================================================ FILE: docs/babel.config.js ================================================ module.exports = { presets: [require.resolve('@docusaurus/core/lib/babel/preset')], }; ================================================ FILE: docs/community/issue.md ================================================ --- title: 关于引擎的 issue 说明 sidebar_position: 2 --- > 提交地址:[https://github.com/alibaba/lowcode-engine/issues](https://github.com/alibaba/lowcode-engine/issues) ### 提交前必读 由于引擎项目复杂,很多问题在复现和沟通上无法花费太多时间,需要大家尽力将复现步骤说明白。 ![image.png](./img/you-think.png) **你以为的 issue** ![image.png](./img/i-see.png) **我们看到的 issue** 为了更好的进行协作,对引擎 issue 的处理定了一些处理的优先级。请大家认真阅读 Orz. - 【支持快】通过线上 Demo 地址 + 控制台输入 API 可复现。 - 【支持快】通过线上 Demo + 导入 schema 可复现 - 【支持稍慢】通过线上 Demo + 完整操作步骤可复现 - 【支持稍慢】通过线上 Demo + 变更代码可复现,并清楚的说明变更代码的位置和内容 - 【支持慢】有完整的项目地址,下载下来可直接安装依赖并启动复现的 - 【支持慢】需求类型的由于人力有限,欢迎大家 PR,如能讲清楚背景上下文和场景,项目维护团队更容易给出方案建议或方向指引。 - 【不保证提供支持】其他 - 只有标题没有复现步骤 - 复现步骤不清晰 - 和引擎无关的 ### 不同优先级的示例 #### 【支持快】通过线上 Demo 地址 + 控制台输入 API 可复现。 **示例** ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01np6ARb1KnJFOELjXg_!!6000000001208-2-tps-3322-1862.png) 复现步骤: - 打开线上 demo - 在控制台输入 ```json // 当前 doc const doc = window.AliLowCodeEngine.project.currentDocument // 新建 doc 并成功切换 window.AliLowCodeEngine.project.openDocument({ componentName: 'Page' }); // 无法切换回来 window.AliLowCodeEngine.project.openDocument('docl4xkca5b') ``` 预期效果: - 使用 openDocument 可以正常的切换回原来的 doc #### 【支持快】通过线上 demo + 导入 schema 可复现 步骤: - 使用线上 demo - 导入下面的 schema - schema 代码/schema zip 压缩包 - 页面效果如下 期望: - 页面中的 xxx 部分和预期不符合,期望的效果是 xxx #### 【支持稍慢】通过线上 demo + 完整操作步骤可复现 **示例** 1.使用 antd 组件 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN019dFe4Y24SDKbmpbdw_!!6000000007389-2-tps-3584-1812.png) 2.拖拽这个组件 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN0109SdxO1OtxSbpLn4Q_!!6000000001764-2-tps-3584-1802.png) 3.配置该属性值为 100 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WeVXpW1HBny0VmQcS_!!6000000000720-2-tps-3584-1800.png) 期望效果: - 组件同配置一致 #### 【支持稍慢】通过线上 demo + 变更代码可复现,并清楚的说明变更代码的位置和内容 **示例** ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01FL0Urq1tl1pLcYhJH_!!6000000005941-2-tps-1892-754.png) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WIpR9V1i363wzyFzi_!!6000000004356-2-tps-1917-778.png) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01ZDkR3n1MNmP2uk15t_!!6000000001423-2-tps-1836-253.png) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01OKzt1Z28b9WZIbM6B_!!6000000007950-2-tps-1912-914.png) #### 【支持慢】有完整的项目地址,下载下来可直接安装依赖并启动复现的 由于完整的项目中有很多冗余的信息,这部分排查起来十分耗时且困难。不推荐使用改方式。 #### 【不保证提供支持】其他 ##### 只有标题没有复现步骤 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN017rO2gR1YKpEgIMBjh_!!6000000003041-2-tps-2520-1020.png) ##### 复现步骤不清晰 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01vtHi5z225CC7aFVS2_!!6000000007068-2-tps-3584-1666.png) ##### 和引擎无关的 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01KxqT9M1vcu25xJHFP_!!6000000006194-2-tps-2548-1430.png) ### 扩展阅读 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/~sgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。(此段参考 [antd](https://github.com/ant-design/ant-design)) ================================================ FILE: docs/config/navbar.js ================================================ /** * 此配置的修改,如未生效,可以重新启动下即可 */ module.exports = { title: '', logo: { alt: 'LowCode-Engine', src: 'https://img.alicdn.com/imgextra/i2/O1CN01uv6vu822RBCSYLro2_!!6000000007116-55-tps-139-26.svg', srcDark: 'https://tianshu.alicdn.com/052a190e-c961-4afe-aa4c-49ee9722952d.svg', }, items: [ { type: 'doc', docId: 'guide/quickStart/intro', position: 'left', label: '文档', }, { type: 'doc', docId: 'api/index', position: 'left', label: 'API', }, { type: 'doc', docId: 'specs/lowcode-spec', position: 'left', label: '协议', }, { type: 'doc', docId: 'faq/index', position: 'left', label: 'FAQ', }, { type: 'doc', docId: 'article/index', position: 'left', label: '文章', }, { type: 'doc', docId: 'video/index', position: 'left', label: '视频', }, { type: 'doc', docId: 'demoUsage/intro', position: 'left', label: 'Demo 使用文档', }, { to: '/community/issue', position: 'left', label: '社区', activeBaseRegex: '/community/', }, // 版本切换,如需,这里开启即可 // { // type: 'docsVersionDropdown', // position: 'right', // dropdownActiveClassDisabled: true, // }, // { { href: 'https://github.com/alibaba/lowcode-engine', position: 'right', className: 'header-github-link', 'aria-label': 'GitHub repository', }, { type: 'doc', docId: 'participate/index', position: 'right', label: '参与贡献', }, { type: 'search', position: 'right', }, ], }; ================================================ FILE: docs/config/sidebars.js ================================================ /* * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ const getDocsFromDir = require('../scripts/getDocsFromDir'); module.exports = { // 手动配置的导航 // guide: [ // 'guide/quickStart/intro', // 'guide/quickStart/start', // { // type: 'category', // label: 'FAQ', // collapsed: false, // items: getDocsFromDir('guide/quickStart/faq'), // }, // ], /** * 根据当前目录自动生成导航配置 */ guide: [ [ { type: 'category', label: '入门', collapsed: false, items: getDocsFromDir('guide/quickStart'), }, { type: 'category', label: '创建编辑器', collapsed: false, items: getDocsFromDir('guide/create'), }, { type: 'category', label: '扩展编辑器', collapsed: false, items: getDocsFromDir('guide/expand/editor', [{ dir: 'guide/expand/editor/parts', label: 'Parts·造物' }]), }, { type: 'category', label: '扩展运行时', collapsed: false, items: getDocsFromDir('guide/expand/runtime'), }, { type: 'category', label: '设计原理', collapsed: false, items: getDocsFromDir('guide/design'), }, { type: 'category', label: '附录', collapsed: false, items: [ { type: 'link', label: '更新日志', href: 'https://github.com/alibaba/lowcode-engine/releases', }, ...getDocsFromDir('guide/appendix'), { type: 'category', label: '预置设置器详情', items: getDocsFromDir('guide/appendix/setterDetails'), }, ], }, { type: 'link', label: '技术白皮书', href: 'https://developer.aliyun.com/ebook/7507', }, ], ], api: [ { type: 'autogenerated', dirName: 'api', }, ], specs: [ { type: 'autogenerated', dirName: 'specs', }, ], faq: [ { type: 'autogenerated', dirName: 'faq', }, ], participate: [ { type: 'autogenerated', dirName: 'participate', }, ], demoUsage: [ { type: 'autogenerated', dirName: 'demoUsage', }, ], }; ================================================ FILE: docs/config/sidebarsCommunity.js ================================================ module.exports = { community: [ { type: 'autogenerated', dirName: '.', }, { type: 'link', label: '生态资源', href: 'https://github.com/lowcode-workspace/awesome-lowcode-engine', }, ], }; ================================================ FILE: docs/docs/api/canvas.md ================================================ --- title: canvas - 画布 API sidebar_position: 10 --- > **@types** [IPublicApiCanvas](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/canvas.ts)
> **@since** v1.1.0 ## 模块简介 通过该模块可以触达对画布拖拽相关的一些能力。 ## 变量 ### dragon 获取拖拽操作对象的实例 `@type {IPublicModelDragon | null}` 相关类型:[IPublicModelDragon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/dragon.ts) ### activeTracker 获取活动追踪器实例 `@type {IPublicModelActiveTracker | null}` 相关类型:[IPublicModelActiveTracker](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/active-tracker.ts) ### isInLiveEditing 是否处于 LiveEditing 状态 `@type {boolean}` ### clipboard 全局剪贴板实例 `@type {IPublicModelClipboard}` 相关类型:[IPublicModelClipboard](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/clipboard.ts) ## 方法 ### createLocation 创建一个文档插入位置对象,该对象用来描述一个即将插入的节点在文档中的位置 ```typescript /** * 创建一个文档插入位置对象,该对象用来描述一个即将插入的节点在文档中的位置 * create a drop location for document, drop location describes a location in document * @since v1.1.0 */ createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation; ``` ### createScroller 创建一个滚动控制器 Scroller,赋予一个视图滚动的基本能力, ```typescript /** * 创建一个滚动控制器 Scroller,赋予一个视图滚动的基本能力, * a Scroller is a controller that gives a view (IPublicTypeScrollable) the ability scrolling * to some cordination by api scrollTo. * * when a scroller is inited, will need to pass is a scrollable, which has a scrollTarget. * and when scrollTo(options: { left?: number; top?: number }) is called, scroller will * move scrollTarget`s top-left corner to (options.left, options.top) that passed in. * @since v1.1.0 */ createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller; ``` ### createScrollTarget 创建一个 ScrollTarget,与 Scroller 一起发挥作用,详见 [createScroller](#createscroller) 中的描述 ```typescript /** * 创建一个 ScrollTarget,与 Scroller 一起发挥作用,详见 createScroller 中的描述 * this works with Scroller, refer to createScroller`s description * @since v1.1.0 */ createScrollTarget(shell: HTMLDivElement): IPublicModelScrollTarget; ``` ================================================ FILE: docs/docs/api/command.md ================================================ --- title: command - 指令 API sidebar_position: 10 --- ## 模块概览 该模块使得与命令系统的交互成为可能,提供了一种全面的方式来处理、执行和管理应用程序中的命令。 ## 接口 ### IPublicApiCommand 与命令交互的接口。它提供了注册、注销、执行和管理命令的方法。 ## 方法 ### registerCommand 注册一个新命令及其处理函数。 ``` typescriptCopy code /** * 注册一个新的命令及其处理程序。 * @param command {IPublicTypeCommand} - 要注册的命令。 */ registerCommand(command: IPublicTypeCommand): void; ``` ### unregisterCommand 注销一个已存在的命令。 ``` typescriptCopy code /** * 注销一个已存在的命令。 * @param name {string} - 要注销的命令的名称。 */ unregisterCommand(name: string): void; ``` ### executeCommand 根据名称和提供的参数执行命令,确保参数符合命令的定义。 ``` typescriptCopy code /** * 根据名称和提供的参数执行命令。 * @param name {string} - 要执行的命令的名称。 * @param args {IPublicTypeCommandHandlerArgs} - 命令的参数。 */ executeCommand(name: string, args?: IPublicTypeCommandHandlerArgs): void; ``` ### batchExecuteCommand 批量执行命令,在所有命令执行后进行重绘,历史记录中只记录一次。 ``` typescriptCopy code /** * 批量执行命令,随后进行重绘,历史记录中只记录一次。 * @param commands {Array} - 命令对象的数组,包含名称和可选参数。 */ batchExecuteCommand(commands: { name: string; args?: IPublicTypeCommandHandlerArgs }[]): void; ``` ### listCommands 列出所有已注册的命令。 ``` typescriptCopy code /** * 列出所有已注册的命令。 * @returns {IPublicTypeListCommand[]} - 已注册命令的数组。 */ listCommands(): IPublicTypeListCommand[]; ``` ### onCommandError 为命令执行过程中的错误注册错误处理回调函数。 ``` typescriptCopy code /** * 为命令执行过程中的错误注册一个回调函数。 * @param callback {(name: string, error: Error) => void} - 错误处理的回调函数。 */ onCommandError(callback: (name: string, error: Error) => void): void; ``` ================================================ FILE: docs/docs/api/common.md ================================================ --- title: common - 通用 API sidebar_position: 10 --- > **@types** [IPublicApiCommon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/common.ts)
> **@since** v1.0.0 ## 模块简介 通用模块里包含除了几大核心模块 API 之外的所有 API,比如通用 utils、面板扩展相关 等。 > 高能预警:之所以叫 skeletonCabin / designerCabin 跟兼容上一个版本的引擎有关系。若有必要,后面将用更有意义的命名空间来组织这些 API。 ## 变量 #### utils 通用 utils,详见下方方法签名 相关类型:[IPublicApiCommonUtils](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/common.ts) #### skeletonCabin 面板扩展相关,详见下方方法签名 ## 方法 ### utils #### isNodeSchema 是否为合法的 schema 结构 ```typscript /** * 是否为合法的 schema 结构 * check if data is valid NodeSchema * * @param {*} data * @returns {boolean} */ isNodeSchema(data: any): boolean; ``` #### isFormEvent 是否为表单事件类型 ```typescript /** * 是否为表单事件类型 * check if e is a form event * @param {(KeyboardEvent | MouseEvent)} e * @returns {boolean} */ isFormEvent(e: KeyboardEvent | MouseEvent): boolean; ``` #### getNodeSchemaById 从 schema 结构中查找指定 id 节点 ```typescript /** * 从 schema 结构中查找指定 id 节点 * get node schema from a larger schema with node id * @param {IPublicTypeNodeSchema} schema * @param {string} nodeId * @returns {(IPublicTypeNodeSchema | undefined)} */ getNodeSchemaById( schema: IPublicTypeNodeSchema, nodeId: string, ): IPublicTypeNodeSchema | undefined; ``` 相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) #### executeTransaction 批处理事务,用于优化特定场景的性能 ```typescript /** * 批处理事务,用于优化特定场景的性能 * excute something in a transaction for performence * * @param {() => void} fn * @param {IPublicEnumTransitionType} type * @since v1.0.16 */ executeTransaction(fn: () => void, type: IPublicEnumTransitionType): void; ``` **@since v1.0.16** **示例** ```typescript import { common } from '@alilc/lowcode-engine'; import { IPublicEnumTransitionType } from '@alilc/lowcode-types'; common.utils.startTransaction(() => { node1.setProps(); node2.setProps(); node3.setProps(); // ... }, IPublicEnumTransitionType.repaint); ``` #### getConvertedExtraKey props key 转化工具 ```typescript getConvertedExtraKey(key: string): string ``` **@since v1.0.17** #### createIntl i18n 相关工具 ```typescript /** * i18n 相关工具 * i18n tools * * @param {(string | object)} instance * @returns {{ * intlNode(id: string, params?: object): ReactNode; * intl(id: string, params?: object): string; * getLocale(): string; * setLocale(locale: string): void; * }} * @since v1.0.17 */ createIntl(instance: string | object): { intlNode(id: string, params?: object): ReactNode; intl(id: string, params?: object): string; getLocale(): string; setLocale(locale: string): void; }; ``` **@since v1.0.17** **示例** ```typescript import { common } from '@alilc/lowcode-engine'; import enUS from './en-US.json'; import zhCN from './zh-CN.json'; const { intl, getLocale, setLocale } = common.utils.createIntl({ 'en-US': enUS, 'zh-CN': zhCN, }); ``` #### intl i18n 转换方法 ```typescript /** * i18n 转换方法 */ intl(data: IPublicTypeI18nData | string, params?: object): string; ``` **示例** ``` const title = common.utils.intl(node.title) ``` ### skeletonCabin #### Workbench 编辑器框架 View ```typescript /** * 编辑器框架 View * get Workbench Component */ get Workbench(): Component; ``` ================================================ FILE: docs/docs/api/commonUI.md ================================================ --- title: commonUI - UI 组件库 sidebar_position: 10 --- ## 简介 CommonUI API 是一个专为低代码引擎设计的组件 UI 库,使用它开发的插件,可以保证在不同项目和主题切换中能够保持一致性和兼容性。 ## 组件列表 ### Tip 提示组件 | 参数 | 说明 | 类型 | 默认值 | |-----------|--------------|---------------------------------------|--------| | className | className | string (optional) | | | children | tip 的内容 | IPublicTypeI18nData \| ReactNode | | | direction | tip 的方向 | 'top' \| 'bottom' \| 'left' \| 'right' | | ### HelpTip 带 help icon 的提示组件 | 参数 | 说明 | 类型 | 默认值 | |-----------|--------|-----------------------------------|--------| | help | 描述 | IPublicTypeHelpTipConfig | | | direction | 方向 | IPublicTypeTipConfig['direction'] | 'top' | | size | 方向 | IconProps['size'] | 'small'| ### Title 标题组件 | 参数 | 说明 | 类型 | 默认值 | |-----------|------------|-----------------------------|--------| | title | 标题内容 | IPublicTypeTitleContent | | | className | className | string (optional) | | | onClick | 点击事件 | () => void (optional) | | ### ContextMenu | 参数 | 说明 | 类型 | 默认值 | |--------|----------------------------------------------------|------------------------------------|--------| | menus | 定义上下文菜单的动作数组 | IPublicTypeContextMenuAction[] | | | children | 组件的子元素 | React.ReactElement[] | | **IPublicTypeContextMenuAction Interface** | 参数 | 说明 | 类型 | 默认值 | |------------|--------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|----------------------------------------| | name | 动作的唯一标识符
Unique identifier for the action | string | | | title | 显示的标题,可以是字符串或国际化数据
Display title, can be a string or internationalized data | string \| IPublicTypeI18nData (optional) | | | type | 菜单项类型
Menu item type | IPublicEnumContextMenuType (optional) | IPublicEnumContextMenuType.MENU_ITEM | | action | 点击时执行的动作,可选
Action to execute on click, optional | (nodes: IPublicModelNode[]) => void (optional) | | | items | 子菜单项或生成子节点的函数,可选,仅支持两级
Sub-menu items or function to generate child node, optional | Omit[] \| ((nodes: IPublicModelNode[]) => Omit[]) (optional) | | | condition | 显示条件函数
Function to determine display condition | (nodes: IPublicModelNode[]) => boolean (optional) | | | disabled | 禁用条件函数,可选
Function to determine disabled condition, optional | (nodes: IPublicModelNode[]) => boolean (optional) | | **ContextMenu 示例** ```typescript const App = () => { const menuItems: IPublicTypeContextMenuAction[] = [ { name: 'a', title: '选项 1', action: () => console.log('选项 1 被点击'), }, { name: 'b', title: '选项 2', action: () => console.log('选项 2 被点击'), }, ]; const ContextMenu = ctx.commonUI.ContextMenu; return (
右键点击这里
); }; export default App; ``` **ContextMenu.create 示例** ```typescript const App = () => { const menuItems: IPublicTypeContextMenuAction[] = [ { name: 'a', title: '选项 1', action: () => console.log('选项 1 被点击'), }, { name: 'b', title: '选项 2', action: () => console.log('选项 2 被点击'), }, ]; const ContextMenu = ctx.commonUI.ContextMenu; return (
{ ContextMenu.create(menuItems, e); }}>点击这里
); }; export default App; ``` ### Balloon 详细文档: [Balloon Documentation](https://fusion.design/pc/component/balloon) ### Breadcrumb 详细文档: [Breadcrumb Documentation](https://fusion.design/pc/component/breadcrumb) ### Button 详细文档: [Button Documentation](https://fusion.design/pc/component/button) ### Card 详细文档:[Card Documentation](https://fusion.design/pc/component/card) ### Checkbox 详细文档:[Checkbox Documentation](https://fusion.design/pc/component/checkbox) ### DatePicker 详细文档:[DatePicker Documentation](https://fusion.design/pc/component/datepicker) ### Dialog 详细文档:[Dialog Documentation](https://fusion.design/pc/component/dialog) ### Dropdown 详细文档:[Dropdown Documentation](https://fusion.design/pc/component/dropdown) ### Form 详细文档:[Form Documentation](https://fusion.design/pc/component/form) ### Icon 详细文档:[Icon Documentation](https://fusion.design/pc/component/icon) 引擎默认主题支持的 icon 列表:https://fusion.design/64063/component/icon?themeid=20133 ### Input 详细文档:[Input Documentation](https://fusion.design/pc/component/input) ### Loading 详细文档:[Loading Documentation](https://fusion.design/pc/component/loading) ### Message 详细文档:[Message Documentation](https://fusion.design/pc/component/message) ### Overlay 详细文档:[Overlay Documentation](https://fusion.design/pc/component/overlay) ### Pagination 详细文档:[Pagination Documentation](https://fusion.design/pc/component/pagination) ### Radio 详细文档:[Radio Documentation](https://fusion.design/pc/component/radio) ### Search 详细文档:[Search Documentation](https://fusion.design/pc/component/search) ### Select 详细文档:[Select Documentation](https://fusion.design/pc/component/select) ### SplitButton 详细文档:[SplitButton Documentation](https://fusion.design/pc/component/splitbutton) ### Step 详细文档:[Step Documentation](https://fusion.design/pc/component/step) ### Switch 详细文档:[Switch Documentation](https://fusion.design/pc/component/switch) ### Tab 详细文档:[Tab Documentation](https://fusion.design/pc/component/tab) ### Table 详细文档:[Table Documentation](https://fusion.design/pc/component/table) ### Tree 详细文档:[Tree Documentation](https://fusion.design/pc/component/tree) ### TreeSelect 详细文档:[TreeSelect Documentation](https://fusion.design/pc/component/treeselect) ### Upload 详细文档:[Upload Documentation](https://fusion.design/pc/component/upload) ### Divider 详细文档:[Divider Documentation](https://fusion.design/pc/component/divider) ## 说明 如果需要其他组件,可以提 issue 给我们。 ================================================ FILE: docs/docs/api/config.md ================================================ --- title: config - 配置 API sidebar_position: 5 --- > **@types** [IPublicModelEngineConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/engine-config.ts)
> **@since** v1.0.0 ## 模块简介 配置模块,负责配置的读、写等操作。 ## 方法 ### get 获取指定 key 的值 ```typescript /** * 获取指定 key 的值 * get value by key * @param key * @param defaultValue * @returns */ get(key: string, defaultValue?: any): any; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.get('keyA', true); config.get('keyB', { a: 1 }); ``` ### set 设置指定 key 的值 ```typescript /** * 设置指定 key 的值 * set value for certain key * @param key * @param value */ set(key: string, value: any): void; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.set('keyC', 1); ``` ### has 判断指定 key 是否有值 ```typescript /** * 判断指定 key 是否有值 * check if config has certain key configed * @param key * @returns */ has(key: string): boolean; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.has('keyD'); ``` ### setConfig 批量设值,set 的对象版本 ```typescript /** * 批量设值,set 的对象版本 * set multiple config key-values * @param config */ setConfig(config: { [key: string]: any }): void; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.setConfig({ keyA: false, keyB: 2 }); ``` ### getPreference 获取全局 Preference 管理器,用于管理全局浏览器侧用户 Preference,如 Panel 是否钉住 ```typescript /** * 获取全局 Preference, 用于管理全局浏览器侧用户 Preference,如 Panel 是否钉住 * get global user preference manager, which can be use to store * user`s preference in user localstorage, such as a panel is pinned or not. * @returns {IPublicModelPreference} * @since v1.1.0 */ getPreference(): IPublicModelPreference; ``` 相关类型:[IPublicModelPreference](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/preference.ts) **@since v1.1.0** 示例 ```javascript import { config } from '@alilc/lowcode-engine'; const panelName = 'outline-master-pane'; // 设置大纲树面板钉住,在大纲树下次重新打开时生效 config.getPreference().set(`${panelName}-pinned-status-isFloat`, false, 'skeleton') ``` ## 事件 ### onceGot 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值 注:此函数返回 Promise 实例 ```typescript /** * 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值 * 注:此函数返回 Promise 实例,只会执行(fullfill)一次 * wait until value of certain key is set, will only be * triggered once. * @param key * @returns */ onceGot(key: string): Promise; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.onceGot('keyA').then(value => { console.log(`The value of keyA is ${value}`); }); // or const value = await config.onceGot('keyA'); ``` ### onGot 获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用 ```typescript /** * 获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用 * set callback for event of value set for some key * this will be called each time the value is set * @param key * @param fn * @returns */ onGot(key: string, fn: (data: any) => void): () => void; ``` **示例** ```typescript import { config } from '@alilc/lowcode-engine'; config.onGot('keyA', (value) => { console.log(`The value of keyA is ${value}`); }); const.set('keyA', 1); // 'The value of keyA is 1' const.set('keyA', 2); // 'The value of keyA is 2' ``` ================================================ FILE: docs/docs/api/configOptions.md ================================================ --- title: config options - 配置列表 sidebar_position: 5 --- > **@types** [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts)
## 配置方式 #### init API ```javascript import { init } from '@alilc/lowcode-engine'; init(document.getElementById('engine'), { enableCondition: false, }); ``` [**init api**](./init) #### config API ```javascript import { config } from '@alilc/lowcode-engine'; config.set('enableCondition', false) ``` [**config api**](./config) ## 配置详情 > 源码详见 [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts) ### 画布 #### locale - 语言 `@type {string}`、`@default {zh-CN}` 语言 #### device - 设备类型 `@type {string}` 引擎默认支持的 device 类型有 `default`、`mobile`、`iphonex`、`iphone6`。 插件 `@alilc/lowcode-plugin-simulator-select` 支持的 device 类型有 `default`、`phone`、`tablet`、`desktop`。 如果需要自定义的 device 类型,需要补充 device 类型对应的样式,例如 device 为 phone 时,需要补充样式如下: ```css .lc-simulator-device-phone { top: 16px; bottom: 16px; left: 50%; width: 375px; transform: translateX(-50%); margin: auto; } ``` #### deviceClassName `@type {string}` 指定初始化的 deviceClassName,挂载到画布的顶层节点上 #### appHelper 与 react-renderer 的 appHelper 一致,https://lowcode-engine.cn/site/docs/guide/expand/runtime/renderer#apphelper #### enableCondition `@type {boolean}` 是否开启 condition 的能力,默认在设计器中不管 condition 是啥都正常展示 #### disableAutoRender `@type {boolean}` `@default {false}` 关闭画布自动渲染,在资产包多重异步加载的场景有效 #### renderEnv - 渲染器类型 渲染器类型 `@type {string}`、`@default {react}` #### simulatorUrl `@type {string[]}` 设置 simulator 相关的 url #### enableStrictNotFoundMode `@type {boolean}` `@default {false}` 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 ### 编排 #### focusNodeSelector - 指定根组件 配置指定节点为根组件 类型定义 ```typescript focusNodeSelector?: (rootNode: IPublicModelNode) => Node; ``` #### supportVariableGlobally - 全局变量配置 `@type {boolean}` `@default {false}` 设置所有属性支持变量配置 开启拖拽组件时,即将被放入的容器是否有视觉反馈 #### customizeIgnoreSelectors - 点击忽略 配置画布中,需要屏蔽点击事件的元素,即配置的元素默认点击行为均不生效。 类型定义: ```typescript customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]; ``` 默认值: ```javascript () => { return [ '.next-input-group', '.next-checkbox-group', '.next-checkbox-wrapper', '.next-date-picker', '.next-input', '.next-month-picker', '.next-number-picker', '.next-radio-group', '.next-range', '.next-range-picker', '.next-rating', '.next-select', '.next-switch', '.next-time-picker', '.next-upload', '.next-year-picker', '.next-breadcrumb-item', '.next-calendar-header', '.next-calendar-table', '.editor-container', // 富文本组件 ] } ``` #### enableCanvasLock `@type {boolean}` `@default {false}` 打开画布的锁定操作 #### enableLockedNodeSetting `@type {boolean}` `@default {false}` 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效 #### enableMouseEventPropagationInCanvas `@type {boolean}` `@default {false}` 鼠标事件(mouseover、mouseleave、mousemove)在画布中是否允许冒泡,默认不允许。 #### enableReactiveContainer `@type {boolean}` `@default {false}` #### enableContextMenu - 开启右键菜单 `@type {boolean}` `@default {false}` 是否开启右键菜单 #### disableDetecting `@type {boolean}` `@default {false}` 关闭拖拽组件时的虚线响应,性能考虑 #### disableDefaultSettingPanel `@type {boolean}` `@default {false}` 禁止默认的设置面板 #### disableDefaultSetters `@type {boolean}` `@default {false}` 禁止默认的设置器 #### stayOnTheSameSettingTab `@type {boolean}` `@default {false}` 当选中节点切换时,是否停留在相同的设置 tab 上 #### hideSettingsTabsWhenOnlyOneItem `@type {boolean}` `@default {false}` 是否在只有一个 item 的时候隐藏设置 tabs #### hideComponentAction `@type {boolean}` `@default {false}` 隐藏设计器辅助层 #### thisRequiredInJSE `@type {boolean}` `@default {true}` JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false ### 应用级设计器 #### enableWorkspaceMode - 应用级设计模式 `@type {boolean}` `@default {false}` 开启应用级设计模式 #### enableAutoOpenFirstWindow `@type {boolean}` `@default {true}` 应用级设计模式下,自动打开第一个窗口 #### workspaceEmptyComponent 应用级设计模式下,当窗口为空时,展示的占位组件 ### 定制组件 #### faultComponent 组件渲染错误时的占位组件 #### notFoundComponent 组件不存在时的占位组件 #### loadingComponent - loading 组件 自定义 loading 组件 ### 插件 #### defaultSettingPanelProps 内置设置面板插件的 panelProps #### defaultOutlinePaneProps 内置大纲树面板插件的 panelProps ### 其他 #### enableStrictPluginMode `@type {boolean}` 开启严格插件模式,默认值:STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过 engineOptions 传递自定义配置项 #### requestHandlersMap 数据源引擎的请求处理器映射 #### customPluginTransducer 插件处理中间件,方便提供插件调试能力 类型定义 ```typescript customPluginTransducer: async (originPlugin: IPublicTypePlugin, ctx: IPublicModelPluginContext, options): IPublicTypePlugin; ``` #### defaultOutlinePaneProps `@type {object}` 大纲树插件面板默认 props ================================================ FILE: docs/docs/api/event.md ================================================ --- title: event - 事件 API sidebar_position: 10 --- > **@types** [IPublicApiEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/event.ts)
> **@since** v1.0.0 ## 模块简介 负责事件处理 API,支持自定义监听事件、触发事件。 ## 方法 ### on 监听事件 ```typescript /** * 监听事件 * add monitor to a event * @param event 事件名称 * @param listener 事件回调 */ on(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### prependListener 监听事件,会在其他回调函数之前执行 ```typescript /** * 监听事件,会在其他回调函数之前执行 * @param event 事件名称 * @param listener 事件回调 */ prependListener(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### off 取消监听事件 ```typescript /** * 取消监听事件 * cancel a monitor from a event * @param event 事件名称 * @param listener 事件回调 */ off(event: string, listener: (...args: any[]) => void): void; ``` ### emit 触发事件 ```typescript /** * 触发事件 * emit a message for a event * @param event 事件名称 * @param args 事件参数 * @returns */ emit(event: string, ...args: any[]): void; ``` ## 使用示例 ### 事件触发和监听 ```typescript const eventName = 'eventName'; // 事件监听 // 插件中发出的事件,默认以 `common` 为前缀,监听时需要注意下 event.on(`common:${eventName}`); // 触发事件 event.emit(eventName); ``` ### setter 和 setter/plugin 之间的联动 在 A setter 中进行事件注册: ```typescript import { event } from '@alilc/lowcode-engine'; const SETTER_NAME = 'SetterA'; class SetterA extends React.Component { componentDidMount() { // 这里由于面板上会有多个 setter,使用 field.id 来标记 setter 名 this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`; event.on(`common:${this.emitEventName}.bindEvent`, this.bindEvent) } bindEvent = (eventName) => { // do someting } componentWillUnmount() { // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多 event.off(`common:${this.emitEventName}.bindEvent`, this.bindEvent) } } ``` 在 B setter 中触发事件,来完成通信: ```typescript import { event } from '@alilc/lowcode-engine'; class SetterB extends React.Component { bindFunction = () => { const { field, value } = this.props; // 这里展示的和插件进行通信,事件规则是插件名 + 方法 event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); } } ``` ================================================ FILE: docs/docs/api/hotkey.md ================================================ --- title: hotkey - 快捷键 API sidebar_position: 10 --- > **@types** [IPublicApiHotkey](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/hotkey.ts)
> **@since** v1.0.0 ## 模块简介 绑定快捷键 API,可以自定义项目快捷键使用。 ## 方法 ### bind 绑定快捷键 ```typescript /** * 绑定快捷键 * bind hotkey/hotkeys, * @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等 * @param callback 回调函数 * @param action * @returns */ bind( combos: string[] | string, callback: IPublicTypeHotkeyCallback, action?: string, ): IPublicTypeDisposable; ``` 相关 types - [IPublicTypeHotkeyCallback](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/hotkey-callback.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ## 使用示例 ### 基础示例 ```typescript hotkey.bind('command+s', (e) => { e.preventDefault(); // command+s 快捷键按下时需要执行的逻辑 }); ``` ### 同时绑定多个快捷键 ```typescript hotkey.bind(['command+s', 'command+c'], (e) => { e.preventDefault(); // command+s 或者 command+c 快捷键按下时需要执行的逻辑 }); ``` ### 保存快捷键配置 ```typescript import { hotkey, } from '@alilc/lowcode-engine'; function saveSchema(schema) { // 保存 schema 相关操作 } const saveSampleHotKey = (ctx: IPublicModelPluginContext) => { return { name: 'saveSample', async init() { hotkey.bind('command+s', (e) => { e.preventDefault(); saveSchema(); }); }, }; } saveSampleHotKey.pluginName = 'saveSampleHotKey'; plugins.register(saveSampleHotKey); ``` ================================================ FILE: docs/docs/api/index.md ================================================ --- title: API 总览 sidebar_position: 0 --- 引擎提供的公开 API 分为`命名空间`和`模型`两类,其中`命名空间`用于聚合一大类的 API,`模型`为各 API 涉及到的对象模型。 ## 命名空间 引擎直接提供以下几大类 API - skeleton 面板 API - material 物料 API - project 模型 API - simulator-host 模拟器 API - hotkey 快捷键 API - setters 设置器 API - event 事件 API - config 配置 API - common 通用 API - logger 日志 API - init 初始化 API ## 模型 以下模型通过前面的 API 以返回值等形式间接透出。 - document-model 文档 - node 节点 - node-children 节点孩子 - props 属性集 - prop 属性 - setting-field 设置属性 - setting-top-entry 设置属性集 - component-meta 物料元数据 - selection 画布选中 - detecting 画布 hover - history 操作历史 - window 低代码设计器窗口模型 - detecting 画布节点悬停模型 - modal-nodes-manager 模态节点管理器模型 - plugin-instance 插件实例 - drop-location 拖拽放置位置模型 ## API 设计约定 一些 API 设计约定: 1. 所有 API 命名空间都按照 variables / functions / events 来组织 2. 事件(events)的命名格式为:on[Will|Did]VerbNoun?,参考 [https://code.visualstudio.com/api/references/vscode-api#events](https://code.visualstudio.com/api/references/vscode-api#events) 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数 4. 对于属性的导出,统一用 .xxx 的 getter 模式,(尽量)不使用 .getXxx() ## experimental 说明此模块处于公测阶段, API 可能会发生改变. ================================================ FILE: docs/docs/api/init.md ================================================ --- title: init - 初始化 API sidebar_position: 0 --- > **@since** v1.0.0 ## 模块简介 提供 init 等方法 ## 方法 #### init 初始化引擎 **方法定义** ```typescript function init(container?: Element, options?: IPublicTypeEngineOptions): void ``` [**初始化引擎配置参数列表**](./configOptions) ## 使用示例 ```typescript import { init } from '@alilc/lowcode-engine'; init(document.getElementById('engine'), { enableCondition: false, }); ``` ### 默认打开移动端画布 ```typescript import { init } from '@alilc/lowcode-engine'; init({ device: 'mobile', }); ``` ### 使用 utils 第三方工具扩展 ```json import { init } from '@alilc/lowcode-engine'; init({ device: 'mobile', appHelper: { utils: { xxx: () => {console.log('123')}, } } }); ``` 在引擎中即可这样使用。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01FWvu051OxAEYrHBy5_!!6000000001771-2-tps-3584-1796.png) ================================================ FILE: docs/docs/api/logger.md ================================================ --- title: logger - 日志 API sidebar_position: 10 --- > **@types** [IPublicApiLogger](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/logger.ts)
> **@since** v1.0.0 ## 模块简介 引擎日志模块,可以按照 **日志级别 **和** 业务类型 **两个维度来定制日志。 > 注:日志级别可以通过 url query 动态调整,详见下方[查看示例](#查看示例)。
> 参考 [zen-logger](https://web.npm.alibaba-inc.com/package/zen-logger) 实现进行封装 ## 方法 日志记录方法 ```typescript /** * debug info */ debug(...args: any | any[]): void; /** * normal info output */ info(...args: any | any[]): void; /** * warning info output */ warn(...args: any | any[]): void; /** * error info output */ error(...args: any | any[]): void; /** * log info output */ log(...args: any | any[]): void; ``` ## 输出示例 ```typescript import { Logger } from '@alilc/lowcode-utils'; const logger = new Logger({ level: 'warn', bizName: 'myPlugin:moduleA' }); logger.log('Awesome Low-Code Engine'); ``` ## 查看示例 开启查看方式: - 方式 1:所有 logger 创建时会有默认输出的 level, 默认为 warn , 即只展示 warn , error - 方式 2:url 上追加 __logConf__进行开启,示例如下 ``` https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn // 开启所有 bizName的 warn 和 error https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=debug // 开启所有 bizName的 debug, log, info, warn 和 error https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=log // 开启所有 bizName的 log, info, warn 和 error https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|* // 同 __logConf__=warn https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|bizName // 开启 bizName 的 debug, log, info, warn 和 error https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|partOfBizName // 开启 bizName like '%partOfBizName%' 的 debug, log, info, warn 和 error ``` ================================================ FILE: docs/docs/api/material.md ================================================ --- title: material - 物料 API sidebar_position: 10 --- > **@types** [IPublicApiMaterial](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/material.ts)
> **@since** v1.0.0 ## 模块简介 负责物料相关的 API,包括资产包、设计器辅助层、物料元数据和物料元数据管道函数。 ## 变量 ### componentsMap 获取组件 map 结构 ```typescript /** * 获取组件 map 结构 * get map of components */ get componentsMap(): { [key: string]: IPublicTypeNpmInfo | ComponentType | object } ; ``` 相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts) ## 方法 ### 资产包 #### setAssets 设置「[资产包](/site/docs/specs/lowcode-spec#2-协议结构)」结构 ```typescript /** * 设置「资产包」结构 * set data for Assets * @returns void */ setAssets(assets: IPublicTypeAssetsJson): void; ``` 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) **示例** 直接在项目中引用 npm 包 ```javascript import { material } from '@alilc/lowcode-engine'; import assets from '@alilc/mc-assets-/assets.json'; material.setAssets(assets); ``` 通过接口动态引入资产包 ```typescript import { material, plugins } from '@alilc/lowcode-engine'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; // 动态加载 assets plugins.register((ctx: IPublicModelPluginContext) => { return { name: 'ext-assets', async init() { try { // 将下述链接替换为您的物料描述地址即可。 const res = await window.fetch('https://fusion.alicdn.com/assets/default@0.1.95/assets.json'); const assets = await res.text(); material.setAssets(assets); } catch (err) { console.error(err); }; }, }; }).catch(err => console.error(err)); ``` #### getAssets 获取「资产包」结构 ```typescript /** * 获取「资产包」结构 * get AssetsJson data * @returns IPublicTypeAssetsJson */ getAssets(): IPublicTypeAssetsJson; ``` 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) **示例** ```typescript import { material } from '@alilc/lowcode-engine'; material.getAssets(); ``` #### loadIncrementalAssets 加载增量的「资产包」结构,该增量包会与原有的合并 ```typescript /** * 加载增量的「资产包」结构,该增量包会与原有的合并 * load Assets incrementally, and will merge this with exiting assets * @param incrementalAssets * @returns */ loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): Promise; ``` 相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts) **示例** ```typescript import { material } from '@alilc/lowcode-engine'; import assets1 from '@alilc/mc-assets-/assets.json'; import assets2 from '@alilc/mc-assets-/assets.json'; material.setAssets(assets1); material.loadIncrementalAssets(assets2); ``` 更新特定物料的描述文件 ```typescript import { material } from '@alilc/lowcode-engine'; material.loadIncrementalAssets({ version: '', components: [ { "componentName": 'Button', "props": [{ name: 'new', title: 'new', propType: 'string' }] } ], }) ``` ### 设计器辅助层 #### addBuiltinComponentAction 在设计器辅助层增加一个扩展 action ```typescript /** * 在设计器辅助层增加一个扩展 action * add an action button in canvas context menu area * @param action */ addBuiltinComponentAction(action: IPublicTypeComponentAction): void; ``` 相关类型:[IPublicTypeComponentAction](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/component-action.ts) **示例** 新增设计扩展位,并绑定事件 ```typescript import { material } from '@alilc/lowcode-engine'; material.addBuiltinComponentAction({ name: 'myIconName', content: { icon: () => 'x', title: 'hover title', action(node) { console.log('myIconName 扩展位被点击'); } }, important: true, condition: true, }); ``` ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01jDbN7B1KfWVzJ16tw_!!6000000001191-2-tps-230-198.png) #### removeBuiltinComponentAction 移除设计器辅助层的指定 action ```typescript /** * 移除设计器辅助层的指定 action * remove a builtin action button from canvas context menu area * @param name */ removeBuiltinComponentAction(name: string): void; ``` ##### 内置设计器辅助 name - remove:删除 - hide:隐藏 - copy:复制 - lock:锁定,不可编辑 - unlock:解锁,可编辑 **示例** ```typescript import { material } from '@alilc/lowcode-engine'; material.removeBuiltinComponentAction('myIconName'); ``` #### modifyBuiltinComponentAction 修改已有的设计器辅助层的指定 action ```typescript /** * 修改已有的设计器辅助层的指定 action * modify a builtin action button in canvas context menu area * @param actionName * @param handle */ modifyBuiltinComponentAction( actionName: string, handle: (action: IPublicTypeComponentAction) => void, ): void; ``` 相关类型:[IPublicTypeComponentAction](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/component-action.ts) ##### 内置设计器辅助 name - remove:删除 - hide:隐藏 - copy:复制 - lock:锁定,不可编辑 - unlock:解锁,可编辑 **示例** 给原始的 remove 扩展时间添加执行前后的日志 ```typescript import { material } from '@alilc/lowcode-engine'; material.modifyBuiltinComponentAction('remove', (action) => { const originAction = action.content.action; action.content.action = (node) => { console.log('before reomve!'); originAction(node); console.log('after remove!'); } }); ``` ### 右键菜单项 #### addContextMenuOption 添加右键菜单项 ```typescript /** * 添加右键菜单项 * @param action */ addContextMenuOption(action: IPublicTypeContextMenuAction): void; ``` 示例 ```typescript import { IPublicEnumContextMenuType } from '@alilc/lowcode-types'; material.addContextMenuOption({ name: 'parentItem', title: 'Parent Item', condition: (nodes) => true, items: [ { name: 'childItem1', title: 'Child Item 1', action: (nodes) => console.log('Child Item 1 clicked', nodes), condition: (nodes) => true }, // 分割线 { type: IPublicEnumContextMenuType.SEPARATOR name: 'separator.1' } // 更多子菜单项... ] }); ``` #### removeContextMenuOption 删除特定右键菜单项 ```typescript /** * 删除特定右键菜单项 * @param name */ removeContextMenuOption(name: string): void; ``` #### adjustContextMenuLayout 调整右键菜单项布局,每次调用都会覆盖之前注册的调整函数,只有最后注册的函数会被应用。 ```typescript /** * 调整右键菜单项布局 * @param actions */ adjustContextMenuLayout(fn: (actions: IPublicTypeContextMenuItem[]) => IPublicTypeContextMenuItem[]): void; ``` **示例** 通过 adjustContextMenuLayout 补充分割线 ```typescript material.adjustContextMenuLayout((actions: IPublicTypeContextMenuAction) => { const names = ['a', 'b']; const newActions = []; actions.forEach(d => { newActions.push(d); if (names.include(d.name)) { newActions.push({ type: 'separator' }) } }); return newActions }) ``` ### 物料元数据 #### getComponentMeta 获取指定名称的物料元数据 ```typescript /** * 获取指定名称的物料元数据 * get component meta by component name * @param componentName * @returns */ getComponentMeta(componentName: string): IPublicModelComponentMeta | null; ``` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) **示例** ```typescript import { material } from '@alilc/lowcode-engine'; material.getComponentMeta('Input'); ``` #### getComponentMetasMap 获取所有已注册的物料元数据 ```typescript /** * 获取所有已注册的物料元数据 * get map of all component metas * @returns */ getComponentMetasMap(): Map; ``` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) **示例** ```typescript import { material } from '@alilc/lowcode-engine'; material.getComponentMetasMap(); ``` #### refreshComponentMetasMap 刷新 componentMetasMap,可触发模拟器里的 components 重新构建 **@since v1.1.7** ```typescript refreshComponentMetasMap(): void; ``` ### 物料元数据管道函数 #### registerMetadataTransducer 注册物料元数据管道函数,在物料信息初始化时执行。 ```typescript /** * 注册物料元数据管道函数,在物料信息初始化时执行。 * register transducer to process component meta, which will be * excuted during component meta`s initialization * @param transducer * @param level * @param id */ registerMetadataTransducer( transducer: IPublicTypeMetadataTransducer, level?: number, id?: string | undefined ): void; ``` **示例** 给每一个组件的配置添加高级配置面板,其中有一个是否渲染配置项 ```typescript import { material } from '@alilc/lowcode-engine' function addonCombine(metadata: TransformedComponentMetadata) { const { componentName, configure = {} } = metadata; const advanceGroup = []; const combined: FieldConfig[] = []; advanceGroup.push({ name: getConvertedExtraKey('condition'), title: { type: 'i18n', 'zh-CN': '是否渲染', 'en-US': 'Condition' }, defaultValue: true, setter: [ { componentName: 'BoolSetter', }, { componentName: 'VariableSetter', }, ], extraProps: { display: 'block', }, }); combined.push({ name: '#advanced', title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' }, items: advanceGroup, }); return { ...metadata, configure: { ...configure, combined, }, }; } material.registerMetadataTransducer(addonCombine, 1, 'parse-func'); ``` 删除高级 Tab ```typescript import { material } from '@alilc/lowcode-engine'; import { IPublicTypeFieldConfig } from '@alilc/lowcode-types'; material.registerMetadataTransducer((transducer) => { const combined: IPublicTypeFieldConfig[] = []; transducer.configure.combined?.forEach(d => { if (d.name !== '#advanced') { combined.push(d); } }); return { ...transducer, configure: { ...transducer.configure, combined, } }; }, 111, 'parse-func'); ``` #### getRegisteredMetadataTransducers 获取所有物料元数据管道函数 ```typescript /** * 获取所有物料元数据管道函数 * get all registered metadata transducers * @returns {IPublicTypeMetadataTransducer[]} */ getRegisteredMetadataTransducers(): IPublicTypeMetadataTransducer[]; ``` **示例** ```typescript import { material } from '@alilc/lowcode-engine' material.getRegisteredMetadataTransducers(); ``` ## 事件 ### onChangeAssets 监听 assets 变化的事件 ```typescript /** * 监听 assets 变化的事件 * add callback for assets changed event * @param fn */ onChangeAssets(fn: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **示例** ```typescript import { material } from '@alilc/lowcode-engine'; material.onChangeAssets(() => { console.log('asset changed'); }); ``` ================================================ FILE: docs/docs/api/model/_category_.json ================================================ { "label": "模型定义 Models", "position": 100, "collapsed": false, "collapsible": true } ================================================ FILE: docs/docs/api/model/clipboard.md ================================================ --- title: Clipboard sidebar_position: 14 --- > **@types** [IPublicModelClipboard](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/clipboard.ts)
> **@since** v1.1.0 ## 方法 ### setData 给剪贴板赋值 ```typescript /** * 给剪贴板赋值 * set data to clipboard * * @param {*} data * @since v1.1.0 */ setData(data: any): void; ``` ### waitPasteData 设置剪贴板数据设置的回调 ```typescript /** * 设置剪贴板数据设置的回调 * set callback for clipboard provide paste data * * @param {KeyboardEvent} keyboardEvent * @param {(data: any, clipboardEvent: ClipboardEvent) => void} cb * @since v1.1.0 */ waitPasteData( keyboardEvent: KeyboardEvent, cb: (data: any, clipboardEvent: ClipboardEvent) => void, ): void; ``` ================================================ FILE: docs/docs/api/model/component-meta.md ================================================ --- title: ComponentMeta sidebar_position: 15 --- > **@types** [IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)
> **@since** v1.0.0 ## 基本介绍 组件元数据信息模型 ## 属性 ### componentName 组件名 `@type {string}` ### isContainer 是否是「容器型」组件 `@type {boolean}` ### isMinimalRenderUnit 是否是最小渲染单元 当组件需要重新渲染时: - 若为最小渲染单元,则只渲染当前组件, - 若不为最小渲染单元,则寻找到上层最近的最小渲染单元进行重新渲染,直至根节点。 `@type {boolean}` ### isModal 是否为「模态框」组件 `@type {boolean}` ### configure 获取用于设置面板显示用的配置 `@type {IPublicTypeFieldConfig[]}` 相关类型:[IPublicTypeFieldConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/field-config.ts) ### title 标题 `@type {string | IPublicTypeI18nData | ReactElement}` 相关类型:[IPublicTypeI18nData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/i18n-data.ts) ### icon 图标 `@type {IPublicTypeIconType}` 相关类型:[IPublicTypeIconType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/icon-type.ts) ### npm 组件 npm 信息 `@type {IPublicTypeNpmInfo}` 相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts) ### availableActions 获取元数据 `@type {IPublicTypeTransformedComponentMetadata}` 相关类型:[IPublicTypeTransformedComponentMetadata](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/transformed-component-metadata.ts) ### advanced 组件元数据中高级配置部分 `@type {IPublicTypeAdvanced}` 相关类型:[IPublicTypeAdvanced](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/advanced.ts) ## 方法 ### setNpm 设置 npm 信息 ```typescript /** * 设置 npm 信息 * set method for npm inforamtion * @param npm */ setNpm(npm: IPublicTypeNpmInfo): void; ``` 相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts) ### getMetadata 获取元数据 ```typescript /** * 获取元数据 * get component metadata */ getMetadata(): IPublicTypeTransformedComponentMetadata; ``` 相关类型:[IPublicTypeTransformedComponentMetadata](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/transformed-component-metadata.ts) ### checkNestingUp 检测当前对应节点是否可被放置在父节点中 ```typescript /** * 检测当前对应节点是否可被放置在父节点中 * check if the current node could be placed in parent node * @param my 当前节点 * @param parent 父节点 */ checkNestingUp(my: IPublicModelNode | IPublicTypeNodeData, parent: any): boolean; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) ### checkNestingDown 检测目标节点是否可被放置在父节点中 ```typescript /** * 检测目标节点是否可被放置在父节点中 * check if the target node(s) could be placed in current node * @param my 当前节点 * @param parent 父节点 */ checkNestingDown( my: IPublicModelNode | IPublicTypeNodeData, target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[], ): boolean; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) - [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### refreshMetadata 刷新元数据,会触发元数据的重新解析和刷新 ```typescript /** * 刷新元数据,会触发元数据的重新解析和刷新 * refresh metadata */ refreshMetadata(): void; ``` ================================================ FILE: docs/docs/api/model/detecting.md ================================================ --- title: Detecting sidebar_position: 6 --- > **@types** [IPublicModelDetecting](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/detecting.ts)
> **@since** v1.0.0 ## 基本介绍 画布节点悬停模型 ## 属性 ### current 当前 hover 的节点 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) **@since v1.0.16** ### enable 是否启用 `@type {boolean}` ## 方法 ### capture hover 指定节点 ```typescript /** * hover 指定节点 * capture node with nodeId * @param id 节点 id */ capture(id: string): void; ``` ### release hover 离开指定节点 ```typescript /** * hover 离开指定节点 * release node with nodeId * @param id 节点 id */ release(id: string): void; ``` ### leave 清空 hover 态 ```typescript /** * 清空 hover 态 * clear all hover state */ leave(): void; ``` ## 事件 ### onDetectingChange hover 节点变化事件 ```typescript /** * hover 节点变化事件 * set callback which will be called when hovering object changed. * @since v1.1.0 */ onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **@since v1.1.0** ================================================ FILE: docs/docs/api/model/document-model.md ================================================ --- title: DocumentModel sidebar_position: 0 --- > **@types** [IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts)
> **@since** v1.0.0 ## 基本介绍 文档模型 ## 属性 ### id 唯一 ID `@type {string}` ### selection 画布节点选中区模型实例 `@type {IPublicModelSelection}` 相关章节:[节点选中区模型](./selection) 相关类型:[IPublicModelSelection](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/selection.ts) ### detecting 画布节点 hover 区模型实例 `@type {IPublicModelDetecting}` 相关章节:[画布节点悬停模型](./detecting) 相关类型:[IPublicModelDetecting](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/detecting.ts) ### history 操作历史模型实例 `@type {IPublicModelHistory}` 相关章节:[操作历史模型](./history) 相关类型:[IPublicModelHistory](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/history.ts) ### project 获取当前文档模型所属的 project `@type {IPublicApiProject}` 相关类型:[IPublicApiProject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/project.ts) ### root 获取文档的根节点 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### nodesMap 获取文档下所有节点 Map, key 为 nodeId `@type {Map} ` 相关章节:[节点模型](./node) 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### modalNodesManager 模态节点管理器 `@type {IPublicModelModalNodesManager | null}` 相关章节:[模态节点管理](./modal-nodes-manager) 相关类型:[IPublicModelModalNodesManager](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/modal-nodes-manager.ts) ### dropLocation 文档的 dropLocation `@type {IPublicModelDropLocation | null}` 相关类型:[IPublicModelDropLocation](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/drop-location.ts) **@since v1.1.0** ## 方法 ### getNodeById 根据 nodeId 返回 [Node](./node) 实例 ```typescript /** * 根据 nodeId 返回 Node 实例 * get node by nodeId * @param nodeId * @returns */ getNodeById(nodeId: string): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### importSchema 导入 schema ```typescript /** * 导入 schema * import schema data * @param schema */ importSchema(schema: IPublicTypeRootSchema): void; ``` 相关类型:[IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) ### exportSchema 导出 schema ```typescript /** * 导出 schema * export schema * @param stage * @returns */ exportSchema(stage: IPublicEnumTransformStage): IPublicTypeRootSchema | undefined; ``` 相关类型: - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) - [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) ### insertNode 插入节点 ```typescript /** * 插入节点 * insert a node */ insertNode( parent: IPublicModelNode, thing: IPublicModelNode, at?: number | null | undefined, copy?: boolean | undefined ): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### createNode 创建一个节点 ```typescript /** * 创建一个节点 * create a node * @param data * @returns */ createNode(data: any): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### removeNode 移除指定节点/节点id ```typescript /** * 移除指定节点/节点id * remove a node by node instance or nodeId * @param idOrNode */ removeNode(idOrNode: string | IPublicModelNode): void; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### checkNesting 检查拖拽放置的目标节点是否可以放置该拖拽对象 ```typescript /** * 检查拖拽放置的目标节点是否可以放置该拖拽对象 * check if dragOjbect can be put in this dragTarget * @param dropTarget 拖拽放置的目标节点 * @param dragObject 拖拽的对象 * @returns boolean 是否可以放置 * @since v1.0.16 */ checkNesting( dropTarget: IPublicModelNode, dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject ): boolean; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDragNodeObject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/drag-node-object.ts) - [IPublicTypeDragNodeDataObject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/drag-node-object-data.ts) **@since v1.0.16** ### isDetectingNode 判断是否当前节点处于被探测状态 ```typescript /** * 判断是否当前节点处于被探测状态 * check is node being detected * @param node * @since v1.1.0 */ isDetectingNode(node: IPublicModelNode): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) **@since v1.1.0** ## 事件 ### onAddNode 当前 document 新增节点事件 ```typescript /** * 当前 document 新增节点事件 * set callback for event on node is created for a document */ onAddNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onMountNode 当前 document 新增节点事件,此时节点已经挂载到 document 上 ```typescript /** * 当前 document 新增节点事件,此时节点已经挂载到 document 上 * set callback for event on node is mounted to canvas */ onMountNode(fn: (payload: { node: IPublicModelNode }) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onRemoveNode 当前 document 删除节点事件 ```typescript /** * 当前 document 删除节点事件 * set callback for event on node is removed */ onRemoveNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeDetecting 当前 document 的 hover 变更事件 ```typescript /** * 当前 document 的 hover 变更事件 * * set callback for event on detecting changed */ onChangeDetecting(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeSelection 当前 document 的选中变更事件 ```typescript /** * 当前 document 的选中变更事件 * set callback for event on selection changed */ onChangeSelection(fn: (ids: string[]) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeNodeVisible 当前 document 的节点显隐状态变更事件 ```typescript /** * 当前 document 的节点显隐状态变更事件 * set callback for event on visibility changed for certain node * @param fn */ onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): IPublicTypeDisposable; ``` - 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeNodeChildren 当前 document 的节点 children 变更事件 ```typescript onChangeNodeChildren(fn: (info?: IPublicTypeOnChangeOptions) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeNodeProp 当前 document 节点属性修改事件 ```typescript onChangeNodeProp(fn: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onImportSchema 当前 document 导入新的 schema 事件 ```typescript /** * import schema event * @param fn * @since v1.0.15 */ onImportSchema(fn: (schema: IPublicTypeRootSchema) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) - [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) **@since v1.0.15** ### onFocusNodeChanged 设置聚焦节点变化的回调 ```typescript /** * 设置聚焦节点变化的回调 * triggered focused node is set mannually from plugin * @param fn * @since v1.1.0 */ onFocusNodeChanged( fn: (doc: IPublicModelDocumentModel, focusNode: IPublicModelNode) => void, ): IPublicTypeDisposable; ``` 相关类型: - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) **@since v1.1.0** ### onDropLocationChanged 设置 DropLocation 变化的回调 ```typescript /** * 设置 DropLocation 变化的回调 * triggered when drop location changed * @param fn * @since v1.1.0 */ onDropLocationChanged(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **@since v1.1.0** ================================================ FILE: docs/docs/api/model/dragon.md ================================================ --- title: Dragon sidebar_position: 99 --- > **@types** [IPublicModelDragon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/dragon.ts)
> **@since** v1.0.0 ## 基本介绍 拖拽对象 ### 对应接口 ```typescript import { IPublicModelDragon } from '@alilc/lowcode-types'; ``` ### 支持版本 **@since** v1.1.0 ## 属性 ### dragging 是否正在拖动 ```typescript /** * is dragging or not */ get dragging(): boolean; ``` ## 方法 ### onDragstart 绑定 dragstart 事件 ```typescript /** * 绑定 dragstart 事件 * bind a callback function which will be called on dragging start * @param func * @returns */ onDragstart(func: (e: IPublicModelLocateEvent) => any): () => void; ``` ### onDrag 绑定 drag 事件 ```typescript /** * 绑定 drag 事件 * bind a callback function which will be called on dragging * @param func * @returns */ onDrag(func: (e: IPublicModelLocateEvent) => any): () => void; ``` ### onDragend 绑定 dragend 事件 ```typescript /** * 绑定 dragend 事件 * bind a callback function which will be called on dragging end * @param func * @returns */ onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): () => void; ``` ### from 设置拖拽监听的区域 shell,以及自定义拖拽转换函数 boost ```typescript /** * 设置拖拽监听的区域 shell,以及自定义拖拽转换函数 boost * set a html element as shell to dragon as monitoring target, and * set boost function which is used to transform a MouseEvent to type * IPublicTypeDragNodeDataObject. * @param shell 拖拽监听的区域 * @param boost 拖拽转换函数 */ from(shell: Element, boost: (e: MouseEvent) => IPublicTypeDragNodeDataObject | null): any; ``` ### boost 发射拖拽对象 ```typescript /** * 发射拖拽对象 * boost your dragObject for dragging(flying) * * @param dragObject 拖拽对象 * @param boostEvent 拖拽初始时事件 */ boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: IPublicModelNode): void; ``` ### addSensor 添加投放感应区 ```typescript /** * 添加投放感应区 * add sensor area */ addSensor(sensor: any): void; ``` ### removeSensor 移除投放感应 ```typescript /** * 移除投放感应 * remove sensor area */ removeSensor(sensor: any): void; ``` ================================================ FILE: docs/docs/api/model/drop-location.md ================================================ --- title: DropLocation sidebar_position: 13 --- > **@types** [IPublicModelDropLocation](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/drop-location.ts)
> **@since** v1.1.0 ## 基本介绍 拖拽放置位置模型 ## 属性 ### target 拖拽放置位置目标 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### detail 拖拽放置位置详情 `@type {IPublicTypeLocationDetail}` 相关类型:[IPublicTypeLocationDetail](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/location-detail.ts) ### event 拖拽放置位置对应的事件 `@type {IPublicTypeLocationDetail}` 相关类型:[IPublicModelLocateEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/location-event.ts) ## 方法 ### clone 获取一份当前对象的克隆 ```typescript /** * 获取一份当前对象的克隆 * get a clone object of current dropLocation */ clone(event: IPublicModelLocateEvent): IPublicModelDropLocation; ``` 相关类型:[IPublicModelLocateEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/location-event.ts) ================================================ FILE: docs/docs/api/model/editor-view.md ================================================ --- title: EditorView sidebar_position: 12 --- > **[@experimental](./#experimental)**
> **@types** [IPublicModelEditorView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/editor-view.ts)
> **@since** v1.1.7 窗口编辑视图 ## 类型定义 ``` import { IPublicModelPluginContext } from "./plugin-context"; export interface IPublicModelEditorView extends IPublicModelPluginContext {}; ``` 相关类型定义: [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts) ================================================ FILE: docs/docs/api/model/history.md ================================================ --- title: History sidebar_position: 5 --- > **@types** [IPublicModelHistory](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/history.ts)
> **@since** v1.0.0 ## 基本介绍 操作历史记录模型 ## 方法 ### go 历史记录跳转到指定位置 ```typescript /** * 历史记录跳转到指定位置 * go to a specific history * @param cursor */ go(cursor: number): void; ``` ### back 历史记录后退 ```typescript /** * 历史记录后退 * go backward in history */ back(): void; ``` ### forward forward() 历史记录前进 ```typescript /** * 历史记录前进 * go forward in history */ forward(): void; ``` ### savePoint 保存当前状态 ```typescript /** * 保存当前状态 * do save current change as a record in history */ savePoint(): void; ``` ### isSavePoint 当前是否是「保存点」,即是否有状态变更但未保存 ```typescript /** * 当前是否是「保存点」,即是否有状态变更但未保存 * check if there is unsaved change for history */ isSavePoint(): boolean; ``` ### getState 获取 state,判断当前是否为「可回退」、「可前进」的状态 ```typescript /** * 获取 state,判断当前是否为「可回退」、「可前进」的状态 * get flags in number which indicat current change state * * | 1 | 1 | 1 | * | -------- | -------- | -------- | * | modified | redoable | undoable | * eg: * 7 means : modified && redoable && undoable * 5 means : modified && undoable */ getState(): number; ``` ## 事件 ### onChangeState 监听 state 变更事件 ```typescript /** * 监听 state 变更事件 * monitor on stateChange event * @param func */ onChangeState(func: () => any): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeCursor 监听历史记录游标位置变更事件 ```typescript /** * 监听历史记录游标位置变更事件 * monitor on cursorChange event * @param func */ onChangeCursor(func: () => any): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ================================================ FILE: docs/docs/api/model/modal-nodes-manager.md ================================================ --- title: ModalNodesManager sidebar_position: 7 --- > **@types** [IPublicModelModalNodesManager](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/modal-nodes-manager.ts)
> **@since** v1.0.0 ## 基本介绍 模态节点管理器模型 ## 方法 ### setNodes 设置模态节点,触发内部事件 ```typescript /** * 设置模态节点,触发内部事件 * set modal nodes, trigger internal events */ setNodes(): void; ``` ### getModalNodes 获取模态节点(们) ```typescript /** * 获取模态节点(们) * get modal nodes */ getModalNodes(): IPublicModelNode[]; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### getVisibleModalNode 获取当前可见的模态节点 ```typescript /** * 获取当前可见的模态节点 * get current visible modal node */ getVisibleModalNode(): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### hideModalNodes 隐藏模态节点(们) ```typescript /** * 隐藏模态节点(们) * hide modal nodes */ hideModalNodes(): void; ``` ### setVisible 设置指定节点为可见态 ```typescript /** * 设置指定节点为可见态 * set specific model node as visible * @param node IPublicModelNode */ setVisible(node: IPublicModelNode): void; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### setInvisible 设置指定节点为不可见态 ```typescript /** * 设置指定节点为不可见态 * set specific model node as invisible * @param node IPublicModelNode */ setInvisible(node: IPublicModelNode): void; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ================================================ FILE: docs/docs/api/model/node-children.md ================================================ --- title: NodeChildren sidebar_position: 2 --- > **@types** [IPublicModelNodeChildren](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node-children.ts)
> **@since** v1.0.0 ## 基本介绍 节点孩子模型 ## 属性 ### owner 返回当前 children 实例所属的节点实例 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### size children 内的节点实例数 `@type {number}` ### isEmptyNode 是否为空 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isEmpty` ### notEmptyNode 是否不为空 `@type {boolean}` **@since v1.1.0** ## 方法 ### delete 删除指定节点 ```typescript /** * 删除指定节点 * delete the node * @param node */ delete(node: IPublicModelNode): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### insert 插入一个节点 ```typescript /** * 插入一个节点 * insert the node * @param node */ insert(node: IPublicModelNode): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### indexOf 返回指定节点的下标 ```typescript /** * 返回指定节点的下标 * get index of node in current children * @param node * @returns */ indexOf(node: IPublicModelNode): number; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### splice 类似数组 splice 操作 ```typescript /** * 类似数组 splice 操作 * provide the same function with {Array.prototype.splice} * @param start * @param deleteCount * @param node */ splice(start: number, deleteCount: number, node?: IPublicModelNode): any; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### get 返回指定下标的节点 ```typescript /** * 返回指定下标的节点 * get node with index * @param index * @returns */ get(index: number): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### has 是否包含指定节点 ```typescript /** * 是否包含指定节点 * check if node exists in current children * @param node * @returns */ has(node: IPublicModelNode): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### forEach 类似数组的 forEach ```typescript /** * 类似数组的 forEach * provide the same function with {Array.prototype.forEach} * @param fn */ forEach(fn: (node: IPublicModelNode, index: number) => void): void; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### reverse 类似数组的 reverse ```typescript /** * 类似数组的 reverse * provide the same function with {Array.prototype.reverse} */ reverse(): IPublicModelNode[]; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### map 类似数组的 map ```typescript /** * 类似数组的 map * provide the same function with {Array.prototype.map} * @param fn */ map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### every 类似数组的 every ```typescript /** * 类似数组的 every * provide the same function with {Array.prototype.every} * @param fn */ every(fn: (node: IPublicModelNode, index: number) => boolean): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### some 类似数组的 some ```typescript /** * 类似数组的 some * provide the same function with {Array.prototype.some} * @param fn */ some(fn: (node: IPublicModelNode, index: number) => boolean): boolean; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### filter 类似数组的 filter ```typescript /** * 类似数组的 filter * provide the same function with {Array.prototype.filter} * @param fn */ filter(fn: (node: IPublicModelNode, index: number) => boolean): any; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### find 类似数组的 find ```typescript /** * 类似数组的 find * provide the same function with {Array.prototype.find} * @param fn */ find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### reduce 类似数组的 reduce ```typescript /** * 类似数组的 reduce * provide the same function with {Array.prototype.reduce} * @param fn */ reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### importSchema 导入 schema ```typescript /** * 导入 schema * import schema * @param data */ importSchema(data?: IPublicTypeNodeData | IPublicTypeNodeData[]): void; ``` 相关类型:[IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) ### exportSchema 导出 schema ```typescript /** * 导出 schema * export schema * @param stage */ exportSchema(stage: IPublicEnumTransformStage): IPublicTypeNodeSchema; ``` 相关类型: - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) - [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### mergeChildren 执行新增、删除、排序等操作 ```typescript /** * 执行新增、删除、排序等操作 * excute remove/add/sort operations * @param remover * @param adder * @param sorter */ mergeChildren( remover: (node: IPublicModelNode, idx: number) => boolean, adder: (children: IPublicModelNode[]) => IPublicTypeNodeData[] | null, sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number ): any; ``` 相关类型: - [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) - [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts) ================================================ FILE: docs/docs/api/model/node.md ================================================ --- title: Node sidebar_position: 1 --- > **@types** [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
> **@since** v1.0.0 ## 基本介绍 节点模型 ## 属性 ### id 节点 id `@type {string}` ### title 节点标题 `@type {string | IPublicTypeI18nData | ReactElement}` 相关类型:[IPublicTypeI18nData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/i18n-data.ts) ### isContainerNode 是否为「容器型」节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isContainer` ### isRootNode 是否为根节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isRoot` ### isEmptyNode 是否为空节点(无 children 或者 children 为空) `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isEmpty` ### isPageNode 是否为 Page 节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isPage` ### isComponentNode 是否为 Component 节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isComponent` ### isModalNode 是否为「模态框」节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isModal` ### isSlotNode 是否为插槽节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isSlot` ### isParentalNode 是否为父类/分支节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isParental` ### isLeafNode 是否为叶子节点 `@type {boolean}` **@since v1.1.0** > v1.1.0 之前请使用 `isLeaf` ### isLocked 获取当前节点的锁定状态 **@since v1.0.16** ### isRGLContainerNode 设置为磁贴布局节点,使用方式可参考:[磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) `@type {boolean}` **@since v1.1.0** > v1.0.16 - v1.1.0 请使用 `isRGLContainer` ### index 下标 `@type {number}` ### icon 图标 `@type {IPublicTypeIconType}` 相关类型:[IPublicTypeIconType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/icon-type.ts) ### zLevel 节点所在树的层级深度,根节点深度为 0 `@type {number}` ### componentName 节点 componentName `@type {string}` ### componentMeta 节点的物料元数据 `@type {IPublicModelComponentMeta | null}` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) ### document 获取节点所属的[文档模型](./document-model)对象 `@type {IPublicModelDocumentModel | null}` 相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) ### prevSibling 获取当前节点的前一个兄弟节点 `@type {IPublicModelNode | null}` ### nextSibling 获取当前节点的后一个兄弟节点 `@type {IPublicModelNode | null}` ### parent 获取当前节点的父亲节点 `@type {IPublicModelNode | null}` ### children 获取当前节点的孩子节点模型 `@type {IPublicModelNodeChildren | null}` 相关类型:[IPublicModelNodeChildren](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node-children.ts) ### slots 节点上挂载的插槽节点们 `@type {IPublicModelNode[]}` ### slotFor 当前节点为插槽节点时,返回节点对应的属性实例 `@type {IPublicModelProp | null}` 相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts) ### props 返回节点的属性集 `@type {IPublicModelProps | null}` 相关类型:[IPublicModelProps](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/props.ts) ### propsData 返回节点的属性集值 `@type {IPublicTypePropsMap | IPublicTypePropsList | null}` 相关类型: - [IPublicTypePropsMap](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-map.ts) - [IPublicTypePropsList](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-list.ts) ### conditionGroup 获取条件组 `@type {IPublicModelExclusiveGroup | null}` 相关类型:[IPublicModelExclusiveGroup](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/exclusive-group.ts) **@since v1.1.0** ### schema 获取符合搭建协议 - 节点 schema 结构 `@type {IPublicTypeNodeSchema | null}` 相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### settingEntry 获取对应的 setting entry `@type {IPublicModelSettingTopEntry}` 相关章节:[设置器顶层操作对象](./setting-top-entry) 相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts) ### visible 当前节点是否可见 `@type {boolean}` **@since v1.1.0** ## 方法 ### getRect 返回节点的尺寸、位置信息 ```typescript /** * 返回节点的尺寸、位置信息 * get rect information for this node */ getRect(): DOMRect | null; ``` ### hasSlots 是否有挂载插槽节点 ```typescript /** * 是否有挂载插槽节点 * check if current node has slots */ hasSlots(): boolean; ``` ### hasCondition 是否设定了渲染条件 ```typescript /** * 是否设定了渲染条件 * check if current node has condition value set */ hasCondition(): boolean; ``` ### hasLoop 是否设定了循环数据 ```typescript /** * 是否设定了循环数据 * check if loop is set for this node */ hasLoop(): boolean; ``` ### getProp 获取指定 path 的属性模型实例 ```typescript /** * 获取指定 path 的属性模型实例 * get prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getProp(path: string, createIfNone: boolean): IPublicModelProp | null; ``` 相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts) ### getPropValue 获取指定 path 的属性模型实例值 ```typescript /** * 获取指定 path 的属性模型实例值 * get prop value by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getPropValue(path: string): any; ``` ### getExtraProp 获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 ```typescript /** * 获取指定 path 的属性模型实例, * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 * * get extra prop by path, an extra prop means a prop not exists in the `props` * but as siblint of the `props` * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param createIfNone 当没有属性的时候,是否创建一个属性 */ getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null; ``` 相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts) ### getExtraPropValue 获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 ```typescript /** * 获取指定 path 的属性模型实例, * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 * * get extra prop value by path, an extra prop means a prop not exists in the `props` * but as siblint of the `props` * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ getExtraPropValue(path: string): any; ``` ### setPropValue setPropValue(path: string, value: CompositeValue) 设置指定 path 的属性模型实例值 ```typescript /** * 设置指定 path 的属性模型实例值 * set value for prop with path * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param value 值 */ setPropValue(path: string, value: IPublicTypeCompositeValue): void; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ### setExtraPropValue 设置指定 path 的属性模型实例值 ```typescript /** * 设置指定 path 的属性模型实例值 * set value for extra prop with path * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param value 值 */ setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ### importSchema 导入节点数据 ```typescript /** * 导入节点数据 * import node schema * @param data */ importSchema(data: IPublicTypeNodeSchema): void; ``` 相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### exportSchema 导出节点数据 ```typescript /** * 导出节点数据 * export schema from this node * @param stage * @param options */ exportSchema(stage: IPublicEnumTransformStage, options?: any): IPublicTypeNodeSchema; ``` 相关类型: - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) - [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### insertBefore 在指定位置之前插入一个节点 ```typescript /** * 在指定位置之前插入一个节点 * insert a node befor current node * @param node * @param ref * @param useMutator */ insertBefore( node: IPublicModelNode, ref?: IPublicModelNode | undefined, useMutator?: boolean, ): void; ``` ### insertAfter 在指定位置之后插入一个节点 ```typescript /** * 在指定位置之后插入一个节点 * insert a node after this node * @param node * @param ref * @param useMutator */ insertAfter( node: IPublicModelNode, ref?: IPublicModelNode | undefined, useMutator?: boolean, ): void; ``` ### replaceChild 替换指定子节点 ```typescript /** * 替换指定子节点 * replace a child node with data provided * @param node 待替换的子节点 * @param data 用作替换的节点对象或者节点描述 * @returns */ replaceChild(node: IPublicModelNode, data: any): IPublicModelNode | null; ``` ### replaceWith 将当前节点替换成指定节点描述 ```typescript /** * 将当前节点替换成指定节点描述 * replace current node with a new node schema * @param schema */ replaceWith(schema: IPublicTypeNodeSchema): any; ``` 相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### select 选中当前节点实例 ```typescript /** * 选中当前节点实例 * select current node */ select(): void; ``` ### hover 设置悬停态 ```typescript /** * 设置悬停态 * set hover value for current node * @param flag */ hover(flag: boolean): void; ``` ### lock 设置节点锁定状态 ```typescript /** * 设置节点锁定状态 * set lock value for current node * @param flag * @since v1.0.16 */ lock(flag?: boolean): void; ``` **@since v1.0.16** ### remove 删除当前节点实例 ```typescript /** * 删除当前节点实例 * remove current node */ remove(): void; ``` ### mergeChildren 执行新增、删除、排序等操作 ```typescript /** * 执行新增、删除、排序等操作 * excute remove/add/sort operations on node`s children * * @since v1.1.0 */ mergeChildren( remover: (node: IPublicModelNode, idx: number) => boolean, adder: (children: IPublicModelNode[]) => any, sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number ): any; ``` **@since v1.1.0** ### contains 当前节点是否包含某子节点 ```typescript /** * 当前节点是否包含某子节点 * check if current node contains another node as a child * @param node * @since v1.1.0 */ contains(node: IPublicModelNode): boolean; ``` **@since v1.1.0** ### canPerformAction 是否可执行某 action ```typescript /** * 是否可执行某 action * check if current node can perform certain aciton with actionName * @param actionName action 名字 * @since v1.1.0 */ canPerformAction(actionName: string): boolean; ``` **@since v1.1.0** ### isConditionalVisible 获取该节点的 ConditionalVisible 值 ```typescript /** * 获取该节点的 ConditionalVisible 值 * check if current node ConditionalVisible * @since v1.1.0 */ isConditionalVisible(): boolean | undefined; ``` **@since v1.1.0** ### setConditionalVisible 设置该节点的 ConditionalVisible 为 true ```typescript /** * 设置该节点的 ConditionalVisible 为 true * make this node as conditionalVisible === true * @since v1.1.0 */ setConditionalVisible(): void; ``` **@since v1.1.0** ### getDOMNode 获取节点实例对应的 dom 节点 ```typescript /** * 获取节点实例对应的 dom 节点 */ getDOMNode(): HTMLElement; ``` ### getRGL 获取磁贴相关信息 ```typescript /** * 获取磁贴相关信息 */ getRGL(): { isContainerNode: boolean; isEmptyNode: boolean; isRGLContainerNode: boolean; isRGLNode: boolean; isRGL: boolean; rglNode: IPublicModelNode | null; } ``` ================================================ FILE: docs/docs/api/model/plugin-instance.md ================================================ --- title: PluginInstance sidebar_position: 12 --- > **@types** [IPublicModelPluginInstance](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-instance.ts)
> **@since** v1.1.0 ## 基本介绍 插件实例 ## 属性 ### pluginName 插件名字 `@type {string}` ### dep 插件依赖 `@type {string[]}` ### disabled 插件是否禁用 `@type {boolean}` ### meta 插件 meta 信息 `@type {IPublicTypePluginMeta}` 相关类型:[IPublicTypePluginMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-meta.ts) ================================================ FILE: docs/docs/api/model/prop.md ================================================ --- title: Prop sidebar_position: 3 --- > **@types** [IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
> **@since** v1.0.0 ## 基本介绍 属性模型 ## 属性 ### id id `@type {string}` ### key key 值 `@type {string | number | undefined}` ### path 返回当前 prop 的路径 `@type {string[]}` ### node 返回所属的节点实例 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### slotNode 当本 prop 代表一个 Slot 时,返回对应的 slotNode `@type {IPublicModelNode | undefined | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ## 方法 ### setValue 设置值 ```typescript /** * 设置值 * set value for this prop * @param val */ setValue(val: IPublicTypeCompositeValue): void; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ### getValue 获取值 ```typescript /** * 获取值 * get value of this prop */ getValue(): any; ``` ### remove 移除值 ```typescript /** * 移除值 * remove value of this prop * @since v1.0.16 */ remove(): void; ``` **@since v1.0.16** ### exportSchema 导出值 ```typescript /** * 导出值 * export schema * @param stage */ exportSchema(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue; ``` 相关类型: - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) - [IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ================================================ FILE: docs/docs/api/model/props.md ================================================ --- title: Props sidebar_position: 4 --- > **@types** [IPublicModelProps](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/props.ts)
> **@since** v1.0.0 ## 基本介绍 属性集模型 ## 属性 ### id id `@type {string}` ### path 返回当前 props 的路径 `@type {string[]}` ### node 返回当前属性集所属的节点实例 `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ## 方法 ### getProp 获取指定 path 的属性模型实例 ```typescript /** * 获取指定 path 的属性模型实例 * get prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getProp(path: string): IPublicModelProp | null; ``` 相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts) ### getPropValue 获取指定 path 的属性模型实例值 ```typescript /** * 获取指定 path 的属性模型实例值 * get value of prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getPropValue(path: string): any; ``` ### getExtraProp 获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 ```typescript /** * 获取指定 path 的属性模型实例, * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 * get extra prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getExtraProp(path: string): IPublicModelProp | null; ``` 相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts) ### getExtraPropValue 获取指定 path 的属性模型实例值,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 ```typescript /** * 获取指定 path 的属性模型实例值 * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 * get value of extra prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 */ getExtraPropValue(path: string): any; ``` ### setPropValue 设置指定 path 的属性模型实例值 ```typescript /** * 设置指定 path 的属性模型实例值 * set value of prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param value 值 */ setPropValue(path: string, value: IPublicTypeCompositeValue): void; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ### setExtraPropValue 设置指定 path 的属性模型实例值 ```typescript /** * 设置指定 path 的属性模型实例值 * set value of extra prop by path * @param path 属性路径,支持 a / a.b / a.0 等格式 * @param value 值 */ setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) ### has 当前 props 是否包含某 prop ```typescript /** * 当前 props 是否包含某 prop * check if the specified key is existing or not. * @param key * @since v1.1.0 */ has(key: string): boolean; ``` **@since v1.1.0** ### add 添加一个 prop ```typescript /** * 添加一个 prop * add a key with given value * @param value * @param key * @since v1.1.0 */ add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any; ``` 相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) **@since v1.1.0** ================================================ FILE: docs/docs/api/model/resource.md ================================================ --- title: Resource sidebar_position: 13 --- > **[@experimental](./#experimental)**
> **@types** [IPublicModelResource](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/resource.ts)
> **@since** v1.1.0 ## 属性 ### title 资源标题 `@type {string}` ### id 资源 id `@type {string}` ### name 资源名字 `@type {string}` ### type 资源类型 `@type {string}` ### category 资源分类 `@type {string}` ### icon 资源 icon `@type {ReactElement}` ### options 资源配置信息 `@type {Object}` ### config 资源配置信息 `@type {Object}` ================================================ FILE: docs/docs/api/model/selection.md ================================================ --- title: Selection sidebar_position: 6 --- > **@types** [IPublicModelSelection](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/selection.ts)
> **@since** v1.0.0 ## 基本介绍 画布节点选中模型 ## 属性 ### selected 返回选中的节点 id `@type {string[]}` ### node 返回选中的节点(如多个节点只返回第一个) `@type {IPublicModelNode | null}` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) **@since v1.1.0** ## 方法 ### select 选中指定节点(覆盖方式) ```typescript /** * 选中指定节点(覆盖方式) * select node with id, this will override current selection * @param id */ select(id: string): void; ``` ### selectAll 批量选中指定节点们 ```typescript /** * 批量选中指定节点们 * select node with ids, this will override current selection * * @param ids */ selectAll(ids: string[]): void; ``` ### remove **取消选中**选中的指定节点,不会删除组件 ```typescript /** * 移除选中的指定节点 * remove node from selection with node id * @param id */ remove(id: string): void; ``` ### clear **取消选中**所有选中节点,不会删除组件 ```typescript /** * 清除所有选中节点 * clear current selection */ clear(): void; ``` ### has 判断是否选中了指定节点 ```typescript /** * 判断是否选中了指定节点 * check if node with specific id is selected * @param id */ has(id: string): boolean; ``` ### add 选中指定节点(增量方式) ```typescript /** * 选中指定节点(增量方式) * add node with specific id to selection * @param id */ add(id: string): void; ``` ### getNodes 获取选中的节点实例 ```typescript /** * 获取选中的节点实例 * get selected nodes */ getNodes(): IPublicModelNode[]; ``` 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts) ### getTopNodes 获取选区的顶层节点 例如选中的节点为: - DivA - ChildrenA - DivB getNodes 返回的是 [DivA、ChildrenA、DivB],getTopNodes 返回的是 [DivA、DivB],其中 ChildrenA 由于是二层节点,getTopNodes 不会返回 ```typescript /** * 获取选区的顶层节点 * get seleted top nodes * for example: * getNodes() returns [A, subA, B], then * getTopNodes() will return [A, B], subA will be removed * @since v1.0.16 */ getTopNodes(includeRoot?: boolean): IPublicModelNode[]; ``` **@since v1.0.16** ## 事件 ### onSelectionChange 注册 selection 变化事件回调 ```typescript /** * 注册 selection 变化事件回调 * set callback which will be called when selection is changed * @since v1.1.0 */ onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **@since v1.1.0** ================================================ FILE: docs/docs/api/model/setting-field.md ================================================ --- title: SettingField sidebar_position: 6 --- > **@types** [IPublicModelSettingField](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-field.ts)
## 基本介绍 setter 设置器操作对象 ## 属性 #### isGroup 获取设置属性的 isGroup `@type {boolean}` #### id 获取设置属性的 id `@type {string}` #### name 获取设置属性的 name `@type {string | number | undefined}` #### key 获取设置属性的 key `@type {string | number | undefined}` #### path 获取设置属性的 path `@type {(string | number)[]}` #### title 获取设置属性的 title `@type {string}` #### setter 获取设置属性的 setter `@type {IPublicTypeSetterType | null}` #### expanded 获取设置属性的 expanded `@type {boolean}` #### extraProps 获取设置属性的 extraProps `@type {IPublicTypeFieldExtraProps}` #### props `@type {IPublicModelSettingTopEntry}` 相关章节:[设置器顶层操作对象](./setting-top-entry) 相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts) #### node 获取设置属性对应的节点实例 `@type {IPublicModelNode | null}` #### parent 获取设置属性的父设置属性 `@type {IPublicModelSettingTopEntry | IPublicModelSettingField}` 相关章节:[设置器顶层操作对象](./setting-top-entry) 相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts) #### top 获取顶级设置属性 `@type {IPublicModelSettingTopEntry}` 相关章节:[设置器顶层操作对象](./setting-top-entry) 相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts) #### isSettingField 是否是 SettingField 实例 `@type {boolean}` #### componentMeta `@type {IPublicModelComponentMeta}` 相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts) #### items 获取设置属性的 items `@type {Array}` 相关类型:[IPublicTypeCustomView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/custom-view.ts) ## 方法 #### setKey 设置 key 值 ``` /** * 设置 key 值 * @param key */ setKey(key: string | number): void; ``` #### setValue 设置值 ``` /** * 设置值 * @param val 值 */ setValue(val: IPublicTypeCompositeValue, extraOptions?: IPublicTypeSetValueOptions): void; ``` 相关类型: - [IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts) - [IPublicTypeSetValueOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/set-value-options.ts) #### setPropValue 设置子级属性值 ``` /** * 设置子级属性值 * @param propName 子属性名 * @param value 值 */ setPropValue(propName: string | number, value: any): void; ``` #### clearPropValue 清空指定属性值 ``` /** * 清空指定属性值 * @param propName */ clearPropValue(propName: string | number): void; ``` #### getDefaultValue 获取配置的默认值 ``` /** * 获取配置的默认值 * @returns */ getDefaultValue(): any; ``` #### getValue 获取值 ``` /** * 获取值 * @returns */ getValue(): any; ``` #### getPropValue 获取子级属性值 ``` /** * 获取子级属性值 * @param propName 子属性名 * @returns */ getPropValue(propName: string | number): any; ``` #### getExtraPropValue 获取顶层附属属性值 ``` /** * 获取顶层附属属性值 */ getExtraPropValue(propName: string): any; ``` #### setExtraPropValue 设置顶层附属属性值 ``` /** * 设置顶层附属属性值 */ setExtraPropValue(propName: string, value: any): void; ``` #### getProps 获取设置属性集 ``` /** * 获取设置属性集 * @returns */ getProps(): IPublicModelSettingTopEntry; ``` 相关章节:[设置器顶层操作对象](./setting-top-entry) 相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts) #### isUseVariable 是否绑定了变量 ``` /** * 是否绑定了变量 * @returns */ isUseVariable(): boolean; ``` #### setUseVariable 设置绑定变量 ``` /** * 设置绑定变量 * @param flag */ setUseVariable(flag: boolean): void; ``` #### createField 创建一个设置 field 实例 ``` /** * 创建一个设置 field 实例 * @param config * @returns */ createField(config: IPublicTypeFieldConfig): IPublicModelSettingField; ``` 相关类型:[IPublicTypeFieldConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/field-config.ts) #### getMockOrValue 获取值,当为变量时,返回 mock ``` /** * 获取值,当为变量时,返回 mock * @returns */ getMockOrValue(): any; ``` #### purge 销毁当前 field 实例 ``` /** * 销毁当前 field 实例 */ purge(): void; ``` #### remove 移除当前 field 实例 ``` /** * 移除当前 field 实例 */ remove(): void; ``` ## 事件 #### onEffect 设置 autorun ``` /** * 设置 autorun * @param action * @returns */ onEffect(action: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ================================================ FILE: docs/docs/api/model/setting-top-entry.md ================================================ --- title: SettingTopEntry sidebar_position: 6 --- > **@types** [IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
## 基本介绍 setter 设置器顶层操作对象 ## 属性 #### node 返回所属的节点实例 `@type {IPublicModelNode | null}` ## 方法 #### get 获取子级属性对象 ``` /** * 获取子级属性对象 * @param propName * @returns */ get(propName: string | number): IPublicModelSettingField | null; ``` 相关章节:[设置器操作对象](./setting-field) 相关类型:[IPublicModelSettingField](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-field.ts) #### getPropValue 获取指定 propName 的值 ``` /** * 获取指定 propName 的值 * @param propName * @returns */ getPropValue(propName: string | number): any; ``` #### setPropValue 设置指定 propName 的值 ``` /** * 设置指定 propName 的值 * @param propName * @param value */ setPropValue(propName: string | number, value: any): void; ``` #### clearPropValue 清除指定 propName 的值 ``` /** * 清除指定 propName 的值 * @param propName */ clearPropValue(propName: string | number): void; ``` ================================================ FILE: docs/docs/api/model/simulatorRender.md ================================================ --- title: SimulatorRender sidebar_position: 6 --- > **@types** [IPublicModelSimulatorRender](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/simulator-render.ts)
> **@since** v1.0.0 ## 基本介绍 画布节点选中模型 ## 属性 ### components 画布组件列表 ```typescript /** * 画布组件列表 */ components: { [key: string]: any; } ``` ## 方法 ### rerender 触发画布重新渲染 ```typescript /** * 触发画布重新渲染 */ rerender: () => void; ``` ================================================ FILE: docs/docs/api/model/window.md ================================================ --- title: Window sidebar_position: 12 --- > **[@experimental](./#experimental)**
> **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/window.ts)
> **@since** v1.1.0 ## 基本介绍 低代码设计器窗口模型 ## 属性 ### id 窗口唯一 id `@type {string}` ### title 窗口标题 `@type {string}` ### icon `@type {ReactElement}` ### resource 窗口对应资源 `@type {IPublicModelResource}` 关联模型 [IPublicModelResource](./resource) ### currentEditorView 窗口当前视图 `@type {IPublicModelEditorView}` 关联模型 [IPublicModelEditorView](./editor-view) **@since v1.1.7** ### editorViews 窗口所有视图 `@type {IPublicModelEditorView[]}` 关联模型 [IPublicModelEditorView](./editor-view) **@since v1.1.7** ## 方法 ### importSchema 当前窗口导入 schema, 会调用当前窗口对应资源的 import 钩子 ```typescript function importSchema(schema: IPublicTypeNodeSchema): void ``` 相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts) ### changeViewType 修改当前窗口视图类型 ```typescript function changeViewType(viewName: string): void ``` ### save 当前窗口的保存方法,会调用当前窗口对应资源的 save 钩子 ```typescript function save(): Promise(void) ``` ## 事件 ### onChangeViewType 窗口视图变更事件 ``` onChangeViewType(fn: (viewName: string) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onSave 窗口视图保存事件 ``` onSave(fn: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **@since v1.1.7** ================================================ FILE: docs/docs/api/plugins.md ================================================ --- title: plugins - 插件 API sidebar_position: 2 --- > **@types** [IPublicApiPlugins](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/plugins.ts)
> **@since** v1.0.0 ## 模块简介 插件管理器,提供编排模块中管理插件的能力。 ## 方法 ### register 注册插件 ```typescript async function register( plugin: IPublicTypePlugin, options?: IPublicTypePluginRegisterOptions, ): Promise ``` 相关 types: - [IPublicTypePlugin](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin.ts) - [IPublicTypePluginRegisterOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-register-options.ts) 其中第一个参数 plugin 通过低代码工具链的插件脚手架生成编写模板,开发者可以参考[这个章节](/site/docs/guide/expand/editor/cli)进行创建 #### 简单示例 ```typescript import { plugins } from '@alilc/lowcode-engine'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { async init() { const { skeleton } = ctx; // 注册组件面板 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); ``` #### 使用 exports 示例 ```typescript import { plugins } from '@alilc/lowcode-engine'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const PluginA = (ctx: IPublicModelPluginContext) => { return { async init() {}, exports() { return { x: 1, } }, }; } PluginA.pluginName = 'PluginA'; const PluginB = (ctx: IPublicModelPluginContext) => { return { async init() { // 获取 pluginA 的导出值 console.log(ctx.plugins.PluginA.x); // => 1 }, }; } PluginA.pluginName = 'pluginA'; PluginB.pluginName = 'PluginB'; PluginB.meta = { dependencies: ['PluginA'], } await plugins.register(PluginA); await plugins.register(PluginB); ``` > 注:ctx 是在插件中获取引擎 API 的唯一渠道,具体定义参见 [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts) #### 设置兼容引擎版本示例 ```typescript import { plugins } from '@alilc/lowcode-engine'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const BuiltinPluginRegistry = (ctx: IPublicModelPluginContext) => { return { async init() { ... }, }; } BuiltinPluginRegistry.pluginName = 'BuiltinPluginRegistry'; BuiltinPluginRegistry.meta = { engines: { lowcodeEngine: '^1.0.0', // 插件需要配合 ^1.0.0 的引擎才可运行 }, } await plugins.register(BuiltinPluginRegistry); ``` #### 设置插件参数版本示例 ```typescript import { plugins } from '@alilc/lowcode-engine'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const BuiltinPluginRegistry = (ctx: IPublicModelPluginContext, options: any) => { return { async init() { // 直接传值方式: // 通过 register(xxx, options) 传入 // 通过 options 取出 // 引擎初始化时也可以设置某插件的全局配置项: // 通过 engine.init(..., preference) 传入 // 通过 ctx.preference.getValue() 取出 }, }; } BuiltinPluginRegistry.pluginName = 'BuiltinPluginRegistry'; BuiltinPluginRegistry.meta = { preferenceDeclaration: { title: 'pluginA 的参数定义', properties: [ { key: 'key1', type: 'string', description: 'this is description for key1', }, { key: 'key2', type: 'boolean', description: 'this is description for key2', }, { key: 'key3', type: 'number', description: 'this is description for key3', }, { key: 'key4', type: 'string', description: 'this is description for key4', }, ], }, } await plugins.register(BuiltinPluginRegistry, { key1: 'abc', key5: 'willNotPassToPlugin' }); ``` ### get 获取指定插件 ```typescript /** * 获取指定插件 * get plugin instance by name */ get(pluginName: string): IPublicModelPluginInstance | null; ``` 关联模型 [IPublicModelPluginInstance](./model/plugin-instance) ### getAll 获取所有的插件实例 ```typescript /** * 获取所有的插件实例 * get all plugin instances */ getAll(): IPublicModelPluginInstance[]; ``` 关联模型 [IPublicModelPluginInstance](./model/plugin-instance) ### has 判断是否有指定插件 ```typescript /** * 判断是否有指定插件 * check if plugin with certain name exists */ has(pluginName: string): boolean; ``` ### delete 删除指定插件 ```typescript /** * 删除指定插件 * delete plugin instance by name */ delete(pluginName: string): void; ``` ### getPluginPreference 引擎初始化时可以提供全局配置给到各插件,通过这个方法可以获得本插件对应的配置 ```typescript /** * 引擎初始化时可以提供全局配置给到各插件,通过这个方法可以获得本插件对应的配置 * use this to get preference config for this plugin when engine.init() called */ getPluginPreference( pluginName: string, ): Record | null | undefined; ``` ## 相关类型定义 - [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts) - [IPublicTypePluginConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-config.ts) - [IPublicModelPluginInstance](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-instance.ts) ## 插件元数据工程转化示例 your-plugin/package.json ```json { "name": "@alilc/lowcode-plugin-debug", "lcMeta": { "pluginName": "debug", "meta": { "engines": { "lowcodeEgnine": "^1.0.0" }, "preferenceDeclaration": { ... } } } } ``` 转换后的结构: ```typescript const debug = (ctx: IPublicModelPluginContext, options: any) => { return {}; } debug.pluginName = 'debug'; debug.meta = { engines: { lowcodeEgnine: '^1.51.0', }, preferenceDeclaration: { ... } }; ``` ================================================ FILE: docs/docs/api/project.md ================================================ --- title: project - 模型 API sidebar_position: 10 --- ## 模块简介 引擎编排模块中包含多种模型,包括: - [文档模型 DocumentModel](./model/document-model) - [节点模型 Node](./model/node) - [节点孩子模型 NodeChildren](./model/node-children) - [属性模型 Prop](./model/prop) - [属性集模型 Props](./model/props) 他们的依赖关系如下图: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01B1bAZi1asNU3KaSUJ_!!6000000003385-2-tps-1650-1352.png) 在文档模型内部,又有一些引申模型,比如: - [历史操作 History)](./model/history) - [画布节点选中 Selection)](./model/selection) - [画布节点悬停 Detecting)](./model/detecting) - [模态节点管理器 ModalNodesManager](./model/modal-nodes-manager) 整个模型系统,以 project API 为入口,所有模型实例均需要通过 project 来获得,比如 project.currentDocument 来获取当前的文档模型,project.currentDocument.nodesMap 来获取当前文档模型里所有的节点列表。 下面来看看 project API 的具体介绍 ## 变量 ### currentDocument 获取当前的 document 实例 ```typescript /** * 获取当前的 document * get current document */ get currentDocument(): IPublicModelDocumentModel | null; ``` 相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) ### documents 获取当前 project 下所有 documents ```typescript /** * 获取当前 project 下所有 documents * get all documents of this project * @returns */ get documents(): IPublicModelDocumentModel[]; ``` 相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) ### simulatorHost 获取模拟器的 host ```typescript /** * 获取模拟器的 host * get simulator host */ get simulatorHost(): IPublicApiSimulatorHost | null; ``` 相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) ## 方法 ### openDocument 打开一个 document ```typescript /** * 打开一个 document * @param doc * @returns */ openDocument(doc?: string | IPublicTypeRootSchema | undefined): IPublicModelDocumentModel | null; ``` 相关类型: - [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) - [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) ### createDocument 创建一个 document ```typescript /** * 创建一个 document * create a document * @param data * @returns */ createDocument(data?: IPublicTypeRootSchema): IPublicModelDocumentModel | null; ``` 相关类型: - [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) - [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) ### removeDocument 删除一个 document ```typescript /** * 删除一个 document * remove a document * @param doc */ removeDocument(doc: IPublicModelDocumentModel): void; ``` 相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) ### getDocumentByFileName 根据 fileName 获取 document ```typescript /** * 根据 fileName 获取 document * get a document by filename * @param fileName * @returns */ getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null; ``` 相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) ### getDocumentById 根据 id 获取 document ```typescript /** * 根据 id 获取 document * get a document by id * @param id * @returns */ getDocumentById(id: string): IPublicModelDocumentModel | null; ``` 相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) ### exportSchema 导出 project schema ```typescript /** * 导出 project * export project to schema * @returns */ exportSchema(stage: IPublicEnumTransformStage): IPublicTypeProjectSchema; ``` 相关类型: - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) - [IPublicTypeProjectSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/project-schema.ts) ### importSchema 导入 project ```typescript /** * 导入 project schema * import schema to project * @param schema 待导入的 project 数据 */ importSchema(schema?: IPublicTypeProjectSchema): void; ``` 相关类型:[IPublicTypeProjectSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/project-schema.ts) ### addPropsTransducer 增加一个属性的管道处理函数 ```typescript /** * 增加一个属性的管道处理函数 * add a transducer to process prop * @param transducer * @param stage */ addPropsTransducer( transducer: IPublicTypePropsTransducer, stage: IPublicEnumTransformStage, ): void; ``` 相关类型: - [IPublicTypePropsTransducer](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-transducer.ts) - [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) **示例** 在保存的时候删除每一个组件的 props.hidden ```typescript import { project } from '@alilc/lowcode-engine'; import { IPublicTypeCompositeObject, IPublicEnumTransformStage, IPublicModelPluginContext } from '@alilc/lowcode-types'; export const DeleteHiddenTransducer = (ctx: IPublicModelPluginContext) => { return { async init() { const { project } = ctx; project.addPropsTransducer((props: IPublicTypeCompositeObject): IPublicTypeCompositeObject => { delete props.hidden; return props; }, IPublicEnumTransformStage.Save); }, }; } DeleteHiddenTransducer.pluginName = 'DeleteHiddenTransducer'; ``` ### setI18n 设置多语言语料 ```typescript /** * 设置多语言语料 * 数据格式参考 https://github.com/alibaba/lowcode-engine/blob/main/specs/lowcode-spec.md#2434%E5%9B%BD%E9%99%85%E5%8C%96%E5%A4%9A%E8%AF%AD%E8%A8%80%E7%B1%BB%E5%9E%8Baa * * set I18n data for this project * @param value object * @since v1.0.17 */ setI18n(value: object): void; ``` **@since v1.0.17** ### setConfig 设置当前项目配置 ```typescript /** * 设置当前项目配置 * set config for this project * @param value object * @since v1.1.4 */ setConfig(value: IPublicTypeAppConfig): void; setConfig(key: T, value: IPublicTypeAppConfig[T]): void; ``` **@since v1.1.4** #### 如何扩展项目配置 ```typescript // shims.d.ts declare module '@alilc/lowcode-types' { export interface IPublicTypeAppConfig { customProp: CustomPropType } } export {}; ``` ## 事件 ### onRemoveDocument 绑定删除文档事件 ```typescript /** * 绑定删除文档事件 * set callback for event onDocumentRemoved * @param fn * @since v1.0.16 */ onRemoveDocument(fn: (data: { id: string }) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) **@since v1.0.16** ### onChangeDocument 当前 project 内的 document 变更事件 ```typescript /** * 当前 project 内的 document 变更事件 * set callback for event onDocumentChanged */ onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onSimulatorHostReady 当前 project 的模拟器 ready 事件 ```typescript /** * 当前 project 的模拟器 ready 事件 * set callback for event onSimulatorHostReady */ onSimulatorHostReady(fn: (host: IPublicApiSimulatorHost) => void): IPublicTypeDisposable; ``` 相关类型: - [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) - [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onSimulatorRendererReady 当前 project 的渲染器 ready 事件 ```typescript /** * 当前 project 的渲染器 ready 事件 * set callback for event onSimulatorRendererReady */ onSimulatorRendererReady(fn: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ================================================ FILE: docs/docs/api/setters.md ================================================ --- title: setters - 设置器 API sidebar_position: 10 --- > **@types** [IPublicApiSetters](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/setters.ts)
> **@since** v1.0.0 ## 模块简介 负责注册设置器、管理设置器的 API。注册自定义设置器之后可以在物料中进行使用。 ## 方法 ### getSetter 获取指定 setter ```typescript /** * 获取指定 setter * get setter by type * @param type * @returns */ getSetter(type: string): IPublicTypeRegisteredSetter | null; ``` 相关类型:[IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts) ### getSettersMap 获取已注册的所有 settersMap ```typescript /** * 获取已注册的所有 settersMap * get map of all registered setters * @returns */ getSettersMap(): Map; ``` 相关类型:[IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts) ### registerSetter 注册一个 setter ```typescript /** * 注册一个 setter * register a setter * @param typeOrMaps * @param setter * @returns */ registerSetter( typeOrMaps: string | { [key: string]: IPublicTypeCustomView | IPublicTypeRegisteredSetter }, setter?: IPublicTypeCustomView | IPublicTypeRegisteredSetter | undefined ): void; ``` 相关类型: - [IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts) - [IPublicTypeCustomView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/custom-view.ts) ## 使用示例 ### 注册官方内置 Setter 到设计器中 ```typescript import { setters, skeleton } from '@alilc/lowcode-engine'; import { setterMap, pluginMap } from '@alilc/lowcode-engine-ext'; import { IPublicModelPluginContext } from '@alilc/lowcode-types'; const SetterRegistry = (ctx: IPublicModelPluginContext) => { return { name: 'ext-setters-registry', async init() { // 注册 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); ``` ### 开发自定义 Setter AltStringSetter 代码如下: ```typescript import * as React from "react"; import { Input } from "@alifd/next"; import "./index.scss"; interface AltStringSetterProps { // 当前值 value: string; // 默认值 initialValue: string; // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; } export default class AltStringSetter extends React.PureComponent { componentDidMount() { const { onChange, value, defaultValue } = this.props; if (value == undefined && defaultValue) { onChange(defaultValue); } } // 声明 Setter 的 title static displayName = 'AltStringSetter'; render() { const { onChange, value, placeholder } = this.props; return ( onChange(val)} > ); } } ``` 开发完毕之后,注册 AltStringSetter 到设计器中: ```typescript import AltStringSetter from './AltStringSetter'; import { setters } from '@alilc/lowcode-engine'; const { registerSetter } = setters; registerSetter('AltStringSetter', AltStringSetter); ``` 注册之后,我们就可以在物料中使用了,其中核心配置如下: ```typescript { "props": { "isExtends": true, "override": [ { "name": "type", "setter": "AltStringSetter" } ] } } ``` 完整配置如下: ```typescript { "componentName": "Message", "title": "Message", "props": [ { "name": "title", "propType": "string", "description": "标题", "defaultValue": "标题" }, { "name": "type", "propType": { "type": "oneOf", "value": [ "success", "warning", "error", "notice", "help", "loading" ] }, "description": "反馈类型", "defaultValue": "success" } ], "configure": { "props": { "isExtends": true, "override": [ { "name": "type", "setter": "AltStringSetter" } ] } } } ``` ================================================ FILE: docs/docs/api/simulatorHost.md ================================================ --- title: simulatorHost - 模拟器 API sidebar_position: 10 --- > **@types** [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts)
> **@since** v1.0.0 ## 模块简介 负责模拟器相关的 API,包括画布尺寸、语言等。 ## 方法 ### set 设置 host 配置值 ```typescript /** * 设置若干用于画布渲染的变量,比如画布大小、locale 等。 * set config for simulator host, eg. device locale and so on. * @param key * @param value */ set(key: string, value: any): void; ``` **示例** 设置若干用于画布渲染的变量,比如画布大小、locale 等。 以设置画布大小为例: 目前支持 3 种定制方式: ```typescript // 直接使用内置设备类型 project.simulatorHost.set('device', 'mobile' / 'iphonex' / 'iphone6' / 'default'); // 定制 canvas 的样式类 project.simulatorHost.set('deviceClassName', 'my-canvas-class'); // 最灵活的方式,直接设置 canvas / viewport 的样式(canvas 是外框,viewport 是内框,可以在 canvas 设置手机 / 平板背景图) project.simulatorHost.set('deviceStyle', { canvas: { width: '300px', backgroundColor: 'red' }, viewport: { width: '280px' } }); ``` ### get 获取模拟器中设置的变量,比如画布大小、locale 等。 ```typescript /** * 获取模拟器中设置的变量,比如画布大小、locale 等。 * set config value by key * @param key * @returns */ get(key: string): any; ``` ### rerender 触发组件构建,并刷新渲染画布 ```typescript /** * 触发组件构建,并刷新渲染画布 * make simulator render again */ rerender(): void; ``` ### scrollToNode 滚动到指定节点 ```typescript /** * 滚动到指定节点 * scroll to specific node * @param node * @since v1.1.0 */ scrollToNode(node: IPublicModelNode): void; ``` **@since v1.1.0** ================================================ FILE: docs/docs/api/skeleton.md ================================================ --- title: skeleton - 面板 API sidebar_position: 10 --- > **@types** [IPublicApiSkeleton](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/skeleton.ts)
> **@since** v1.0.0 ## 模块简介 面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png) 页面上可以扩展的区域共 5 个,具体如下: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN014d2AcS1D5c9TshEiQ_!!6000000000165-2-tps-1892-974.png) ### 基本概念 #### 扩展区域位置 (area) ##### topArea 展示在设计器的顶部区域,常见的相关区域的插件主要是: 1. 注册设计器 Logo; 2. 设计器操作回退和撤销按钮; 3. 全局操作按钮,例如:保存、预览等; ##### leftArea 左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。 该区域相关插件的主要有: 1. 大纲树展示,展示该设计器设计页面的大纲。 2. 组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。 3. 数据源面板 4. JS 等代码面板。 可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 ##### centerArea 画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: 1. 画布大小修改 2. 物料选中扩展区域修改 ##### rightArea 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 ##### toolbar 跟 topArea 类似,按需放置面板插件~ #### 展示类型 (type) 展示类型用于区分插件在设计器内可操作的几种不同界面类型。主要的几种类型为 PanelDock、Widget、Dock,另有 Panel 类型目前不推荐使用。 ##### PanelDock PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。 下图是组件库插件的展示效果。 ![Feb-08-2022 19-44-15.gif](https://img.alicdn.com/imgextra/i2/O1CN01i66G5O27bK37nlpxV_!!6000000007815-1-tps-1536-790.gif) 其中右上角可以进行固定,可以对弹出的宽度做设定 接入可以参考代码 ```javascript import { skeleton } from "@alilc/lowcode-engine"; skeleton.add({ area: "leftArea", // 插件区域 type: "PanelDock", // 插件类型,弹出面板 name: "sourceEditor", content: SourceEditor, // 插件组件实例 props: { align: "left", icon: "wenjian", title: '标题', // 图标下方展示的标题 description: "JS 面板", }, panelProps: { floatable: true, // 是否可浮动 height: 300, hideTitleBar: false, maxHeight: 800, maxWidth: 1200, title: "JS 面板", width: 600, }, }); ``` ##### Widget Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01IRQIZp1m5AJPwBKDv_!!6000000004902-2-tps-1988-94.png) 接入可以参考代码: ```javascript import { skeleton } from "@alilc/lowcode-engine"; // 注册 logo 面板 skeleton.add({ area: "topArea", type: "Widget", name: "logo", content: Logo, // Widget 组件实例 contentProps: { // Widget 插件 props logo: "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", href: "/", }, props: { align: "left", width: 100, }, }); ``` ##### Dock 一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。 ```javascript import { skeleton } from "@alilc/lowcode-engine"; skeleton.add({ area: "leftArea", type: "Dock", name: "opener", props: { icon: Icon, // Icon 组件实例 align: "bottom", onClick: function () { // 打开外部链接 window.open('https://lowcode-engine.cn'); // 显示 widget skeleton.showWidget('xxx'); } } }); ``` ## 方法 ### add 往指定扩展区加入一块面板 ```typescript /** * 增加一个面板实例 * add a new panel * @param config * @param extraConfig * @returns */ add(config: IPublicTypeWidgetBaseConfig, extraConfig?: Record): any; ``` IWidgetBaseConfig 定义如下: | 属性名 | 含义 | 备注 | | --- | --- | --- | | name | 面板名称 | | | area | 扩展区位置,可选值:'topArea' | 'leftArea' | 'rightArea' | 'toolbar' | 'bottomArea' | 'mainArea' | | | type | 面板类型,可选值:'Widget' | 'PanelDock' | 'Panel' | Dock | 详见前文中对**展示类型**的描述 | | content | 面板的实现类/节点,类型是 ReactClass | ReactElement | | | props | 面板属性 | align: 'top' | 'bottom' | 'left' | 'center' | 'right'; // 指定面板 icon 位置区域
icon: string | ReactElement;  // icon 为字符串时,请确定当前 fusion 主题包中包含该 icon
description: string;
condition: Function; // 指定当前面板的显影状态 | | contentProps | 面板的实现类/节点的参数 | | | panelProps | 假如 type: 'Panel' | 'PanelDock' 时有效,传给 Panel 类的参数 | keepVisibleWhileDragging: boolean; // 当有元素在当前 panel 拖拽时,是否保持 panel 为展开状态,默认值:false
area: 'leftFloatArea' | 'leftFixedArea' // 指定 panel 位于浮动面板还是钉住面板 | | index | 面板的位置,不传默认按插件注册顺序 | | ### remove 移除一个面板实例 ```typescript /** * 移除一个面板实例 * remove a panel * @param config * @returns */ remove(config: IPublicTypeWidgetBaseConfig): number | undefined; ``` ### getPanel 获取面板实例 ```typescript /** * 获取面板实例 * @param name 面板名称 */ getPanel(name: string): IPublicModelSkeletonItem | undefined; ``` 相关类型:[IPublicModelSkeletonItem](https://github.com/alibaba/lowcode-engine/blob/main/packages/shell/src/model/skeleton-item.ts) @since v1.1.10 ### showPanel 展示指定 Panel 实例 ```typescript /** * 展示指定 Panel 实例 * show panel by name * @param name */ showPanel(name: string): void; ``` ### hidePanel 隐藏面板 ```typescript /** * 隐藏面板 * hide panel by name * @param name */ hidePanel(name: string): void; ``` ### showWidget 展示指定 Widget 实例 ```typescript /** * 展示指定 Widget 实例 * show widget by name * @param name */ showWidget(name: string): void; ``` ### enableWidget 将 widget 启用。 ```typescript /** * 将 widget 启用 * enable widget * @param name */ enableWidget(name: string): void; ``` ### hideWidget 隐藏指定 widget 实例。 ```typescript /** * 隐藏指定 widget 实例 * hide widget by name * @param name */ hideWidget(name: string): void; ``` ### disableWidget 将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。 适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。 ```typescript /** * 将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。 * disable widget,and make it not responding any click event. * @param name */ disableWidget(name: string): void; ``` ### showArea 显示某个 Area ```typescript /** * 显示某个 Area * show area * @param areaName name of area */ showArea(areaName: string): void; ``` ### hideArea 隐藏某个 Area ```typescript /** * 隐藏某个 Area * hide area * @param areaName name of area */ hideArea(areaName: string): void; ``` ### getAreaItems 获取某个区域下的所有面板实例 ```typescript /** * 获取某个区域下的所有面板实例 * @param areaName IPublicTypeWidgetConfigArea */ getAreaItems(areaName: IPublicTypeWidgetConfigArea): IPublicModelSkeletonItem[] | undefined; ``` 相关类型:[IPublicModelSkeletonItem](https://github.com/alibaba/lowcode-engine/blob/main/packages/shell/src/model/skeleton-item.ts) ### registerConfigTransducer 注册一个面板的配置转换器(transducer)。 ```typescript /** * 注册一个面板的配置转换器(transducer)。 * Registers a configuration transducer for a panel. * @param {IPublicTypeConfigTransducer} transducer * - 要注册的转换器函数。该函数接受一个配置对象(类型为 IPublicTypeSkeletonConfig)作为输入,并返回修改后的配置对象。 * - The transducer function to be registered. This function takes a configuration object * * @param {number} level * - 转换器的优先级。优先级较高的转换器会先执行。 * - The priority level of the transducer. Transducers with higher priority levels are executed first. * * @param {string} [id] * - (可选)转换器的唯一标识符。用于在需要时引用或操作特定的转换器。 * - (Optional) A unique identifier for the transducer. Used for referencing or manipulating a specific transducer when needed. */ registerConfigTransducer(transducer: IPublicTypeConfigTransducer, level: number, id?: string): void; ``` 使用示例 ```typescript import { IPublicModelPluginContext, IPublicTypeSkeletonConfig } from '@alilc/lowcode-types'; function updatePanelWidth(config: IPublicTypeSkeletonConfig) { if (config.type === 'PanelDock') { return { ...config, panelProps: { ...(config.panelProps || {}), width: 240, }, } } return config; } const controlPanelWidthPlugin = (ctx: IPublicModelPluginContext) => { const { skeleton } = ctx; (skeleton as any).registerConfigTransducer?.(updatePanelWidth, 1, 'update-panel-width'); return { init() {}, }; }; controlPanelWidthPlugin.pluginName = 'controlPanelWidthPlugin'; controlPanelWidthPlugin.meta = { dependencies: [], engines: { lowcodeEngine: '^1.2.3', // 插件需要配合 ^1.0.0 的引擎才可运行 }, }; export default controlPanelWidthPlugin; ``` ## 事件 ### onShowPanel 监听 Panel 实例显示事件 ```typescript /** * 监听 panel 显示事件 * set callback for panel shown event * @param listener * @returns */ onShowPanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onHidePanel 监听 Panel 实例隐藏事件 ```typescript /** * 监听 Panel 实例隐藏事件 * set callback for panel hidden event * @param listener * @returns */ onHidePanel(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onDisableWidget 监听 Widget 实例 Disable 事件 ```typescript /** * 监听 Widget 实例 Disable 事件 * @param listener */ onDisableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onEnableWidget 监听 Widget 实例 Enable 事件 ```typescript /** * 监听 Widget 实例 Enable 事件 * @param listener */ onEnableWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onShowWidget 监听 Widget 实例显示事件 ```typescript /** * 监听 Widget 显示事件 * set callback for widget shown event * @param listener * @returns */ onShowWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onHideWidget 监听 Widget 实例隐藏事件 ```typescript /** * 监听 Widget 隐藏事件 * set callback for widget hidden event * @param listener * @returns */ onHideWidget(listener: (paneName?: string, panel?: IPublicModelSkeletonItem) => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ## 使用示例 ```typescript import { skeleton } from '@alilc/lowcode-engine'; skeleton.add({ name: 'logo', area: 'topArea', type: 'Widget', contentProps: {}, content: LogoContent, }); skeleton.add({ name: 'sourceEditor', type: 'PanelDock', area: 'leftArea', props: { align: 'top', icon: 'wenjian', description: 'JS 面板', }, panelProps: { floatable: true, height: 300, help: undefined, hideTitleBar: false, maxHeight: 800, maxWidth: 1200, title: 'JS 面板', width: 600, }, content: SourceEditor, }); // 显隐 panel skeleton.showPanel('sourceEditor'); skeleton.hidePanel('sourceEditor'); // 创建一个浮动的 widget skeleton.add({ name: 'floatingWidget', type: 'Widget', area: 'mainArea', props: {}, content: React.createElement('div', {}, 'haha'), contentProps: { style: { position: 'fixed', top: '200px', bottom: 0, width: 'calc(100% - 46px)', 'background-color': 'lightblue' } } }); // 显隐 widget skeleton.showWidget('floatingWidget'); skeleton.hideWidget('floatingWidget'); // 控制 widget 的可点击态 skeleton.enableWidget('sourceEditor'); skeleton.disableWidget('sourceEditor'); ``` ### bottomArea 示例 ```typescript import { skeleton } from '@alilc/lowcode-engine'; skeleton.add({ name: 'bottomAreaPanelName', area: 'bottomArea', type: 'Panel', content: () => 'demoText', }); skeleton.showPanel('bottomAreaPanelName'); ``` ### widget 示例 ```typescript // 注册 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: 'https://lowcode-engine.cn', }, props: { align: 'left', }, }); ``` ================================================ FILE: docs/docs/api/workspace.md ================================================ --- title: workspace - 应用级 API sidebar_position: 10 --- > **[@experimental](./#experimental)**
> **@types** [IPublicApiWorkspace](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/workspace.ts)
> **@since** v1.1.0 ## 模块简介 通过该模块可以开发应用级低代码设计器。 ## 变量 ### isActive 是否启用 workspace 模式 ### window 当前设计器窗口模型 ```typescript get window(): IPublicModelWindow ``` 关联模型 [IPublicModelWindow](./model/window) ### plugins 应用级别的插件注册 ```typescript get plugins(): IPublicApiPlugins ``` 关联模型 [IPublicApiPlugins](./plugins) ### skeleton 应用级别的面板管理 ```typescript get skeleton(): IPublicApiSkeleton ``` 关联模型 [IPublicApiSkeleton](./skeleton) ### windows 当前设计器的编辑窗口 ```typescript get window(): IPublicModelWindow[] ``` 关联模型 [IPublicModelWindow](./model/window) ### resourceList 当前设计器的资源列表数据 ``` get resourceList(): IPublicModelResource; ``` 关联模型 [IPublicModelResource](./model/resource) ## 方法 ### registerResourceType 注册资源 ```typescript /** 注册资源 */ registerResourceType(resourceTypeModel: IPublicTypeResourceType): void; ``` 相关类型:[IPublicTypeResourceType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-type.ts) ### setResourceList 设置设计器资源列表数据 ```typescript setResourceList(resourceList: IPublicResourceList) {} ``` 相关类型:[IPublicResourceData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-list.ts) ### openEditorWindow 打开视图窗口 ```typescript /** * 打开视图窗口 * @deprecated */ openEditorWindow(resourceName: string, id: string, extra: Object, viewName?: string, sleep?: boolean): Promise; /** 打开视图窗口 */ openEditorWindow(resource: Resource, sleep?: boolean): Promise; ``` ### openEditorWindowById 通过视图 id 打开窗口 ```typescript openEditorWindowById(id: string): void; ``` ### removeEditorWindow 移除视图窗口 ```typescript /** * 移除视图窗口 * @deprecated */ removeEditorWindow(resourceName: string, id: string): void; /** * 移除视图窗口 */ removeEditorWindow(resource: Resource): void; ``` ### removeEditorWindowById 通过视图 id 移除窗口 ```typescript removeEditorWindowById(id: string): void; ``` ## 事件 ### onChangeWindows 窗口新增/删除的事件 ```typescript function onChangeWindows(fn: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onChangeActiveWindow active 窗口变更事件 ```typescript function onChangeActiveWindow(fn: () => void): IPublicTypeDisposable; ``` 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ### onResourceListChange 设计器资源列表数据变更事件 ```typescript onResourceListChange(fn: (resourceList: IPublicResourceList): void): (): IPublicTypeDisposable; ``` - 相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts) - 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) ================================================ FILE: docs/docs/article/index.md ================================================ # 官方文章 - [2023/11/09 UIPaaS | 基于 LowCodeEngine 的低代码平台孵化器](https://mp.weixin.qq.com/s/mKuv3_Wvgt5T3AGErUGBQQ) - [2023/04/04 什么?低代码引擎可以开发应用了](https://mp.weixin.qq.com/s/dwi40gJjGBHW9MVpag5Oxg) - [2023/03/23 低代码引擎 LowCodeEngine 茁壮成长的一年](https://mp.weixin.qq.com/s/DDt4LQLFUBQ2-F5ehZGBKg) - [2023/02/21 基于 LowCodeEngine 的低代码组件体系的建设和实践](https://mp.weixin.qq.com/s/rnvbGHImGt6oJuX2wCtaqw) - [2022/12/21 低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q) - [2022/11/24 低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409) - [2022/10/27 低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ) - [2022/08/23 基于 LowCodeEngine 的调试能力建设与实践](https://mp.weixin.qq.com/s/H8KvEOylmzLPgIuuBO0S9w) - [2022/06/23 低代码渲染那些事](https://mp.weixin.qq.com/s/yqYey76qLGYPfDtpGkVFfA) - [2022/06/16 关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig) - [2022/04/07 磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) - [2022/03/23 阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) - [2022/01/10 阿里低代码引擎和生态建设实战及思考](https://mp.weixin.qq.com/s/MI6MrUKKydtnSdO4xq6jwA) - [2021/04/14 2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) ================================================ FILE: docs/docs/demoUsage/advanced/_category_.json ================================================ { "label": "进阶功能", "position": 3, "collapsed": false, "collapsible": false } ================================================ FILE: docs/docs/demoUsage/advanced/hotkey.md ================================================ --- title: 8. 编辑器快捷键 sidebar_position: 0 --- - 任意时机: - `⌘` `S` 保存 - `⌘` `P` 预览 - `⌘` `D` 查看 Diff - `⌘` `Z` 撤销 - `⇧` `⌘` `Z` 重做 - 选择任意组件后: - `Backspace` 删除组件 - `⌘` `C` 复制组件 - `⌘` `V` 粘贴组件 - `⌘` `X` 剪切组件 - `⌥` `↑` 向外层移动组件 - `⌥` `↓` 向内层移动组件 - `⌥` `←` 同级向上移动组件 - `⌥` `→` 同级向下移动组件 - `↑` 向上选择组件 - `↓` 向下选择组件 - `←` 向左选择组件 - `→` 向右选择组件 - `Escape` 取消选择组件 ================================================ FILE: docs/docs/demoUsage/appendix/_category_.json ================================================ { "label": "常见问题", "position": 4, "collapsed": false, "collapsible": false } ================================================ FILE: docs/docs/demoUsage/appendix/api.md ================================================ --- title: demo 使用相关 API sidebar_position: 2 --- ## 数据源相关 ### 请求数据源 ```javascript // 请求 userList(userList 在数据源面板中定义) this.dataSourceMap['userList'].load({ data: {} }).then(res => {}) .catch(error => {}); ``` ### 获取数据源的值 ```javascript const { userList } = this.state; ``` ### 手动修改数据源值 ```javascript // 获取数据源面板中定义的值 const { user } = this.state; // 修改 state 值 this.setState({ user: {} }); ``` ================================================ FILE: docs/docs/demoUsage/appendix/loop.md ================================================ --- title: 如何使用循环值 sidebar_position: 0 --- 1.设置循环数据 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Gw1kXO1qaXulQCWap_!!6000000005512-2-tps-3840-1900.png) 2.给需要的变量绑定 this.item ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01RpP2Ev24lRxjqpHdY_!!6000000007431-2-tps-3840-1892.png) 绑定之后的效果如下: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN019qa1J31m7ugsXcnaA_!!6000000004908-2-tps-3840-1884.png) 其中 this.item 的 item 是可以配置的。配置不同的 key 可以方便在多层循环中使用不同层级的循环 item 值。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XQfnYL1P4wxn01oXv_!!6000000001788-2-tps-3840-1896.png) this.index 是当前循环的索引值。 3.在事件绑定函数中使用 在事件绑定函数中使用扩展参数设置 ![image](https://github.com/alibaba/lowcode-engine/assets/11935995/7274506e-decd-497a-b07f-c95941a706b4) 绑定之后在函数中使用 ![image](https://github.com/alibaba/lowcode-engine/assets/11935995/9d52ee5c-9959-4991-91be-9391e639bb7e) 按钮点击效果 ![image](https://github.com/alibaba/lowcode-engine/assets/11935995/6ca590c9-1f5f-4d48-94a5-439130a22e92) ================================================ FILE: docs/docs/demoUsage/intro.md ================================================ --- title: 1. 试用低代码引擎 Demo sidebar_position: 0 --- 低代码编辑器中的区块主要包含这些功能点: ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01aGQull1RVdGs7Pt6x_!!6000000002117-2-tps-3384-1784.png) ## 分区块功能介绍 ### 左侧:面板与操作区 #### 物料面板 可以查找组件,并在此拖动组件到编辑器画布中 ![Dec-17-2021 19-12-46.gif](https://img.alicdn.com/imgextra/i1/O1CN01pEu7811SlwzxraLHG_!!6000000002288-1-tps-1468-754.gif) #### 大纲面板 可以调整页面内的组件树结构: ![Dec-17-2021 19-14-34.gif](https://img.alicdn.com/imgextra/i1/O1CN013DDLqt1GH0rAlajqi_!!6000000000596-1-tps-1468-754.gif) 可以在这里打开或者关闭模态浮层的展现: ![Dec-17-2021 19-19-18.gif](https://img.alicdn.com/imgextra/i2/O1CN01bQfS8W1JitokHRinC_!!6000000001063-1-tps-1468-754.gif) #### 源码面板 可以编辑页面级别的 JavaScript 代码和 CSS 配置 ![Feb-11-2022 14-51-59.gif](https://img.alicdn.com/imgextra/i1/O1CN01d11kK71Q223eWvL5F_!!6000000001917-1-tps-1532-614.gif) #### Schema 编辑 【开发者专属】可以编辑页面的底层 Schema 数据。 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lcQOER23Q5sjA0Gn5_!!6000000007249-2-tps-3070-1648.png) 搭配顶部操作区的“保存到本地”和“重置页面”功能,可以实验各种 schema 对低代码页面的改变。 它们操作的数据关系是: - 页面中的 Schema 数据:保存在低代码引擎中的 Schema,点击 Schema 面板中的“保存 Schema”时将修改引擎中的值,此外低代码引擎中的所有操作都可能修改到 Schema - localStorage 数据:由“保存到本地”保存到 localStorage 中,页面初始化时将读取,预览页面时也会读取 - 默认 Schema:保存在 Demo 项目中的默认 Schema(`public/schema.json`),初始化页面时如果不存在 localStorage 数据即会读取,点击“重置页面”时,也会读取 #### 中英文切换 可以切换编辑器的语言;注:需要组件配置配合。 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN019ORknX1M5SYg7eSJ3_!!6000000001383-2-tps-3018-1512.png) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01R7g7pW21rSJEHd2AI_!!6000000007038-2-tps-3016-1510.png) ## 中部:可视化页面编辑画布区域 点击组件在右侧面板中能够显示出对应组件的属性配置选项 ![Dec-17-2021 19-28-28.gif](https://img.alicdn.com/imgextra/i1/O1CN01uBU3lR1CuAFTTq4RS_!!6000000000140-1-tps-1468-754.gif) 拖拽修改组件的排列顺序 ![Dec-17-2021 19-29-40.gif](https://img.alicdn.com/imgextra/i3/O1CN01DAAYKd1bycUq1C4JV_!!6000000003534-1-tps-1468-754.gif) 将组件拖拽到容器类型的组件中,注意拖拽时会在右侧提示当前的组件树。 ![Dec-17-2021 19-31-30.gif](https://img.alicdn.com/imgextra/i2/O1CN01TzJosP1FIYZe6xIQ5_!!6000000000464-1-tps-1468-754.gif) ## 右侧:组件级别配置 ### 选中的组件 从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上。 ![Dec-17-2021 19-35-25.gif](https://img.alicdn.com/imgextra/i4/O1CN01EbImy425R80OeblSD_!!6000000007522-1-tps-1468-754.gif) ### 选中组件的配置 当前组件的大类目选项,根据组件类型不同,包含如下子类目: #### 属性 组件的基础属性值设置 ![Dec-17-2021 19-37-26.gif](https://img.alicdn.com/imgextra/i2/O1CN01ziBI9T1nQynFKqCp2_!!6000000005085-1-tps-1468-754.gif) #### 样式 组件的样式配置,如文字: ![Dec-17-2021 19-38-55.gif](https://img.alicdn.com/imgextra/i4/O1CN017DQv2R1OEjoawXmKJ_!!6000000001674-1-tps-1468-754.gif) #### 事件 绑定组件对外暴露的事件。 ![Dec-17-2021 19-41-17.gif](https://img.alicdn.com/imgextra/i2/O1CN01mhVutF24I8cLde0zy_!!6000000007367-1-tps-1468-754.gif) #### 高级 循环、条件渲染与 key 设置。 ![Dec-17-2021 19-46-26.gif](https://img.alicdn.com/imgextra/i4/O1CN01xTjXQX1jMcYwuTGKZ_!!6000000004534-1-tps-1468-754.gif) ## 顶部:操作区 ### 撤回和重做 ![Dec-17-2021 19-52-23.gif](https://img.alicdn.com/imgextra/i3/O1CN019VWkbr1jsgHoGKf6g_!!6000000004604-1-tps-1468-754.gif) ================================================ FILE: docs/docs/demoUsage/makeStuff/_category_.json ================================================ { "label": "如何制作", "position": 1, "collapsed": false, "collapsible": false } ================================================ FILE: docs/docs/demoUsage/makeStuff/dialog.md ================================================ --- title: 3. 如何通过按钮展示/隐藏弹窗 sidebar_position: 1 --- > 说明:这个方式依赖低代码弹窗组件是否对外保留了相关的 API,不同的物料支持的方式不一样,这里只针对综合场景的弹窗物料。 ## 1.拖拽一个按钮 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01kLaWA31D6WwTui9VW_!!6000000000167-2-tps-3584-1812.png) ## 2.拖拽一个弹窗 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01rfRzLa1quEwUyulPc_!!6000000005555-2-tps-3578-1622.png) ## 3.查看弹窗 refId ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01rEgPnW1cSqdWpG0YE_!!6000000003600-2-tps-3574-1588.png) - 点击弹窗 - 点击右侧面板中的高级 - 找到 refId ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01MXMfqn1rj4uKzlOh2_!!6000000005666-2-tps-3584-1796.png) 这里我们的 refId 是 "pro-dialog-entryl32xgrus" ## 4.隐藏弹窗 点击工具栏的隐藏小图标,将弹窗在画布中隐藏 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN017Kamt71HFvWkpeK8j_!!6000000000729-2-tps-3578-1568.png) ## 5.按钮绑定事件 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01SwJ0xx1u3LfX2h8yt_!!6000000005981-2-tps-3584-1814.png) **通过下面的代码即可打开弹窗** ```typescript this.$('pro-dialog-entryl32xgrus').open(); ``` #### ================================================ FILE: docs/docs/demoUsage/makeStuff/table.md ================================================ --- title: 2. 如何制作表格 sidebar_position: 0 --- ## 步骤详解 ### 拖入组件 一个常见的表格页面会包含查询框、表格和分页按钮。这些都在 Fusion UI 中进行了相应的封装,我们可以在左侧组件面板处找到他们。 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UU8pVT26XN1A0ExVG_!!6000000007671-2-tps-3032-1648.png) 将他们拖到画布之中: ![Feb-16-2022 16-58-59.gif](https://img.alicdn.com/imgextra/i3/O1CN01UAsQ8124HgDptzPrn_!!6000000007366-1-tps-1534-792.gif) ### 配置组件 选中刚拖入的“查询筛选”组件,您可以配置此组件: ![Feb-14-2022 17-59-47.gif](https://img.alicdn.com/imgextra/i2/O1CN01RiDUy31aufSeVk8IN_!!6000000003390-1-tps-1532-792.gif) 对于形如 Array 的配置项目,我们可以增删项目、修改常用项、修改顺序。 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01eWOK0d1fOfsF9PZu9_!!6000000003997-2-tps-3060-1476.png) 掌握组件配置功能,我们就可以完成一个常用的查询框的配置: ![Feb-21-2022 18-05-52.gif](https://img.alicdn.com/imgextra/i1/O1CN0138fb0P1CTbHKWDBeo_!!6000000000082-1-tps-1532-790.gif) ### 绑定数据 低代码场景下,我们需要绑定动态的数据。通过左侧的源码编辑面板,我们可以创建动态数据和它的相关处理函数: ![image.png](https://img.alicdn.com/imgextra/i1/O1CN015Bw2aQ1jaMRWoYzv5_!!6000000004564-2-tps-2976-1478.png) 如图,我们配入如下自定义值进 state 里: ```json "companies": [ { company: '测试公司1', id: 1, createTime: +new Date() }, { company: '测试公司2', id: 2, createTime: +new Date() }, { company: '测试公司3', id: 3, createTime: +new Date() }, ] ``` 定义动态数据以后,我们需要绑定它到组件的属性中,我们找到相关属性的配置: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN013Cu5OE1CXGRhyEmbJ_!!6000000000090-2-tps-3546-1792.png) ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01iaK15j1bgIeO65svI_!!6000000003494-2-tps-3428-1640.png) 如图,输入表达式: ```javascript this.state.companies ``` 再结合上一节的“配置组件”操作,我们已经可以把表格的主体配置出来了: ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01p8QJ5C1buxKDTS1cU_!!6000000003526-2-tps-3058-1640.png) ### 动态请求 我们进入代码区块,使用生命周期方法来完成动态数据的请求。假设提供数据的接口是:[http://rap2api.taobao.org/app/mock/250089/testCompanies](http://rap2api.taobao.org/app/mock/250089/testCompanies),那么,我们可以在源码面板进行如下配置: ```typescript class LowcodeComponent extends Component { state = { "text": "outer", "isShowDialog": false, "loading": false, "companies": [ { company: '测试公司 1', id: 1, createTime: +new Date() }, { company: '测试公司 2', id: 2, createTime: +new Date() }, { company: '测试公司 3', id: 3, createTime: +new Date() }, ] } componentDidMount() { this.setState({ loading: true }) window.fetch('http://rap2api.taobao.org/app/mock/250089/testCompanies') .then((res) => res.json()) .then((companies) => { this.setState({ companies, }) }) .catch(err => console.error(err)) .then(() => { this.setState({ loading: false }) }) } } ``` 在 `componentDidMount` 生命周期,将请求接口并设置 loading 和数据字段。 点击保存或叉关闭源码面板后,我们可以看到代码已经生效了: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lqjW8e1f39G8Zm7hQ_!!6000000003950-2-tps-3058-1634.png) ### 配置插槽 我们可以用绑定数据的方法把 loading 绑在加载指示上: ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01K3Pwjo1PKWQcoBl5K_!!6000000001822-2-tps-3170-1904.png) ![Feb-16-2022 20-24-35.gif](https://img.alicdn.com/imgextra/i2/O1CN01VGlZPS1JitoljrFFY_!!6000000001063-1-tps-1532-792.gif) 将 Loading 的“是否显示”字段绑定 `this.state.loading` 后,我们可以看到,这里暴露了一个插槽。插槽是可以任意扩展的预设部分,我们可以把其他的部分拖进插槽: ![Feb-16-2022 20-27-03.gif](https://img.alicdn.com/imgextra/i2/O1CN01HSBncU1XWRfPdwlPK_!!6000000002931-1-tps-1528-792.gif) 点击右上角的预览,我们能够看到完整的动态请求效果了: ![Feb-16-2022 20-28-36.gif](https://img.alicdn.com/imgextra/i3/O1CN01o5THZf1fkesw2nZEC_!!6000000004045-1-tps-1534-792.gif) ### 列挂钩浮层 为了能够让表格里的操作挂钩浮层,我们先拖入一个浮层: ![Feb-16-2022 20-32-09.gif](https://img.alicdn.com/imgextra/i2/O1CN01bX3SHk21Z8T4O6knp_!!6000000006998-1-tps-1532-792.gif) 使用大纲树能够临时显示和隐藏此浮层: ![Feb-16-2022 20-32-39.gif](https://img.alicdn.com/imgextra/i3/O1CN01ZtSp0P1LvNqYPeUHg_!!6000000001361-1-tps-1530-792.gif) 我们给表格增加一个数据列: ![Feb-16-2022 20-39-41.gif](https://img.alicdn.com/imgextra/i2/O1CN012K6qWI1hgCG6KwRF7_!!6000000004306-1-tps-1532-792.gif) 然后配置它的行为为“弹窗”: ![Feb-16-2022 20-40-05.gif](https://img.alicdn.com/imgextra/i2/O1CN016axZh61uc9ln0L3Rz_!!6000000006057-1-tps-1532-792.gif) 实现的效果如下: ![Feb-16-2022 20-42-51.gif](https://img.alicdn.com/imgextra/i4/O1CN018iana91j4l71QTmpE_!!6000000004495-1-tps-1534-792.gif) ### 事件回调 上述功能点中,我们是把操作行为绑定在数据列上的,这一节我们绑定到操作列中。在操作列按钮处,点击下方的“添加一项”: ![Feb-23-2022 11-58-02.gif](https://img.alicdn.com/imgextra/i4/O1CN01DsBoHQ1tyli2rtoFR_!!6000000005971-1-tps-1534-790.gif) 点击左侧的详情按钮,配置它的事件回调: ![Feb-23-2022 12-00-18.gif](https://img.alicdn.com/imgextra/i2/O1CN017BuNLP1LPmW8zH7hx_!!6000000001292-1-tps-1534-790.gif) 代码侧,我们配置这个回调函数: ```javascript onClick_new(e, { rowKey, rowIndex, rowRecord }){ window.Next.Message.show(JSON.stringify({ rowKey, rowIndex, rowRecord })) } ``` 保存。预览时我们可以看到效果了: ![Feb-23-2022 12-05-25.gif](https://img.alicdn.com/imgextra/i3/O1CN01CXi1zJ1N302paKUre_!!6000000001513-1-tps-1532-790.gif) ## 研究本例的 schema 我们把本例的 schema 保存在云端,您可以自行下载研究:[https://mo.m.taobao.com/marquex/lowcode-showcase-table](https://mo.m.taobao.com/marquex/lowcode-showcase-table) 您可以通过左下角的 Schema 面板直接导入本例子的 Schema。 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01z2LXgW1iFSklNRzTN_!!6000000004383-2-tps-3054-1620.png) ================================================ FILE: docs/docs/demoUsage/panels/_category_.json ================================================ { "label": "面板详解", "position": 2, "collapsed": false, "collapsible": false } ================================================ FILE: docs/docs/demoUsage/panels/canvas.md ================================================ --- title: 5. 画布详解 sidebar_position: 1 --- ## 组件操作 ### 画布操作 点击组件在右侧面板中能够显示出对应组件的属性配置选项 ![Dec-17-2021 19-28-28.gif](https://img.alicdn.com/imgextra/i1/O1CN01flb5tL1inM47Gdo3a_!!6000000004457-1-tps-1468-754.gif) 拖拽修改组件的排列顺序 ![Dec-17-2021 19-29-40.gif](https://img.alicdn.com/imgextra/i3/O1CN01UJ1x731NBFB4eELV0_!!6000000001531-1-tps-1468-754.gif) 拖拽时会在右侧提示当前的组件树。 ![Dec-17-2021 19-31-30.gif](https://img.alicdn.com/imgextra/i1/O1CN01jLUYQE1h4dmcfYhZB_!!6000000004224-1-tps-1468-754.gif) ### 组件控制 点击组件右上角的复制按钮,或者按下 `ctrl + c` 再按下 `ctrl + v`,可以将其复制; 点击组件右上角的删除按钮,或者直接使用 `Delete` 键,可以将其删除。 ![Dec-17-2021 19-33-20.gif](https://img.alicdn.com/imgextra/i2/O1CN01QT1pq621gvCVpoOm6_!!6000000007015-1-tps-1468-754.gif) ### 选择组件切换 可以用键盘上的按键切换组件选择: - `↑` 向上选择组件 - `↓` 向下选择组件 - `←` 向左选择组件 - `→` 向右选择组件 可以 hover 到组件操作辅助区的第一项来选中组件的父级节点: ![Feb-22-2022 14-42-30.gif](https://img.alicdn.com/imgextra/i4/O1CN01RWbgGJ1TM8HoOpQ7V_!!6000000002367-1-tps-1536-790.gif) ### 可扩展项简述 快捷键、操作辅助区均可扩展。 ## Slot 区块 React 中,可以定义一个 prop 选项为 `JSXElement` 或 `(...args) => JSXElement` 的形式,这个形式在低代码画布中,被定义为 Slot,允许往其内部拖入组件,进行符合直觉的操作。 ![Feb-22-2022 14-46-02.gif](https://img.alicdn.com/imgextra/i4/O1CN01geivkn1csUog5gZbm_!!6000000003656-1-tps-1534-790.gif) ### 锁定 Slot 您可以对 Slot 进行锁定操作,锁定后内部内容无法选中; ![Feb-22-2022 14-50-03.gif](https://img.alicdn.com/imgextra/i3/O1CN01eBD3WY1rPNsZt8UVL_!!6000000005623-1-tps-1534-790.gif) 在组件树可以解除操作。 ## 组件编辑态 低代码引擎允许组件在编辑状态下表现得和渲染时不一样。Demo 中的布局组件就是用对应 API 完成布局的高级操作的。 它背后的实现有两种方法: - 侵入型:组件编辑态下,会往组件内传入 `__designMode: 'design'`,可以在组件中进行相应处理; ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Xh3o891gvTrNBMMy2_!!6000000004204-2-tps-3066-1642.png) - 双入口型:通过配置物料的 editUrls,加载专属于编辑态组件的物料。pro-layout 使用的是这种方式 ```json { "package": "@alifd/pro-layout", "version": "1.0.1-beta.6", "library": "AlifdProLayout", "urls": [ "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.js", "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/dist/AlifdProLayout.css" ], "editUrls": [ "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.js", "https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.6/build/lowcode/view.css" ] } ``` ================================================ FILE: docs/docs/demoUsage/panels/code.md ================================================ --- title: 7. 源码面板详解 sidebar_position: 3 --- 在源码面板中,您可以完成低代码中的代码部分编写。 ## 面板功能拆解 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pRxmmD1agTBVwCO5x_!!6000000003359-2-tps-2502-1740.png) ### 代码编辑面板 代码编辑面板允许您书写 JavaScript 代码,并支持 JSX 语法。 由于依赖了 Babel,所以书写的 JSX 和 Chrome 80+ 以后的新语法也会被自动编译: | 编译前 | 编译后 | | --- | --- | | ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01xI9RVX1yV46HbW02H_!!6000000006583-2-tps-670-190.png) | ![image.png](https://img.alicdn.com/imgextra/i1/O1CN012exYQL1y37wKM7VFT_!!6000000006522-2-tps-2094-110.png) | | ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pK2rPi1lhLij4m3o7_!!6000000004850-2-tps-434-120.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01ti4n9m1ihOupktQow_!!6000000004444-2-tps-2536-120.png) | > 注:因为编译结果会被 `@babel/runtime` 干扰,目前面板不支持 `async await`或 `{ ...arr }` 形态的语法编译。如果您需要此类编译,您可以考虑在读取 schema 中的 `originCode` 之后自己手动通过 babel 编译。 #### 全局变量引用 在代码中,您可以通过 window 来引用全局变量。资产包中的 packages 都是通过 UMD 方式引入的对应内容,如果您引入了 Fusion Next(Demo 中默认引入),那么可以通过此方法直接唤起 Fusion Next 的内容,如弹窗提示: ```typescript window.Next.Message.success('成功') ``` ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Fxjd801p4eigEBpb6_!!6000000005307-2-tps-238-114.png) #### 局部变量引用 您可以在成员函数中访问到如下变量: - `this.state` - `this.setState` - `this.context.appHelper.utils` - `this.context.appHelper.constants` - `this.context.appHelper.requestHandlerMap` - `this.context.components` #### 读、写与异常处理 - 读取:每次打开面板时,都会尝试读取 schema 中的 originCode 字段,如果没有,则从 schema 上的字段还原代码; - 写入:在关闭代码编辑面板(主动点击叉或者点击非代码编辑区块的被动关闭都算)时,将自动写入到 schema 中;您也可以在编辑过程中点击“保存”按钮手动保存; | 源码面板中 | Schema 中 | | --- | --- | | 本地数据初始值设置:![image.png](https://img.alicdn.com/imgextra/i4/O1CN01V6iaTY1gVNHi7gQfK_!!6000000004147-2-tps-370-146.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN010rhIPa268BEfGmzO6_!!6000000007616-2-tps-2098-826.png) | | 生命周期方法:![image.png](https://img.alicdn.com/imgextra/i4/O1CN010Y1TxV1QOvrVLRUjD_!!6000000001967-2-tps-478-260.png) | ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01pbJzVQ1VSfAL7Lh8G_!!6000000002652-2-tps-2010-836.png) | | 自定义函数:![image.png](https://img.alicdn.com/imgextra/i4/O1CN01S2gjFk1CU3fm61eiD_!!6000000000083-2-tps-660-642.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01X35YxU1GUkjj1YWVj_!!6000000000626-2-tps-1862-822.png) | | 编译前全量代码:![image.png](https://img.alicdn.com/imgextra/i2/O1CN01sbiK9N1kc1Uxp1OHY_!!6000000004703-2-tps-762-1122.png) | ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01adKSg61QXAzRjQ4bm_!!6000000001985-2-tps-1906-796.png) | - 异常处理:如果代码解析失败,它将无法被正常保存到 schema 中,此时编辑器会弹层提示: ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01aSzh8o26rWRu6zXFE_!!6000000007715-2-tps-3068-1638.png) ### 样式编辑面板 您可以在这里书写 CSS 内容。它对应 schema 中的 css 字段: | 源码面板中 | Schema 中 | | --- | --- | | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01cuWt4L27fRcW5WIP9_!!6000000007824-2-tps-634-388.png) | ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Edu7Gy1MzKsb2iss8_!!6000000001505-2-tps-1646-582.png) | ## 对接代码 ### 生命周期对接 如果您书写了视图相关的声明周期方法,那么对应的方法会在视图的特定周期被调用。支持的生命周期函数在《阿里巴巴中后台前端搭建协议规范》中被定义,包含: ```typescript { componentDidMount(): void; constructor(props: Record, context: any); render(): void; componentDidUpdate(prevProps: Record, prevState: Record, snapshot: Record): void; componentWillUnmount(): void; componentDidCatch(error: Error, info: any): void; } ``` ### 设置器面板对接 书写完了函数 / state 后,您可以在右侧的设置器面板中配置对代码的部分。 通常书写代码是为了对接低代码配置中的“变量绑定”、“事件回调”、“条件判断”和“循环”部分的。 #### 变量绑定 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01wcgwOI1wOXDtgfrgD_!!6000000006298-2-tps-2738-1464.png) ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01GYVAw41FlrvEyFcCO_!!6000000000528-2-tps-1528-1166.png) ```json { "componentName": "NextBlockCell", "id": "node_ockzmje8tf5", "props": { "bodyPadding": { "type": "JSExpression", "value": "this.state.text", "mock": "" } } } ``` #### 事件回调 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01B0tvgw1O6x58dbbIb_!!6000000001657-2-tps-2734-1452.png) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01sD9g2n1tQQ0OjQkcY_!!6000000005896-2-tps-1670-1162.png) ```json { "componentName": "Filter", "id": "node_ockzmj0cl11w", "props": { "__events": { "eventDataList": [ { "type": "componentEvent", "name": "onSearch", "relatedEventName": "closeDialog" } ] }, "onSearch": { "type": "JSFunction", "value": "function(){this.onSearch.apply(this,Array.prototype.slice.call(arguments).concat([])) }" } } } ``` #### 条件判断 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01zXqec823EBaCutOY2_!!6000000007223-2-tps-2738-1452.png) ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Ze3snL24BGfuRIMCl_!!6000000007352-2-tps-1528-1166.png) ```json { "componentName": "Filter", "id": "node_ockzmj0cl11w", "condition": { "type": "JSExpression", "value": "this.state.text", "mock": true } } ``` #### 循环 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Kbj6XP297fe0BvhKz_!!6000000008021-2-tps-2746-1460.png) ![image.png](https://img.alicdn.com/imgextra/i1/O1CN018Ogesd1qnN0IOKRDZ_!!6000000005540-2-tps-1528-1166.png) ```json { "componentName": "Filter", "id": "node_ockzmj0cl11w", "loop": { "type": "JSExpression", "value": "this.state.text", "mock": true } } ``` ================================================ FILE: docs/docs/demoUsage/panels/component.md ================================================ --- title: 4. 组件面板详解 sidebar_position: 0 --- ## 概述 组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据 (数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01a6xgwH1wCAWugmNvU_!!6000000006271-2-tps-3056-1672.png) ## 组件信息 组件面板承载的组件信息有: - 组件标题; - 组件截图; - 组件低代码 schema 片段; - 组件分组; - 组件分类; - 是否隐藏组件; - 关键词:关键词用于搜索,会聚合 name、title、description、keywords 等字段作为搜索匹配的目标; 其中标题和截图是我们能够看到的,schema 片段则是拖拽到设计器时会自动插入页面 schema 中,面板会根据分组、分类来对组件进行排列; 这些组件信息均通过资产包数据获取,字段对应关系如下图所示: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN012ZUg6a289fl4z6WCm_!!6000000007890-2-tps-1326-1678.png) ## 组件分组、分类排序 组件面板会把相同分组的组件放在同一个 tab 下,相同分类的组件放在同一个 collapse 中,同时也支持对 tab 和 collapse 进行排序; 由于是整体性的排序,组件自身的信息无法决定此排序,因此在资产包数据根节点新增了 sort 字段用于指定分组和分类的排序,具体定义在[《低代码引擎资产包协议规范》](https://lowcode-engine.cn/assets)2.4 sort 章节; | **根属性名称** | **类型** | **说明** | **变量支持** | **默认值** | | --- | --- | --- | --- | --- | | sort.groupList | String[] | 组件分组,用于组件面板 tab 展示 | - | ['精选组件', '原子组件'] | | sort.categoryList | String[] | 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列 | - | ['通用', '数据展示', '表格类', '表单类'] | ## 搜索 组件面板会提取组件的 name、title、description、keywords 等字段作为搜索匹配的目标,因此除了能够通过组件名称、描述进行搜索外,还可以指定一些关键词-keywords,keywords 是数组也可以是字符串类型。 ================================================ FILE: docs/docs/demoUsage/panels/datasource.md ================================================ --- title: 8. 数据源面板详解 sidebar_position: 4 --- ## 🪚 概述 数据源面板主要负责管理低代码中远程数据源内容,通过可视化编辑的方式操作低代码协议中的数据源 Schema,配合 [数据源引擎](/site/docs/guide/design/datasourceEngine) 即可实现低代码中数据源的生产和消费; ![image.png](https://img.alicdn.com/imgextra/i1/O1CN0170HeBg276B7fM9rqh_!!6000000007747-2-tps-2878-1642.png) 数据源面板 ## ❓如何使用 > 面板内包含了数据源创建、删除、编辑、排序、导入导出、复制以及搜索等能力,内置支持了 `fecth` & `JSONP`两种常用远程请求类型; ### 三步创建一个数据源 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01bkgbqj1cOGfwQtEif_!!6000000003590-2-tps-2878-1638.png) 三步创建数据源 ### 参数详解 > TODO ## ☠️ 更多介绍 ### 数据源顺序 > 数据源为何支持排序功能,主要原因是数据源的加载存在先后顺序;接下来我们从协议层以及实现层看数据源之间的顺序关系; TODO ### 如何定制数据源 #### 定制数据源类型(设计态) #### 定制数据源请求实现(运行态) > 当出现以下两种情况的时,我们需要定制数据源请求实现, > - 当你默认提供的 `handler`无法满足你的需求 > - 定制了数据源类型,比如 `GraphQL`,需要实现一个对应的 `handler` 接下来我们来看一个例子,如何实现一个 `handler` ```javascript import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types'; import request from 'universal-request'; import { RequestOptions, AsObject } from 'universal-request/lib/types'; export function createFetchHandler(config?: Record) { return async function(options: RuntimeOptionsConfig) { const requestConfig: RequestOptions = { ...options, url: options.uri, method: options.method as RequestOptions['method'], data: options.params as AsObject, headers: options.headers as AsObject, ...config, }; const response = await request(requestConfig); return response; }; } ``` 低代码 fetch-handler 默认实现 以上代码是低代码内置的 fetch-handler 默认实现,内部使用了 `universal-request`,假如你们内部使用的 `axios`,你完全重新实现一个; ```javascript import axios from 'axios'; export function createAxiosFetchHandler(config?: Record) { return async function(options: RuntimeOptionsConfig) { const requestConfig: RequestOptions = { ...options, url: options.uri, method: options.method as RequestOptions['method'], data: options.params, headers: options.headers, ...config, }; const response = await axios(requestConfig); return response; }; } ``` ##### 注册到 render 完成一个 Handler 后你可以通过以下方式接入到 render 或者出码中使用 ###### 渲染 Render ```tsx import React, { memo } from 'react'; import ReactRenderer from '@alilc/lowcode-react-renderer'; const SamplePreview = memo(() => { return ( ); }); ``` ###### 出码 > 目前自定义只能通过重新定义类型来完成,接下来我们会给出码添加 requestHandlersMap 映射能力;如有需求请联系 荣彬 (github-id:xingmolu) ### 设计态启用数据源引擎 > 默认情况下设计态没有开启数据源引擎,我们可以在设计器 init 的时候来传递`requstHandlersMap`来开启;具体代码如下: ```javascript import { init, plugins } from '@alilc/lowcode-engine'; import { RequestHandlersMap } from '@alilc/lowcode-datasource-types'; const preference = new Map(); (async function main() { await plugins.register(scenarioSwitcher); await registerPlugins(); init(document.getElementById('lce-container')!, { // designMode: 'live', // locale: 'zh-CN', enableCondition: true, enableCanvasLock: true, // 默认绑定变量 supportVariableGlobally: true, // simulatorUrl 在当 engine-core.js 同一个父路径下时是不需要配置的!!! // 这里因为用的是 alifd cdn,在不同 npm 包,engine-core.js 和 react-simulator-renderer.js 是不同路径 simulatorUrl: [ 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/css/react-simulator-renderer.css', 'https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@latest/dist/js/react-simulator-renderer.js' ], requestHandlersMap: { fetch: createAxiosFetchHandler() } }, preference); })(); ``` ## 🥡 附录 ### 数据源协议 | **参数** | **说明** | **类型** | **支持变量** | **默认值** | **备注** | | --- | --- | --- | --- | --- | --- | | id | 数据请求 ID 标识 | String | - | - | | | isInit | 是否为初始数据 | Boolean | ✅ | true | 值为 true 时,将在组件初始化渲染时自动发送当前数据请求 | | isSync | 是否需要串行执行 | Boolean | ✅ | false | 值为 true 时,当前请求将被串行执行 | | type | 数据请求类型 | String | - | fetch | 支持四种类型:fetch/mtop/jsonp/custom | | shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | () => true | function 参数参考 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) | | willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数(options),返回值作为请求的 options,当处理异常时,使用原 options。也可以返回一个 Promise,resolve 的值作为请求的 options,reject 时,使用原 options | | requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type=‘custom’时生效 | | dataHandler | request 成功后的回调函数 | Function | - | response => response.data | 参数:请求成功后 promise 的 value 值 | | errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | | options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见见 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) | ### 运行时实现层:数据源引擎设计 [数据源引擎设计](/site/docs/guide/design/datasourceEngine) ================================================ FILE: docs/docs/demoUsage/panels/settings.md ================================================ --- title: 6. 设置面板详解 sidebar_position: 2 --- # 设置器介绍 ## 展示区域 设置器,又称为 Setter,主要展示在编辑器的右边区域,如下图: ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01jN0toi1OknXWrPuYt_!!6000000001744-2-tps-3836-1730.png) 其中包含 属性、样式、事件、高级 - 属性:展示该物料常规的属性 - 样式:展示该物料样式的属性 - 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件。 - 高级:两个逻辑相关的属性,**条件渲染**和**循环** ## 设置器 上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。 下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Bl2hgm1GiUcXD3TOO_!!6000000000656-2-tps-2120-1460.png) 我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。 # 内置设置器 | **预置 Setter** | **用途** | | --- | --- | | StringSetter | 短文本型数据设置器,不可换行 | | NumberSetter | 数值型数据设置器, | | BoolSetter | 布尔型数据设置器, | | SelectSetter | 枚举型数据设置器,采用下拉的形式展现 | | VariableSetter | 变量型数据设置器, | | RadioGroupSetter | 枚举型数据设置器,采用 tab 选择的形式展现 | | TextAreaSetter | 长文本型数据设置器,可换行 | | DateSetter | 日期型数据设置器 | | TimePicker | 时间型数据设置器 | | DateYearSetter | 日期型 - 年数据设置器 | | DateMonthSetter | 日期型 - 月数据设置器 | | DateRangeSetter | 日期型数据设置器,可选择时间区间 | | EventsSetter | 事件绑定设置器 | | ColorSetter | 颜色设置器 | | JsonSetter | json 型数据设置器 | | StyleSetter | 样式设置器 | | ClassNameSetter | 样式名设置器 | | FunctionSetter | 函数型数据设置器 | | MixedSetter | 混合型数据设置器 | | SlotSetter | 节点型数据设置器 | | ArraySetter | 列表数组行数据设置器 | | ObjectSetter | 对象数据设置器,一般内嵌在 ArraySetter 中 | # 设置器定制 ## 编写 AltStringSetter 我们编写一个简单的 Setter,这里我们编写的 Setter 是 AltStringSetter。代码如下: ```javascript import * as React from "react"; import { Input } from "@alifd/next"; import "./index.scss"; interface AltStringSetterProps { // 当前值 value: string; // 默认值 defaultValue: string; // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; } export default class AltStringSetter extends React.PureComponent { componentDidMount() { const { onChange, value, defaultValue } = this.props; if (value == undefined && defaultValue) { onChange(defaultValue); } } // 声明 Setter 的 title static displayName = 'AltStringSetter'; render() { const { onChange, value, placeholder } = this.props; return ( onChange(val)} > ); } } ``` ### setter 和 setter/plugin 之间的联动 我们采用 emit 来进行相互之前的通信,首先我们在 A setter 中进行事件注册: ```javascript import { event } from '@ali/lowcode-engine'; componentDidMount() { // 这里由于面板上会有多个 setter,这里我用 field.id 来标记 setter 名 this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`; event.on(`${this.emitEventName}.bindEvent`, this.bindEvent) } bindEvent = (eventName) => { // do someting } componentWillUnmount() { // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多 event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) } ``` 在 B setter 中触发事件,来完成通信: ```javascript import { event } from '@ali/lowcode-engine'; bindFunction = () => { const { field, value } = this.props; // 这里展示的和插件进行通信,事件规则是插件名 + 方法 event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); } ``` ### 修改同级 props 的其他属性值 setter 本身只影响其中一个 props 的值,如果需要影响其他组件的 props 的值,需要使用 field 的 props: ```javascript bindFunction = () => { const { field, value } = this.props; const propsField = field.parent; // 获取同级其他属性 showJump 的值 const otherValue = propsField.getPropValue('showJump'); // set 同级其他属性 showJump 的值 propsField.setPropValue('showJump', false); } ``` ## 注册 AltStringSetter 我们需要在低代码引擎中注册 Setter,这样就可以通过 AltStringSetter 的名字在物料中使用了。 ```javascript import AltStringSetter from './AltStringSetter'; import { setters } from '@alilc/lowcode-engine'; setters.registerSetter({ AltStringSetter: { component: AltStringSetter, } }); ``` ## 物料中使用 我们需要将目标组件的属性值类型值配置到物料资源配置文件中,例如 `packages/demo/public/assets.json`  其中核心配置如下: ```json { "props": { "isExtends": true, "override": [ { "name": "type", "setter": "AltStringSetter" } ] } } ``` 在物料中的完整配置如下: ```json { "componentName": "Message", "title": "Message", "docUrl": "", "screenshot": "", "npm": { "package": "@alifd/next", "version": "1.19.18", "exportName": "Message", "main": "src/index.js", "destructuring": true, "subName": "" }, "props": [ { "name": "title", "propType": "string", "description": "标题", "defaultValue": "标题" }, { "name": "type", "propType": { "type": "oneOf", "value": [ "success", "warning", "error", "notice", "help", "loading" ] }, "description": "反馈类型", "defaultValue": "success" } ], "configure": { "props": { "isExtends": true, "override": [ { "name": "type", "setter": "AltStringSetter" } ] } } } ``` ### # 小结 本章介绍了设置器是什么,我们有哪些内置的设置器。以及当不满足设置器诉求时,我们如何定制一个设置器。 ================================================ FILE: docs/docs/faq/faq001.md ================================================ --- title: build-scripts 的使用文档 sidebar_position: 1 tags: [FAQ] --- build-scripts 是一个开源项目,详见 [https://github.com/ice-lab/build-scripts](https://github.com/ice-lab/build-scripts) ================================================ FILE: docs/docs/faq/faq002.md ================================================ --- title: 渲染唯一标识(key) sidebar_position: 2 tags: [FAQ] --- 渲染唯一标识(key)和 React 中组件的 key 属性的原理是一致的,都是为了在渲染场景或者组件切换的场景中唯一标识一个组件。 你可以在组件右侧配置面板的「高级」中看到此配置项,该配置项一般配合「是否渲染」和「循环」功能使用。 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01wU7y30232jgLlfzRe_!!6000000007198-2-tps-560-696.png) ## 以下场景必需设置「渲染唯一标识」 #### 场景一:同类组件切换 以下场景中,当「爱好」选择「游戏」时显示「最喜欢的游戏」,选择「运动」时显示「最喜欢的运动」 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN016qHhJB1XWRfUJsml7_!!6000000002931-2-tps-1560-588.png) 配置方式如下: 1. 增加变量数据源:hobby 2. 「最喜欢的游戏」表单标识设置为 game,「是否渲染」绑定变量「state.hobby === '游戏'」 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01oOemw41d0HY3qpwum_!!6000000003673-2-tps-2164-738.png) 3. 「最喜欢的运动」表单标识设置为 sport,「是否渲染」绑定变量「state.hobby === '运动'」 4. 「爱好」设置 onChange 动作 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oH4Giy1GTpwZwVSrO_!!6000000000624-2-tps-892-194.png) 5. 「提交」按钮绑定 onClick 动作 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN016kkf3O1uj1i9ev7uy_!!6000000006072-2-tps-750-134.png) 按以上配置(不配置渲染唯一标识),确实可以实现切换爱好时下方的文本框切换,但在提交数据时会发现,即使选择了「运动」,提交的时候 sport 字段是「最喜欢的游戏」的值。 原因:在进行文本框组件切换时,由于没有设置 key,底层会「复用」切换之前的组件 以上场景只需要给两个组件配置「渲染唯一标识」即可。 ================================================ FILE: docs/docs/faq/faq003.md ================================================ --- title: 点击事件如何添加参数 sidebar_position: 3 tags: [FAQ] --- 背景: - [Antd Table 下 button 点击事件怎么拿到行数据?](https://github.com/alibaba/lowcode-engine/issues/341) ## 方式 1 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01i58EGG1bxFJBdlS6x_!!6000000003531-2-tps-3342-1126.png) 参考 fusion protable,将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据 record,那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件 ## 方式 2 slot + 扩展参数 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01pQk2RC1WBXyxjNDif_!!6000000002750-2-tps-3284-1148.png) 将扩展参数写成: ```json { record: this.record, index: this.index } ``` 那事件处理函数的第二个参数即可得到: ```json onClick_new_new(...args){ console.log(args) } ``` ================================================ FILE: docs/docs/faq/faq004.md ================================================ --- title: 最小渲染单元配置 sidebar_position: 4 tags: [FAQ] --- ## 背景 在低代码引擎画布中,每一个节点的更新是**增量更新**机制。也就是通过 API 监听到组件的参数配置变化的时候,只更新该节点。 一些场景下,父组件需要在子组件的属性变化,获取新的子组件的属性值,也就是从父组件开始渲染。 例如:父组件需要强制修改 children props 值。示例代码如下: ``` React.Children.forEach(children, (child: React.ReactElement) => { // 子元素的参数只有 behavior,且 behavior 为 'READONLY'; const newChild = React.cloneElement(child, { behavior: 'READONLY' }); }) ``` **对于这种场景,需要配置其为“最小渲染单元”****。**即: > **最小渲染单元下的组件渲染和更新都从单元的根节点开始渲染和更新。如果嵌套了多层最小渲染单元,渲染会从最外层的最小渲染单元开始渲染。** ### 组件能力配置 component | **字段** | **用途** | **类型** | | --- | --- | --- | | isContainer(A) | 是否容器组件 | Boolean | | **isMinimalRenderUnit** | **默认值:false** **是否是最小渲染单元** | **Boolean** | | ... | | | #### 配置示例 ##### 标准配置文件 configure.component.isMinimalRenderUnit ```json { "componentName": "Table", "title": "表格", "category": "数据展示", "props": [], "configure": { "supports": { }, "props": [], "component": { // 添加如下配置 "isMinimalRenderUnit": true }, "combined": [] }, "snippets": [], "npm": {} } ``` ## 更新机制说明 1. 没有任何组件被标识为**最小渲染单元**,则是每个组件都伴随自身属性变更而重新渲染; 2. 将根组件标识为**最小渲染单元**,则是整个页面重新渲染; 3. 组件树的分支节点被标识为**最小渲染单元**,则分支节点之下(包括自身)节点属性变更,触发分支节点整体的重新渲染;(若有多个**最小渲染单元**在同一条路径上,从最外层的**最小渲染单元**开始渲染) ================================================ FILE: docs/docs/faq/faq005.md ================================================ --- title: 如何通过 this.utils 使用第三方工具扩展 sidebar_position: 5 tags: [FAQ] --- ## 设计器 ### 通过引擎 API 配置 [API-init](/site/docs/api/init) ### 通过资产包 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01WWJVSA1WutBvCzXnl_!!6000000002849-2-tps-806-788.png) 就可以在引擎代码中访问到 moment ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01EEJ0Kp1nZgJm68nSG_!!6000000005104-2-tps-1248-252.png) PS:需要在 packages 中有相关的资源配置,例如: ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01bdiHVv206uRYvvAAr_!!6000000006801-2-tps-1322-420.png) 否则在画布中可能会访问不到对应的资源。 ## 预览态 [参考资料](/site/docs/guide/expand/runtime/renderer#apphelper) ================================================ FILE: docs/docs/faq/faq006.md ================================================ --- title: 如何通过 API 手动调用数据源请求 sidebar_position: 6 tags: [FAQ] --- 参考:[DataSource API](/site/docs/demoUsage/appendix/api) ================================================ FILE: docs/docs/faq/faq007.md ================================================ --- title: 设置面板中的高级 tab 如何配置 sidebar_position: 7 tags: [FAQ] --- ![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://img.alicdn.com/imgextra/i4/O1CN01lVutr6243wL6gOQAc_!!6000000007336-2-tps-960-1714.png) 默认这个 tab 下的内容为引擎内置,如需要定制,可以使用以下 API [https://lowcode-engine.cn/site/docs/api/material#物料元数据管道函数](https://lowcode-engine.cn/site/docs/api/material#物料元数据管道函数) ================================================ FILE: docs/docs/faq/faq008.md ================================================ --- title: 某某 npm 包对应的源码在哪里? sidebar_position: 8 tags: [FAQ] --- 详见 [NPM 包对应源码位置汇总](/site/docs/guide/appendix/npms) ================================================ FILE: docs/docs/faq/faq009.md ================================================ --- title: 物料出现 Component Not Found 相关报错 sidebar_position: 9 tags: [FAQ] --- ## 预览态,antd 资产包按顺序加载,但是没有按顺序执行 资产包按顺序加载,但是没有按顺序执行,导致部分 js 执行的时候,依赖的资源没有准备好,报错了。 传给 @alilc/lowcode-react-renderer 的 components 值为空。 **解决方案** LowCodeEngine 升级到 1.0.8 > 相关 PR:[https://github.com/alibaba/lowcode-engine/pull/383](https://github.com/alibaba/lowcode-engine/pull/383) ## 编辑态,snippets 和注入组件不对应 1.在控制台中输入 ```json AliLowCodeEngine.material.componentsMap ``` 查看物料配置是否正常。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01bAsPoT1QOTSp7Fmz5_!!6000000001966-2-tps-1640-816.png) 如果正常继续。 LowCodeEngine 需要升级到 1.0.10 ```json AliLowCodeEngine.project.simulator.renderer.components ``` 看看对应的物料是否存在,如果不存在,排查物料问题。 如果不正常,查看资产包配置,其中资产包中的 `components` 和 `material.componentsMap` 生成有关系。 例如,物料配置信息在 @alilc/lowcode-materials 包里面,即需要在 components 中加上下面的代码 ```javascript "components": [{ "exportName": "AlilcLowcodeMaterialsMeta", "npm": { "package": "@alilc/lowcode-materials" }, "url": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", "urls": { "default": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.js", "design": "https://alifd.alicdn.com/npm/@alilc/lowcode-materials@1.0.7/build/lowcode/meta.design.js" } }] ``` `material.componentsMap` 不存在相关的组件信息,原因有两个: - 没有添加对应的物料到 components 字段中 - components 配置不正确,需要查看 url 是否正常加载,查看 exportName 是否配置正确,即 `window.${exportName}` 是否存在。 2.选中组件,在控制台中输入 ```json AliLowCodeEngine.project.currentDocument.selection.getNodes()[0].exportSchema('render') ``` 查看 componentName 是否匹配。 3.调用 rerender 方法 ```json AliLowCodeEngine.project.simulator.rerender() ``` 看一下问题是否恢复。 ## 排查物料问题 找到对应组件的资产包,比如下图的资产包。 ```json { "package": "@yingzhi8/lowcode-public-package", "version": "0.1.2", "library": "BizComps", "urls": [ "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/render/default/view.js", "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/render/default/view.css" ], "editUrls": [ "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/view.js", "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/view.css" ], "advancedUrls": { "default": [ "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/render/default/view.js", "https://unpkg.com/@yingzhi8/lowcode-public-package@0.1.2/build/lowcode/render/default/view.css" ] }, "advancedEditUrls": {} } ``` ### 查看 urls 是否加载 通过查看控制台,看加载的 urls ### library 配置是否正确 library 是可以在画布上访问到全局变量,确定 library 是否正确,在控制台输入: ```json AliLowCodeEngine.project.simulator.contentWindow.${library} ``` ================================================ FILE: docs/docs/faq/faq010.md ================================================ --- title: 插件面板如何调整位置 sidebar_position: 10 tags: [FAQ] --- 使用 index 配置来定义位置,内置的默认都是 0 ```json AliLowCodeEngine.skeleton.add({ area: 'leftArea', type: 'PanelDock', name: 'xxx', content: () => 'xxx', index: -1, // 使用 index 来定义位置,内置的默认都是 0 props: { icon: () => 'x' /* ReactElement 也可以 */ }, }); ``` 这里设置 index 为负数,可以将其调整到第一的位置。 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01PTCH3r20fiXrrbcXe_!!6000000006877-2-tps-1614-1158.png) ================================================ FILE: docs/docs/faq/faq011.md ================================================ --- title: 如何获取物料当前处于编辑态还是渲染态 sidebar_position: 11 tags: [FAQ] --- ## 简单场景 可以利用 props.__designMode ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01btr66024FOEldBOr2_!!6000000007361-2-tps-1616-440.png) 设计态中,__designMode 值为 "design" 渲染态中,__designMode 没有设置值 ## 复杂场景 在资产包里定义 editUrls ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01odal6P27Rhjn8NoJ6_!!6000000007794-2-tps-1590-538.png) ### editUrls 在 lowcode/xx/ 下新建一个 view.tsx ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01q0Bbn91Lrig7d0alA_!!6000000001353-2-tps-598-154.png) 再执行 ```json npm run lowcode:build ``` 之后,build/lowcode 目录下既有 view.js,可作为 editUrls 配置在资产包中。 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01dvIZ441alxwIlwexS_!!6000000003371-2-tps-1082-986.png) ================================================ FILE: docs/docs/faq/faq012.md ================================================ --- title: Procode 物料如何调用数据源方法 sidebar_position: 12 tags: [FAQ] --- ## 解决方案 给物料插入如下配置,可以默认给物料提供 reloadDataSource 的参数。 ```json { title: { label: { type: 'i18n', 'en-US': 'reloadDataSource', 'zh-CN': 'reloadDataSource', }, }, name: 'reloadDataSource', setter: 'StringSetter', initialValue: () => ( { "type": "JSFunction", "value": "function(){ return this.reloadDataSource; }" } ), }, ``` 在物料组件中,即可掉用如下代码来获取到相关方法。 ```json const reloadDataSource = props.getReloadDataSource() ``` ## FAQ ### 希望该配置在配置面板中不展示 在配置中加上 ```json condition: () => false, ``` 完整示例 ```json { title: { label: { type: 'i18n', 'en-US': 'reloadDataSource', 'zh-CN': 'reloadDataSource', }, }, name: 'reloadDataSource', setter: 'StringSetter', condition: () => false, initialValue: () => ( { "type": "JSFunction", "value": "function(){ return this.reloadDataSource; }" } ), }, ``` ### 配置没有生效 查看组件中的 schema,对应的配置是否已经正确设置。 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN015AGT4l1MwaVGGwgua_!!6000000001499-2-tps-1046-1154.png) 没有正确设置上可能的原因是 1.snippets 中没有默认值 需要按照如下的代码中,加上默认的参数配置 ```json const snippets: Snippet[] = [ { title: 'Field', screenshot: '', schema: { componentName: 'ProField', props: { type: 'textarea', value: '我是测试', getReloadDataSource: { "type": "JSFunction", "value": "function(){ return this.reloadDataSource; }" } }, }, }, ]; ``` ### 如何全局生效 通过 [registerMetadataTransducer API](/site/docs/api/material#registermetadatatransducer) 来修改元数据信息,注意如果有 snippets 相关配置也需要修改相关的配置。 ================================================ FILE: docs/docs/faq/faq013.md ================================================ --- title: Modal 类组件 hidden 属性被强制设置 true sidebar_position: 13 tags: [FAQ] --- ## 注意 弹窗的正确弹出方式请参考:[如何通过按钮展示/隐藏弹窗](/site/docs/demoUsage/makeStuff/dialog) ## 问题原因 由于 hidden 属性,导致 Modal 组件在预览的时候不渲染,也就无法获取到实例。 ## 处理方式 ### 【推荐】升级到 Engine Verison 1.0.11 以上 ### 新增 save propsReducer 通过新增 Save 态的 propsReducer,将 hidden props 去掉。可以参考下面的代码: ```typescript import { project } from '@alilc/lowcode-engine'; import { IPublicEnumTransformStage } from '@alilc/lowcode-types'; export const deleteHiddenTransducer = (ctx: any) => { return { name: 'deleteHiddenTransducer', async init() { project.addPropsTransducer((props: any): any => { delete props.hidden; return props; }, IPublicEnumTransformStage.Save); }, }; } deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer'; ``` ### 导出 schema 使用 Save 态 ```typescript import { TransformStage } from '@alilc/lowcode-types'; const schema = project.exportSchema(TransformStage.Save) ``` ================================================ FILE: docs/docs/faq/faq014.md ================================================ --- title: VERSION_PLACEHOLDER is not defined sidebar_position: 14 tags: [FAQ] --- # 问题原因 由于 lowcode-engine 目前只提供 cdn 的使用方式。如果是自己创建的项目,遇到这个报错了,主要是因为将 npm 包打包进去了。 # 解决方案 ## engine-demo 项目 在项目的 externals 配置里加[一行配置](https://github.com/alibaba/lowcode-demo/blob/f8afad0df3190565caccc0a1dfd750dbf84c680f/build.json#L16) ## 其他项目 [相关文档](/site/docs/guide/create/useEditor#引入-umd-包资源) ### webpack [https://webpack.docschina.org/configuration/externals/](https://webpack.docschina.org/configuration/externals/) ### 使用文档 待补充 ================================================ FILE: docs/docs/faq/faq015.md ================================================ --- title: 已有组件如何快速接入引擎 sidebar_position: 15 tags: [FAQ] --- 你可以通过在线工具「Parts 造物」生产物料描述协议,然后使用到你的项目中去。 文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/parts/partsIntro) ================================================ FILE: docs/docs/faq/faq016.md ================================================ --- title: Cannot read property 'Icon' of Undefined sidebar_position: 16 tags: [FAQ] --- @alifd/next 是 React 画布下必须的资源,不能省略。 需要在资产包中检查是否有下列代码: ```typescript { "title": "fusion 组件库", "package": "@alifd/next", "version": "1.23.0", "urls": [ "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next.min.css", "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next-with-locales.min.js" ], "library": "Next" }, ``` ================================================ FILE: docs/docs/faq/faq017.md ================================================ --- title: vue 画布支持说明 sidebar_position: 17 tags: [FAQ] --- #### 低代码引擎官方是否支持 Vue 画布 短期没有支持的计划 #### 社区研发的 Vue 画布 ##### 肯耐珂萨团队实现的 Vue 画布 github:[https://github.com/KNXCloud/lowcode-engine-vue](https://github.com/KNXCloud/lowcode-engine-vue) ================================================ FILE: docs/docs/faq/faq018.md ================================================ --- title: 是否可以生成 Vue 页面代码? sidebar_position: 18 tags: [FAQ] --- 低代码引擎在架构上是和具体语言无关的,通过一定的扩展和插件是可以生成 Vue 页面代码的。 如果只是用现有的基于 React 的 fusion 物料来搭建,只是在最终出码的时候生成 Vue 页面代码,那您需要准备一套和 fusion 兼容的 vue 物料,并定制个出码方案,将[下面的一些出码插件](https://github.com/alibaba/lowcode-engine/blob/main/modules/code-generator/src/solutions/icejs.ts)替换成生成 Vue 框架的即可: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01VxkwCL1l85DiDC2BO_!!6000000004773-2-tps-974-1368.png) 详细定制方案可以参考下[《自定义出码》](/site/docs/guide/expand/runtime/codeGeneration#5自定义出码)。 如果您希望在搭建的时候也使用 Vue 的物料,则还需要扩展定制入料、画布和渲染器等模块,详细方案请参考下[《扩展低代码编辑器》](/site/docs/guide/expand/editor/summary) ================================================ FILE: docs/docs/faq/faq019.md ================================================ --- title: windows 下运行出现报错 sidebar_position: 19 tags: [FAQ] --- 由于阿里内部研发人员没有 windows 开发的诉求,windows 环境下相关的技术兼容短期内暂时没有支持计划。 辛苦使用 [WSL](https://docs.microsoft.com/zh-cn/windows/wsl/install) 在 windows 下进行低代码引擎相关的开发。 如果可以的话,欢迎大佬们提 PR 对 windows 开发环境进行兼容方面的支持。 ================================================ FILE: docs/docs/faq/faq020.md ================================================ --- title: Can't import the named export from non ECMAScript module sidebar_position: 20 tags: [FAQ] --- 如果您是自己配置的引擎打包,那么可能会遇到这个问题。 ![image.png](https://img.alicdn.com/imgextra/i3/O1CN013xHmcz1WBXygt7VvC_!!6000000002750-2-tps-1912-984.png) 问题的根源是 code-editor 插件运行时直接依赖了 babel 来完成 jsx 编译,babel 从 7.17.0 开始依赖了使用 ESM 编写的 @ampproject/remapping@2.1.0。如果打包工具无法正确处理 ESM,则可能报错。 解决方案 1:锁定 babel 版本 如果您使用了 yarn,那么可以在 package.json 中: ```typescript "resolutions": { "@babel/core": "~7.16.7", "@babel/parser": "~7.16.7", "@babel/preset-env": "~7.16.7", "@babel/preset-react": "~7.16.7", "@babel/standalone": "~7.16.7", "@babel/traverse": "~7.16.7", "@babel/types": "~7.16.7" } ``` 解决方案 2:编译层面配置。本例使用 build-script 配置,您可以用类似方法来配置您的 webpack: ```typescript module.exports = ({ onGetWebpackConfig }) => { // see: https://github.com/ice-lab/build-scripts#%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91 onGetWebpackConfig((config) => { config.module // fixes https://github.com/graphql/graphql-js/issues/1272 .rule('mjs$') .test(/\.mjs$/) .include .add(/node_modules/) .end() .type('javascript/auto'); return config; }); }; ``` ================================================ FILE: docs/docs/faq/faq021.md ================================================ --- title: 提交 PR 时,明明签署过 CLA,仍被提示需要签署 sidebar_position: 21 tags: [FAQ] --- ## 问题原因 原因是:git commit 时,本地 git config 配置的 email 与 github 账号的 email 不一致,导致未被识别出来,检查方式 ```bash git config user.email ``` ## 解决办法 如何配置,可参考 [is-it-possible-to-have-different-git-configuration-for-different-projects](https://stackoverflow.com/questions/8801729/is-it-possible-to-have-different-git-configuration-for-different-projects) 配置好正确的 email 之后,已提交的代码需要以新的配置重新提交才可生效。 ================================================ FILE: docs/docs/faq/faq022.md ================================================ --- title: 节点无法拖拽到 Page 下 sidebar_position: 22 tags: [FAQ] --- 查看 Page 节点的 childWhitelist 配置,如果 Page 配置了 childWhitelist,且当前节点不在白名单下,是无法拖拽的。 ```typescript AliLowCodeEngine.material.getComponentMeta('Page').getMetadata().configure.component.nestingRule.childWhitelist ``` 比如在 [demo](https://lowcode-engine.cn/demo/demo-general/index.html) 中 Page 组件的 childWhitelist 为:['NextPage', 'ProDialog', 'Dialog', 'Drawer'],则只有这些组件可以拖拽到 Page 的 children 下,其他组件均不可以。 说明:1.0.15 之前 Page 组件的 childWhitelist 限制是失效的,在 1.0.16 版本进行了 bug 修复。 ### 解决办法 **方法 1:直接修改 Page 组件的 childWhitelist,比如删除**。 **方法 2:通过 **[**material.registerMetadataTransducer**](/site/docs/api/material#registermetadatatransducer)** 修改 Page 组件的 childWhitelist(适用于 Page 组件是其他人维护的)** ================================================ FILE: docs/docs/faq/faq023.md ================================================ --- title: Slot组件渲染报错问题 sidebar_position: 23 tags: [FAQ] --- ## 问题描述 在低代码引擎的页面渲染过程中,可能会遇到一个关于Slot组件的报错,提示“Slot找不到”。实际上,在渲染态时不应使用Slot组件。 ## 问题原因 低代码引擎渲染分为两个状态:设计态和渲染态。 - **设计态**:为了帮助插槽进行可视化设计,引入了Slot组件。 - **渲染态**:在此状态下,不需要使用Slot组件。 这个问题通常是因为在渲染态错误地使用了设计态的schema。 ## 解决方案 1. **区分设计态和渲染态**:通过`project.exportSchema(TransformStage.Save)`的参数来区分。 - `TransformStage.Save`代表渲染态的schema,其中不包含Slot组件。 - 【默认值】`TransformStage.Render`代表设计态的schema,其中包含Slot组件。 2. **使用正确的API和参数**:确保在渲染态使用正确的schema,避免引用设计态的Slot组件。 3. **处理脏数据问题**:如果问题是由脏数据导致,清除数据并重新拖拽组件以恢复正常。 ## 注意事项 - 确保在代码和配置中正确区分设计态和渲染态。 - 如果遇到持续的问题,检查是否有脏数据或配置错误,并进行相应的清理和调整。 ## 相关链接 - Issue链接:[Issue #1798](https://github.com/alibaba/lowcode-engine/issues/1798) --- ================================================ FILE: docs/docs/faq/faq024.md ================================================ --- title: workspace 模式常见问题 sidebar_position: 23 tags: [FAQ] --- #### 如何判断是否开启了IDE模式? - **通过官方API判断**:您可以通过访问 [workspace.isActive](/site/docs/api/workspace#isactive) 来判断当前是否处于IDE模式。这是阿里低代码引擎提供的一个官方API,专门用于确认是否处于集成开发环境。 #### 如何使用插件的ctx来做判断在哪个模式下? - **插件是否为应用级别**:可以通过 **ctx.isPluginRegisteredInWorkspace** 方法来判断一个插件是否是应用级别的插件。这有助于理解插件在阿里低代码引擎中的作用域和潜在的使用场景。 - **插件的注册级别**:您可以使用 **ctx.registerLevel** 属性来判断插件处于哪个级别。插件级别的值包括: - **Default**:默认级别。非 IDE 模式下的值 - **Workspace**:应用级别。 - **Resource**:资源级别。 - **EditorView**:编辑视图级别。 这些级别代表了插件可能的作用域和使用场景,有助于在开发和管理低代码应用时对插件进行更精确的控制和配置。 #### 如何在IDE模式下设置资源列表? - **设置资源列表API**:在IDE模式下,可以通过访问 [workspace.setResourceList](/site/docs/api/workspace#setresourcelist) 来设置或更新IDE中的资源列表。这确保您在编辑器窗口中打开的资源是最新且可访问的。 #### 如何打开视图窗口? - **使用推荐的方法**:使用 `openEditorWindow(resource: Resource, sleep?: boolean): Promise;` 来打开视图窗口。这里的 **resource** 参数指的是您要打开的特定资源,可通过 [workspace.resourceList](/site/docs/api/workspace#resourcelist) 获取。 - **不推荐使用的过时方法**:有一个过时的方法 `openEditorWindow(resourceName: string, id: string, extra: Object, viewName?: string, sleep?: boolean): Promise;` 也用于打开视图窗口。虽然仍然可用,但官方不推荐使用此方法,并计划在后续版本中废弃,因为它在维护和可扩展性方面存在限制。 #### 如何在全局插件中获取视图的上下文? - 在阿里低代码引擎的全局插件中获取视图的上下文,可以通过使用 **ProvideViewPluginContext** 函数实现。这个函数来自 **@alilc/lowcode-utils** 库,它使得您的 React 组件能够接收 **pluginContext** 作为 props,进而访问和操作当前视图的状态和属性。 **步骤** **引入依赖**:首先,确保您的插件文件中已经引入了 **ProvideViewPluginContext** 以及其他必要的依赖。 ``` import { ProvideViewPluginContext } from '@alilc/lowcode-utils'; ``` **定义 React 组件**:创建一个 React 组件,它将使用来自 **ProvideViewPluginContext** 的 **pluginContext**。 ```typescript const MyComponent = (props) => { const { pluginContext } = props; // 组件逻辑 return
/* 组件内容 */
; }; ``` **定义全局插件**:定义一个函数,这个函数会在插件被注册时调用。这个函数通常接受一个上下文对象 **ctx**,它提供了对引擎功能的访问。 ```javascript const globalPlugin = (ctx) => { const { skeleton } = ctx; skeleton.add({ type: 'PanelDock', name: 'datapool', content: ProvideViewPluginContext((props) => { // 组件内容 return ( ) }), // 其他配置 contentProps: { // 需要提供 pluginContext 作为参数 pluginContext: ctx, } }); }; ``` 通过这些步骤,您的全局插件中的 React 组件就能够获取并使用视图的上下文了。这为您在插件中实现更复杂的功能和交互提供了基础。 **注意事项** - **组件重渲染**:正常情况下,**pluginsContext** 是视图的上下文。当视图切换时,组件会重新渲染。如果需要在组件中处理视图切换导致的重新渲染,可以利用 React 的 **key** 属性。 **示例代码** ```typescript ProvideViewPluginContext(props => { return (