From b486a8419cf1f02ad757b2cb279f111e0f7b2fde Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 00:07:43 +0800 Subject: [PATCH 01/12] optimize structure --- .../bem-tools/border-hovering.tsx | 3 +- .../bem-tools/border-selecting.tsx | 26 +- .../src/builtin-simulator/bem-tools/index.tsx | 2 +- .../builtin-simulator/bem-tools/insertion.tsx | 4 +- .../src/builtin-simulator/create-simulator.ts | 4 +- .../src/builtin-simulator/host-view.tsx | 2 +- .../designer/src/builtin-simulator/host.ts | 11 +- .../builtin-simulator/resource-consumer.ts | 2 +- .../builtin-simulator/utils/parse-metadata.ts | 4 +- .../src/builtin-simulator/viewport.ts | 2 +- packages/designer/src/component-meta.ts | 51 ++- .../designer/src/designer/builtin-hotkey.ts | 7 +- .../designer/src/designer/designer-view.tsx | 1 - packages/designer/src/designer/designer.ts | 6 +- .../src/designer/drag-ghost/index.tsx | 2 +- packages/designer/src/designer/dragon.ts | 6 +- packages/designer/src/designer/hovering.ts | 2 +- .../designer/src/designer/offset-observer.ts | 4 +- packages/designer/src/designer/scroller.ts | 2 +- .../src/designer/setting/setting-entry.ts | 2 +- .../src/designer/setting/setting-field.ts | 3 +- .../designer/setting/setting-prop-entry.ts | 4 +- .../src/designer/setting/setting-top-entry.ts | 3 +- .../designer/src/document/document-model.ts | 29 +- .../designer/src/document/document-view.tsx | 2 +- packages/designer/src/document/history.ts | 3 +- .../src/document/node/exclusive-group.ts | 5 +- .../src/document/node/node-children.ts | 3 +- packages/designer/src/document/node/node.ts | 17 +- .../src/document/node/props/prop-stash.ts | 2 +- .../designer/src/document/node/props/prop.ts | 16 +- .../designer/src/document/node/props/props.ts | 6 +- packages/designer/src/document/selection.ts | 2 +- packages/designer/src/icons/clone.tsx | 2 +- packages/designer/src/icons/component.tsx | 2 +- packages/designer/src/icons/container.tsx | 2 +- packages/designer/src/icons/hidden.tsx | 2 +- packages/designer/src/icons/page.tsx | 2 +- packages/designer/src/icons/remove.tsx | 2 +- packages/designer/src/icons/setting.tsx | 2 +- packages/designer/src/locale/index.ts | 2 +- .../designer/src/project/project-view.tsx | 2 +- packages/designer/src/project/project.ts | 3 +- packages/designer/src/simulator.ts | 2 +- packages/editor-core/CHANGELOG.md | 47 --- packages/editor-core/README.md | 12 +- packages/editor-core/build.json | 6 +- .../{globals => editor-core}/cloud-build.json | 0 packages/editor-core/package.json | 51 ++- packages/editor-core/src/areaManager.ts | 75 ---- packages/editor-core/src/context.ts | 4 - .../{globals => editor-core}/src/di/index.ts | 3 +- .../src/di/ioc-context.ts | 0 .../{globals => editor-core}/src/di/setter.ts | 5 +- packages/editor-core/src/editor.ts | 151 +------ .../src/utils => editor-core/src}/hotkey.ts | 0 packages/editor-core/src/index.ts | 17 +- .../src/intl/ali-global-locale.ts | 3 +- .../src/intl/index.ts} | 133 +++---- packages/editor-core/src/pluginFactory.tsx | 84 ---- packages/editor-core/src/utils.ts | 273 ------------- .../editor-core/src/{ => utils}/app-preset.ts | 0 .../src/utils/get-public-path.ts | 0 packages/editor-core/src/utils/goldlog.ts | 11 + packages/editor-core/src/utils/index.ts | 4 + .../index.ts => editor-core/src/utils/obx.ts} | 0 .../editor-core/src/{ => utils}/request.ts | 14 +- .../src/widgets}/index.ts | 2 +- packages/editor-core/src/widgets/tip/index.ts | 4 + .../src/widgets}/tip/style.less | 0 .../src/widgets}/tip/tip-container.tsx | 8 +- .../src/widgets}/tip/tip-handler.ts | 98 ++--- .../src/widgets/tip/tip-item.tsx} | 9 +- packages/editor-core/src/widgets/tip/tip.tsx | 17 + .../src/widgets}/tip/utils.ts | 0 .../src/widgets}/title/index.tsx | 12 +- .../src/widgets}/title/title.less | 0 packages/editor-core/tsconfig.json | 4 +- packages/editor-skeleton/src/area.ts | 59 +++ .../src/components/LeftPlugin/index.scss | 59 --- .../src/components/LeftPlugin/index.tsx | 221 ----------- .../src/components/Panel/index.scss | 52 --- .../src/components/Panel/index.tsx | 60 --- .../src/components/TopIcon/index.scss | 77 ---- .../src/components/TopIcon/index.tsx | 63 --- .../src/components/TopPlugin/index.scss | 2 - .../src/components/TopPlugin/index.tsx | 219 ---------- .../src/components/array-setter/bugs.md | 5 + .../src/components/array-setter/index.tsx | 280 +++++++++++++ .../src/components/array-setter/sortable.less | 29 ++ .../src/components/array-setter/sortable.tsx | 220 ++++++++++ .../src/components/array-setter/style.less | 103 +++++ .../src/components/field/fields.tsx | 185 +++++++++ .../src/components/field/index.less | 154 +++++++ .../src/components/field/index.ts | 28 ++ .../src/components/mixed-setter/index.tsx | 262 ++++++++++++ .../src/components/mixed-setter/style.less | 30 ++ .../src/components/object-setter/index.tsx | 181 +++++++++ .../src/components/object-setter/style.less | 31 ++ .../src/components/popup/index.tsx | 150 +++++++ .../src/components/popup/style.less | 22 + .../src/components/settings/index.ts | 7 + .../src/components/settings/main.ts | 84 ++++ .../src/components/settings/package.json | 49 +++ .../src/components/settings/register.ts | 30 ++ .../src/components/settings/settings-pane.tsx | 152 +++++++ .../settings/settings-primary-view.tsx | 121 ++++++ .../src/components/settings/style.less | 124 ++++++ .../settings/transducers/addon-combine.ts | 255 ++++++++++++ .../settings/transducers/parse-props.ts | 232 +++++++++++ .../settings/transducers/register.ts | 9 + .../src/components/settings/utils.js | 41 ++ .../src/components/widget-views.tsx | 236 +++++++++++ .../editor-skeleton/src/config/skeleton.ts | 1 - packages/editor-skeleton/src/config/utils.ts | 1 - packages/editor-skeleton/src/dock.ts | 87 ++++ packages/editor-skeleton/src/global.scss | 33 -- .../editor-skeleton/src/icons/convert.tsx | 16 + packages/editor-skeleton/src/index.ts | 10 +- .../src/layouts/CenterArea/index.scss | 3 - .../src/layouts/CenterArea/index.tsx | 60 --- .../src/layouts/LeftArea/index.scss | 23 -- .../src/layouts/LeftArea/index.tsx | 7 - .../src/layouts/LeftArea/nav.tsx | 148 ------- .../src/layouts/LeftArea/panel.tsx | 88 ---- .../src/layouts/RightArea/index.scss | 39 -- .../src/layouts/RightArea/index.tsx | 214 ---------- .../src/layouts/TopArea/index.scss | 30 -- .../src/layouts/TopArea/index.tsx | 102 ----- .../src/layouts/bottom-area.tsx | 37 ++ .../editor-skeleton/src/layouts/left-area.tsx | 41 ++ .../src/layouts/left-fixed-pane.tsx | 50 +++ .../src/layouts/left-float-pane.tsx | 73 ++++ .../editor-skeleton/src/layouts/main-area.tsx | 21 + .../src/layouts/right-area.tsx | 35 ++ .../src/layouts}/theme.less | 0 .../editor-skeleton/src/layouts/toolbar.tsx | 49 +++ .../editor-skeleton/src/layouts/top-area.tsx | 44 ++ .../src/layouts}/workbench.less | 0 .../editor-skeleton/src/layouts/workbench.tsx | 40 ++ packages/editor-skeleton/src/locale/en-US.js | 1 - packages/editor-skeleton/src/locale/ja-JP.js | 1 - packages/editor-skeleton/src/locale/zh-CN.js | 1 - packages/editor-skeleton/src/locale/zh-TW.js | 1 - packages/editor-skeleton/src/panel.ts | 166 ++++++++ packages/editor-skeleton/src/skeleton.ts | 318 +++++++++++++++ packages/editor-skeleton/src/skeleton.tsx | 185 --------- packages/editor-skeleton/src/types.ts | 114 ++++++ .../src/widget}/dialog-dock.ts | 0 packages/editor-skeleton/src/widget/dock.ts | 87 ++++ .../editor-skeleton/src/widget/panel-dock.ts | 118 ++++++ packages/editor-skeleton/src/widget/panel.ts | 166 ++++++++ .../src/widget}/stage.ts | 4 +- .../src/widget}/utils.ts | 0 .../src/widget}/widget-container.ts | 0 packages/editor-skeleton/src/widget/widget.ts | 101 +++++ packages/globals/CHANGELOG.md | 78 ---- packages/globals/README.md | 3 - packages/globals/build.json | 9 - .../globals/src/components/tip/embed-tip.tsx | 17 - packages/globals/src/components/tip/index.ts | 4 - packages/globals/src/di/editor.ts | 33 -- packages/globals/src/di/transducer.ts | 31 -- packages/globals/src/index.ts | 6 - packages/plugin-components-pane/src/index.tsx | 2 +- .../plugin-event-bind-dialog/src/index.tsx | 2 +- .../src/helper/indent-track.ts | 6 +- .../src/icons/arrow-right.tsx | 2 +- .../plugin-outline-pane/src/icons/cond.tsx | 2 +- .../src/icons/eye-close.tsx | 2 +- .../plugin-outline-pane/src/icons/eye.tsx | 2 +- .../plugin-outline-pane/src/icons/lock.tsx | 2 +- .../plugin-outline-pane/src/icons/loop.tsx | 2 +- .../plugin-outline-pane/src/icons/outline.tsx | 2 +- .../plugin-outline-pane/src/icons/slot.tsx | 2 +- .../plugin-outline-pane/src/icons/unlock.tsx | 2 +- .../plugin-outline-pane/src/locale/index.ts | 2 +- packages/plugin-outline-pane/src/main.ts | 6 +- packages/plugin-outline-pane/src/tree-node.ts | 5 +- .../plugin-outline-pane/src/views/pane.tsx | 2 +- .../src/views/tree-branches.tsx | 2 +- .../src/views/tree-node.tsx | 2 +- .../src/views/tree-title.tsx | 13 +- .../plugin-outline-pane/src/views/tree.tsx | 5 +- packages/plugin-sample-logo/src/index.tsx | 2 +- packages/plugin-sample-preview/src/index.tsx | 2 +- packages/plugin-source-editor/src/index.tsx | 2 +- .../plugin-variable-bind-dialog/src/index.tsx | 10 +- packages/plugin-zh-en/src/index.tsx | 6 +- .../src/renderer-view.tsx | 2 +- .../react-simulator-renderer/src/renderer.ts | 10 +- .../src/utils/get-client-rects.ts | 2 +- .../src/utils/loader.ts | 2 +- .../src/utils/react-find-dom-nodes.ts | 2 +- packages/setters/package.json | 2 +- packages/setters/src/index.tsx | 2 - packages/setters/src/mixin-setter/index.tsx | 2 +- packages/setters/src/style-setter/index.tsx | 2 +- packages/types/README.md | 1 + packages/types/build.json | 5 + packages/{globals => types}/package.json | 42 +- .../src/types => types/src}/data-source.ts | 0 .../definitions.ts => types/src/editor.ts} | 72 ++-- .../src/types => types/src}/field-config.ts | 1 - .../{globals/src/types => types/src}/i18n.ts | 0 .../{globals/src/types => types/src}/icon.ts | 0 .../{globals/src/types => types/src}/index.ts | 1 + .../src/types => types/src}/metadata.ts | 0 .../{globals/src/types => types/src}/npm.ts | 0 .../src/types => types/src}/prop-config.ts | 0 .../src/types => types/src}/schema.ts | 0 .../src/types => types/src}/setter-config.ts | 3 +- .../src/types => types/src}/setting-target.ts | 2 +- .../{globals/src/types => types/src}/tip.ts | 0 .../{globals/src/types => types/src}/title.ts | 1 - .../{globals/src/types => types/src}/utils.ts | 0 .../src/types => types/src}/value-type.ts | 0 packages/{globals => types}/tsconfig.json | 4 +- packages/utils/package.json | 0 .../{globals/src/utils => utils/src}/asset.ts | 0 .../src/utils => utils/src}/clone-deep.ts | 0 .../src/utils => utils/src}/create-content.ts | 0 .../src/utils => utils/src}/create-icon.tsx | 4 +- .../src/utils => utils/src}/cursor.less | 0 .../src/utils => utils/src}/cursor.ts | 0 .../utils => utils/src}/get-prototype-of.ts | 0 .../utils => utils/src}/has-own-property.ts | 0 .../{globals/src/utils => utils/src}/index.ts | 12 +- .../src/utils => utils/src}/is-css-url.ts | 0 .../src/utils => utils/src}/is-element.ts | 0 .../src/utils => utils/src}/is-es-module.ts | 0 .../src/utils => utils/src}/is-form-event.ts | 0 .../src/utils => utils/src}/is-function.ts | 0 .../src/utils => utils/src}/is-object.ts | 0 .../utils => utils/src}/is-plain-object.ts | 0 .../src/utils => utils/src}/is-react.ts | 0 .../utils => utils/src}/navtive-selection.ts | 0 .../utils => utils/src}/set-prototype-of.ts | 0 .../src/utils => utils/src}/shallow-equal.ts | 0 .../src/components => utils/src}/svg-icon.tsx | 0 .../src/utils => utils/src}/unique-id.ts | 0 packages/vision-polyfill/src/skeleton/area.ts | 4 +- .../skeleton/components/array-setter/bugs.md | 5 + .../components/array-setter/index.tsx | 279 +++++++++++++ .../components/array-setter/sortable.less | 29 ++ .../components/array-setter/sortable.tsx | 220 ++++++++++ .../components/array-setter/style.less | 103 +++++ .../src/skeleton/components/field/fields.tsx | 184 +++++++++ .../src/skeleton/components/field/index.less | 154 +++++++ .../src/skeleton/components/field/index.ts | 28 ++ .../components/mixed-setter/index.tsx | 257 ++++++++++++ .../components/mixed-setter/style.less | 30 ++ .../components/object-setter/index.tsx | 180 +++++++++ .../components/object-setter/style.less | 31 ++ .../src/skeleton/components/popup/index.tsx | 150 +++++++ .../src/skeleton/components/popup/style.less | 22 + .../src/skeleton/components/register.ts | 29 ++ .../src/skeleton/components/settings/index.ts | 9 + .../src/skeleton/components/settings/main.ts | 89 +++++ .../skeleton/components/settings/package.json | 49 +++ .../components/settings/settings-pane.tsx | 149 +++++++ .../settings/settings-primary-view.tsx | 121 ++++++ .../skeleton/components/settings/style.less | 124 ++++++ .../src/skeleton/components/settings/utils.js | 41 ++ .../{ => components}/widget-views.tsx | 14 +- packages/vision-polyfill/src/skeleton/dock.ts | 4 +- .../src/skeleton/icons/convert.tsx | 16 + .../vision-polyfill/src/skeleton/index.ts | 0 .../skeleton/{ => layouts}/bottom-area.tsx | 4 +- .../src/skeleton/{ => layouts}/left-area.tsx | 2 +- .../{ => layouts}/left-fixed-pane.tsx | 6 +- .../{ => layouts}/left-float-pane.tsx | 4 +- .../src/skeleton/{ => layouts}/main-area.tsx | 6 +- .../src/skeleton/{ => layouts}/right-area.tsx | 4 +- .../src/skeleton/layouts/theme.less | 60 +++ .../src/skeleton/{ => layouts}/toolbar.tsx | 2 +- .../src/skeleton/{ => layouts}/top-area.tsx | 2 +- .../src/skeleton/layouts/workbench.less | 375 ++++++++++++++++++ .../src/skeleton/{ => layouts}/workbench.tsx | 2 +- .../vision-polyfill/src/skeleton/panel.ts | 4 +- .../vision-polyfill/src/skeleton/skeleton.ts | 32 +- .../src/skeleton/transducers/addon-combine.ts | 255 ++++++++++++ .../src/skeleton/transducers/parse-props.ts | 232 +++++++++++ .../src/skeleton/transducers/register.ts | 9 + .../vision-polyfill/src/skeleton/types.ts | 14 +- .../src/skeleton/widget/dialog-dock.ts | 0 .../src/skeleton/widget/dock.ts | 86 ++++ .../src/skeleton/{ => widget}/panel-dock.ts | 7 +- .../src/skeleton/widget/panel.ts | 164 ++++++++ .../src/skeleton/widget/stage.ts | 51 +++ .../src/skeleton/widget/utils.ts | 28 ++ .../src/skeleton/widget/widget-container.ts | 134 +++++++ .../src/skeleton/{ => widget}/widget.ts | 6 +- packages/vision-polyfill/src/vision.ts | 2 +- 294 files changed, 8917 insertions(+), 2992 deletions(-) delete mode 100644 packages/editor-core/CHANGELOG.md rename packages/{globals => editor-core}/cloud-build.json (100%) delete mode 100644 packages/editor-core/src/areaManager.ts delete mode 100644 packages/editor-core/src/context.ts rename packages/{globals => editor-core}/src/di/index.ts (50%) rename packages/{globals => editor-core}/src/di/ioc-context.ts (100%) rename packages/{globals => editor-core}/src/di/setter.ts (90%) rename packages/{globals/src/utils => editor-core/src}/hotkey.ts (100%) rename packages/{globals => editor-core}/src/intl/ali-global-locale.ts (97%) rename packages/{globals/src/intl/index.tsx => editor-core/src/intl/index.ts} (51%) delete mode 100644 packages/editor-core/src/pluginFactory.tsx delete mode 100644 packages/editor-core/src/utils.ts rename packages/editor-core/src/{ => utils}/app-preset.ts (100%) rename packages/{globals => editor-core}/src/utils/get-public-path.ts (100%) create mode 100644 packages/editor-core/src/utils/goldlog.ts create mode 100644 packages/editor-core/src/utils/index.ts rename packages/{globals/src/obx/index.ts => editor-core/src/utils/obx.ts} (100%) rename packages/editor-core/src/{ => utils}/request.ts (91%) rename packages/{globals/src/components => editor-core/src/widgets}/index.ts (63%) create mode 100644 packages/editor-core/src/widgets/tip/index.ts rename packages/{globals/src/components => editor-core/src/widgets}/tip/style.less (100%) rename packages/{globals/src/components => editor-core/src/widgets}/tip/tip-container.tsx (83%) rename packages/{globals/src/components => editor-core/src/widgets}/tip/tip-handler.ts (93%) rename packages/{globals/src/components/tip/tip.tsx => editor-core/src/widgets/tip/tip-item.tsx} (91%) create mode 100644 packages/editor-core/src/widgets/tip/tip.tsx rename packages/{globals/src/components => editor-core/src/widgets}/tip/utils.ts (100%) rename packages/{globals/src/components => editor-core/src/widgets}/title/index.tsx (80%) rename packages/{globals/src/components => editor-core/src/widgets}/title/title.less (100%) create mode 100644 packages/editor-skeleton/src/area.ts delete mode 100644 packages/editor-skeleton/src/components/LeftPlugin/index.scss delete mode 100644 packages/editor-skeleton/src/components/LeftPlugin/index.tsx delete mode 100644 packages/editor-skeleton/src/components/Panel/index.scss delete mode 100644 packages/editor-skeleton/src/components/Panel/index.tsx delete mode 100644 packages/editor-skeleton/src/components/TopIcon/index.scss delete mode 100644 packages/editor-skeleton/src/components/TopIcon/index.tsx delete mode 100644 packages/editor-skeleton/src/components/TopPlugin/index.scss delete mode 100644 packages/editor-skeleton/src/components/TopPlugin/index.tsx create mode 100644 packages/editor-skeleton/src/components/array-setter/bugs.md create mode 100644 packages/editor-skeleton/src/components/array-setter/index.tsx create mode 100644 packages/editor-skeleton/src/components/array-setter/sortable.less create mode 100644 packages/editor-skeleton/src/components/array-setter/sortable.tsx create mode 100644 packages/editor-skeleton/src/components/array-setter/style.less create mode 100644 packages/editor-skeleton/src/components/field/fields.tsx create mode 100644 packages/editor-skeleton/src/components/field/index.less create mode 100644 packages/editor-skeleton/src/components/field/index.ts create mode 100644 packages/editor-skeleton/src/components/mixed-setter/index.tsx create mode 100644 packages/editor-skeleton/src/components/mixed-setter/style.less create mode 100644 packages/editor-skeleton/src/components/object-setter/index.tsx create mode 100644 packages/editor-skeleton/src/components/object-setter/style.less create mode 100644 packages/editor-skeleton/src/components/popup/index.tsx create mode 100644 packages/editor-skeleton/src/components/popup/style.less create mode 100644 packages/editor-skeleton/src/components/settings/index.ts create mode 100644 packages/editor-skeleton/src/components/settings/main.ts create mode 100644 packages/editor-skeleton/src/components/settings/package.json create mode 100644 packages/editor-skeleton/src/components/settings/register.ts create mode 100644 packages/editor-skeleton/src/components/settings/settings-pane.tsx create mode 100644 packages/editor-skeleton/src/components/settings/settings-primary-view.tsx create mode 100644 packages/editor-skeleton/src/components/settings/style.less create mode 100644 packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts create mode 100644 packages/editor-skeleton/src/components/settings/transducers/parse-props.ts create mode 100644 packages/editor-skeleton/src/components/settings/transducers/register.ts create mode 100644 packages/editor-skeleton/src/components/settings/utils.js create mode 100644 packages/editor-skeleton/src/components/widget-views.tsx delete mode 100644 packages/editor-skeleton/src/config/skeleton.ts delete mode 100644 packages/editor-skeleton/src/config/utils.ts create mode 100644 packages/editor-skeleton/src/dock.ts delete mode 100644 packages/editor-skeleton/src/global.scss create mode 100644 packages/editor-skeleton/src/icons/convert.tsx delete mode 100644 packages/editor-skeleton/src/layouts/CenterArea/index.scss delete mode 100644 packages/editor-skeleton/src/layouts/CenterArea/index.tsx delete mode 100644 packages/editor-skeleton/src/layouts/LeftArea/index.scss delete mode 100644 packages/editor-skeleton/src/layouts/LeftArea/index.tsx delete mode 100644 packages/editor-skeleton/src/layouts/LeftArea/nav.tsx delete mode 100644 packages/editor-skeleton/src/layouts/LeftArea/panel.tsx delete mode 100644 packages/editor-skeleton/src/layouts/RightArea/index.scss delete mode 100644 packages/editor-skeleton/src/layouts/RightArea/index.tsx delete mode 100644 packages/editor-skeleton/src/layouts/TopArea/index.scss delete mode 100644 packages/editor-skeleton/src/layouts/TopArea/index.tsx create mode 100644 packages/editor-skeleton/src/layouts/bottom-area.tsx create mode 100644 packages/editor-skeleton/src/layouts/left-area.tsx create mode 100644 packages/editor-skeleton/src/layouts/left-fixed-pane.tsx create mode 100644 packages/editor-skeleton/src/layouts/left-float-pane.tsx create mode 100644 packages/editor-skeleton/src/layouts/main-area.tsx create mode 100644 packages/editor-skeleton/src/layouts/right-area.tsx rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/layouts}/theme.less (100%) create mode 100644 packages/editor-skeleton/src/layouts/toolbar.tsx create mode 100644 packages/editor-skeleton/src/layouts/top-area.tsx rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/layouts}/workbench.less (100%) create mode 100644 packages/editor-skeleton/src/layouts/workbench.tsx delete mode 100644 packages/editor-skeleton/src/locale/en-US.js delete mode 100644 packages/editor-skeleton/src/locale/ja-JP.js delete mode 100644 packages/editor-skeleton/src/locale/zh-CN.js delete mode 100644 packages/editor-skeleton/src/locale/zh-TW.js create mode 100644 packages/editor-skeleton/src/panel.ts create mode 100644 packages/editor-skeleton/src/skeleton.ts delete mode 100644 packages/editor-skeleton/src/skeleton.tsx create mode 100644 packages/editor-skeleton/src/types.ts rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/widget}/dialog-dock.ts (100%) create mode 100644 packages/editor-skeleton/src/widget/dock.ts create mode 100644 packages/editor-skeleton/src/widget/panel-dock.ts create mode 100644 packages/editor-skeleton/src/widget/panel.ts rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/widget}/stage.ts (92%) rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/widget}/utils.ts (100%) rename packages/{vision-polyfill/src/skeleton => editor-skeleton/src/widget}/widget-container.ts (100%) create mode 100644 packages/editor-skeleton/src/widget/widget.ts delete mode 100644 packages/globals/CHANGELOG.md delete mode 100644 packages/globals/README.md delete mode 100644 packages/globals/build.json delete mode 100644 packages/globals/src/components/tip/embed-tip.tsx delete mode 100644 packages/globals/src/components/tip/index.ts delete mode 100644 packages/globals/src/di/editor.ts delete mode 100644 packages/globals/src/di/transducer.ts delete mode 100644 packages/globals/src/index.ts create mode 100644 packages/types/README.md create mode 100644 packages/types/build.json rename packages/{globals => types}/package.json (66%) rename packages/{globals/src/types => types/src}/data-source.ts (100%) rename packages/{editor-core/src/definitions.ts => types/src/editor.ts} (60%) rename packages/{globals/src/types => types/src}/field-config.ts (99%) rename packages/{globals/src/types => types/src}/i18n.ts (100%) rename packages/{globals/src/types => types/src}/icon.ts (100%) rename packages/{globals/src/types => types/src}/index.ts (93%) rename packages/{globals/src/types => types/src}/metadata.ts (100%) rename packages/{globals/src/types => types/src}/npm.ts (100%) rename packages/{globals/src/types => types/src}/prop-config.ts (100%) rename packages/{globals/src/types => types/src}/schema.ts (100%) rename packages/{globals/src/types => types/src}/setter-config.ts (96%) rename packages/{globals/src/types => types/src}/setting-target.ts (96%) rename packages/{globals/src/types => types/src}/tip.ts (100%) rename packages/{globals/src/types => types/src}/title.ts (99%) rename packages/{globals/src/types => types/src}/utils.ts (100%) rename packages/{globals/src/types => types/src}/value-type.ts (100%) rename packages/{globals => types}/tsconfig.json (73%) create mode 100644 packages/utils/package.json rename packages/{globals/src/utils => utils/src}/asset.ts (100%) rename packages/{globals/src/utils => utils/src}/clone-deep.ts (100%) rename packages/{globals/src/utils => utils/src}/create-content.ts (100%) rename packages/{globals/src/utils => utils/src}/create-icon.tsx (93%) rename packages/{globals/src/utils => utils/src}/cursor.less (100%) rename packages/{globals/src/utils => utils/src}/cursor.ts (100%) rename packages/{globals/src/utils => utils/src}/get-prototype-of.ts (100%) rename packages/{globals/src/utils => utils/src}/has-own-property.ts (100%) rename packages/{globals/src/utils => utils/src}/index.ts (86%) rename packages/{globals/src/utils => utils/src}/is-css-url.ts (100%) rename packages/{globals/src/utils => utils/src}/is-element.ts (100%) rename packages/{globals/src/utils => utils/src}/is-es-module.ts (100%) rename packages/{globals/src/utils => utils/src}/is-form-event.ts (100%) rename packages/{globals/src/utils => utils/src}/is-function.ts (100%) rename packages/{globals/src/utils => utils/src}/is-object.ts (100%) rename packages/{globals/src/utils => utils/src}/is-plain-object.ts (100%) rename packages/{globals/src/utils => utils/src}/is-react.ts (100%) rename packages/{globals/src/utils => utils/src}/navtive-selection.ts (100%) rename packages/{globals/src/utils => utils/src}/set-prototype-of.ts (100%) rename packages/{globals/src/utils => utils/src}/shallow-equal.ts (100%) rename packages/{globals/src/components => utils/src}/svg-icon.tsx (100%) rename packages/{globals/src/utils => utils/src}/unique-id.ts (100%) create mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md create mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less create mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/style.less create mode 100644 packages/vision-polyfill/src/skeleton/components/field/fields.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/field/index.less create mode 100644 packages/vision-polyfill/src/skeleton/components/field/index.ts create mode 100644 packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less create mode 100644 packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/object-setter/style.less create mode 100644 packages/vision-polyfill/src/skeleton/components/popup/index.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/popup/style.less create mode 100644 packages/vision-polyfill/src/skeleton/components/register.ts create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/index.ts create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/main.ts create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/package.json create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/style.less create mode 100644 packages/vision-polyfill/src/skeleton/components/settings/utils.js rename packages/vision-polyfill/src/skeleton/{ => components}/widget-views.tsx (94%) create mode 100644 packages/vision-polyfill/src/skeleton/icons/convert.tsx create mode 100644 packages/vision-polyfill/src/skeleton/index.ts rename packages/vision-polyfill/src/skeleton/{ => layouts}/bottom-area.tsx (92%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/left-area.tsx (97%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/left-fixed-pane.tsx (91%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/left-float-pane.tsx (96%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/main-area.tsx (81%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/right-area.tsx (91%) create mode 100644 packages/vision-polyfill/src/skeleton/layouts/theme.less rename packages/vision-polyfill/src/skeleton/{ => layouts}/toolbar.tsx (97%) rename packages/vision-polyfill/src/skeleton/{ => layouts}/top-area.tsx (97%) create mode 100644 packages/vision-polyfill/src/skeleton/layouts/workbench.less rename packages/vision-polyfill/src/skeleton/{ => layouts}/workbench.tsx (96%) create mode 100644 packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts create mode 100644 packages/vision-polyfill/src/skeleton/transducers/parse-props.ts create mode 100644 packages/vision-polyfill/src/skeleton/transducers/register.ts create mode 100644 packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts create mode 100644 packages/vision-polyfill/src/skeleton/widget/dock.ts rename packages/vision-polyfill/src/skeleton/{ => widget}/panel-dock.ts (92%) create mode 100644 packages/vision-polyfill/src/skeleton/widget/panel.ts create mode 100644 packages/vision-polyfill/src/skeleton/widget/stage.ts create mode 100644 packages/vision-polyfill/src/skeleton/widget/utils.ts create mode 100644 packages/vision-polyfill/src/skeleton/widget/widget-container.ts rename packages/vision-polyfill/src/skeleton/{ => widget}/widget.ts (92%) diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-hovering.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-hovering.tsx index 715023181..63201f31c 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-hovering.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-hovering.tsx @@ -1,8 +1,9 @@ import { Component, Fragment, PureComponent } from 'react'; import classNames from 'classnames'; -import { computed, observer, TitleContent, Title } from '@ali/lowcode-globals'; +import { computed, observer, Title } from '@ali/lowcode-editor-core'; import { SimulatorContext } from '../context'; import { BuiltinSimulatorHost } from '../host'; +import { TitleContent } from '@ali/lowcode-types'; export class BorderHoveringInstance extends PureComponent<{ title: TitleContent; diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx index dfb41f797..5597e9382 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx @@ -9,19 +9,13 @@ import { ComponentType, } from 'react'; import classNames from 'classnames'; -import { - observer, - computed, - createIcon, - EmbedTip, - isReactComponent, - ActionContentObject, - isActionContentObject, -} from '@ali/lowcode-globals'; +import { observer, computed, Tip } from '@ali/lowcode-editor-core'; +import { createIcon, isReactComponent } from '@ali/lowcode-utils'; +import { ActionContentObject, isActionContentObject } from '@ali/lowcode-types'; import { SimulatorContext } from '../context'; import { BuiltinSimulatorHost } from '../host'; -import { OffsetObserver } from '../../../designer'; -import { Node } from '../../../document'; +import { OffsetObserver } from '../../designer'; +import { Node } from '../../document'; @observer export class BorderSelectingInstance extends Component<{ @@ -94,9 +88,9 @@ class Toolbar extends Component<{ observed: OffsetObserver }> { } const { node } = observed; const actions: ReactNodeArray = []; - node.componentMeta.availableActions.forEach(action => { + node.componentMeta.availableActions.forEach((action) => { const { important, condition, content, name } = action; - if (node.isSlotRoot && (name === 'copy' || name === 'remove')) { + if (node.isSlot() && (name === 'copy' || name === 'remove')) { // FIXME: need this? return; } @@ -130,7 +124,7 @@ function createAction(content: ReactNode | ComponentType | ActionContentObj }} > {icon && createIcon(icon)} - {title} + {title} ); } @@ -167,7 +161,7 @@ export class BorderSelectingForNode extends Component<{ node: Node }> { } return ( - {instances.map(instance => { + {instances.map((instance) => { const observed = designer.createOffsetObserver({ node, instance, @@ -216,7 +210,7 @@ export class BorderSelecting extends Component { return ( - {selecting.map(node => ( + {selecting.map((node) => ( ))} diff --git a/packages/designer/src/builtin-simulator/bem-tools/index.tsx b/packages/designer/src/builtin-simulator/bem-tools/index.tsx index 8ed26d18e..0ad81c8c4 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/index.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/index.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import { BorderHovering } from './border-hovering'; import { SimulatorContext } from '../context'; import { BuiltinSimulatorHost } from '../host'; diff --git a/packages/designer/src/builtin-simulator/bem-tools/insertion.tsx b/packages/designer/src/builtin-simulator/bem-tools/insertion.tsx index f0c546b99..f630e3547 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/insertion.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/insertion.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { computed, observer } from '@ali/lowcode-globals'; +import { computed, observer } from '@ali/lowcode-editor-core'; import { SimulatorContext } from '../context'; import { BuiltinSimulatorHost } from '../host'; import { @@ -10,7 +10,7 @@ import { isVertical } from '../../designer'; import { ISimulatorHost, } from '../../simulator'; -import {ParentalNode } from '../../document'; +import { ParentalNode } from '../../document'; import './insertion.less'; interface InsertionData { diff --git a/packages/designer/src/builtin-simulator/create-simulator.ts b/packages/designer/src/builtin-simulator/create-simulator.ts index ea772db25..796b10f01 100644 --- a/packages/designer/src/builtin-simulator/create-simulator.ts +++ b/packages/designer/src/builtin-simulator/create-simulator.ts @@ -1,7 +1,7 @@ // NOTE: 仅用作类型标注,切勿作为实体使用 import { BuiltinSimulatorHost } from './host'; -import { AssetLevel, AssetLevels, AssetList, isAssetBundle, isAssetItem, AssetType, assetItem } from '@ali/lowcode-globals'; -import { isCSSUrl } from '@ali/lowcode-globals'; +import { AssetLevel, AssetLevels, AssetList, isAssetBundle, isAssetItem, AssetType, assetItem } from '@ali/lowcode-utils'; +import { isCSSUrl } from '@ali/lowcode-utils'; import { BuiltinSimulatorRenderer } from './renderer'; export function createSimulator( diff --git a/packages/designer/src/builtin-simulator/host-view.tsx b/packages/designer/src/builtin-simulator/host-view.tsx index 756653f15..6d71ce9e3 100644 --- a/packages/designer/src/builtin-simulator/host-view.tsx +++ b/packages/designer/src/builtin-simulator/host-view.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import { BuiltinSimulatorHost, BuiltinSimulatorProps } from './host'; import { DocumentModel } from '../document'; import { SimulatorContext } from './context'; diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 0dbddf5f1..5ac616dc2 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -1,10 +1,10 @@ -import { obx, autorun, computed } from '@ali/lowcode-globals'; +import { obx, autorun, computed, getPublicPath, hotkey } from '@ali/lowcode-editor-core'; import { ISimulatorHost, Component, NodeInstance, ComponentInstance } from '../simulator'; import Viewport from './viewport'; import { createSimulator } from './create-simulator'; import { Node, ParentalNode, DocumentModel, isNode, contains, isRootNode } from '../document'; import ResourceConsumer from './resource-consumer'; -import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, getPublicPath } from '@ali/lowcode-globals'; +import { AssetLevel, Asset, AssetList, assetBundle, assetItem, AssetType, isElement } from '@ali/lowcode-utils'; import { DragObjectType, isShaken, @@ -21,9 +21,8 @@ import { Rect, CanvasPoint, } from '../designer'; -import { parseProps, parseMetadata } from './utils/parse-metadata'; -import { isElement, hotkey } from '@ali/lowcode-globals'; -import { ComponentMetadata } from '@ali/lowcode-globals'; +import { parseMetadata } from './utils/parse-metadata'; +import { ComponentMetadata } from '@ali/lowcode-types'; import { BuiltinSimulatorRenderer } from './renderer'; import clipboard from '../designer/clipboard'; @@ -967,7 +966,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost action.name === name); + const i = builtinComponentActions.findIndex((action) => action.name === name); if (i > -1) { builtinComponentActions.splice(i, 1); } @@ -308,3 +309,33 @@ export function removeBuiltinComponentAction(name: string) { export function addBuiltinComponentAction(action: ComponentAction) { builtinComponentActions.push(action); } + +export interface MetadataTransducer { + (prev: TransformedComponentMetadata): TransformedComponentMetadata; + /** + * 0 - 9 system + * 10 - 99 builtin-plugin + * 100 - app & plugin + */ + level?: number; + /** + * use to replace TODO + */ + id?: string; +} +const metadataTransducers: MetadataTransducer[] = []; + +export function registerMetadataTransducer(transducer: MetadataTransducer, level: number = 100, id?: string) { + transducer.level = level; + transducer.id = id; + const i = metadataTransducers.findIndex((item) => item.level != null && item.level > level); + if (i < 0) { + metadataTransducers.push(transducer); + } else { + metadataTransducers.splice(i, 0, transducer); + } +} + +export function getRegisteredMetadataTransducers(): MetadataTransducer[] { + return metadataTransducers; +} diff --git a/packages/designer/src/designer/builtin-hotkey.ts b/packages/designer/src/designer/builtin-hotkey.ts index 08a13be28..d11edbe03 100644 --- a/packages/designer/src/designer/builtin-hotkey.ts +++ b/packages/designer/src/designer/builtin-hotkey.ts @@ -1,6 +1,7 @@ -import { hotkey, isFormEvent } from '@ali/lowcode-globals'; +import { hotkey } from '@ali/lowcode-editor-core'; +import { isFormEvent } from '@ali/lowcode-utils'; import { focusing } from './focusing'; -import { insertChildren } from '../document'; +import { insertChildren, TransformStage } from '../document'; import clipboard from './clipboard'; // hotkey binding @@ -52,7 +53,7 @@ hotkey.bind(['command+c', 'ctrl+c', 'command+x', 'ctrl+x'], (e, action) => { if (!selected || selected.length < 1) return; const componentsMap = {}; - const componentsTree = selected.map((item) => item.export(false)); + const componentsTree = selected.map((item) => item.export(TransformStage.Save)); const data = { type: 'nodeSchema', componentsMap, componentsTree }; diff --git a/packages/designer/src/designer/designer-view.tsx b/packages/designer/src/designer/designer-view.tsx index ec8d46ea1..fa601a994 100644 --- a/packages/designer/src/designer/designer-view.tsx +++ b/packages/designer/src/designer/designer-view.tsx @@ -1,6 +1,5 @@ import { Component } from 'react'; import classNames from 'classnames'; -import { TipContainer } from '@ali/lowcode-globals'; import BuiltinDragGhostComponent from './drag-ghost'; import { Designer, DesignerProps } from './designer'; import { ProjectView } from '../project'; diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 1e1ce573d..bc0a7bf83 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -1,16 +1,14 @@ import { ComponentType } from 'react'; +import { obx, computed, autorun } from '@ali/lowcode-editor-core'; import { ProjectSchema, ComponentMetadata, ComponentAction, NpmInfo, - obx, - computed, - autorun, IEditor, CompositeObject, PropsList, -} from '@ali/lowcode-globals'; +} from '@ali/lowcode-types'; import { Project } from '../project'; import { Node, DocumentModel, insertChildren, isRootNode, ParentalNode, TransformStage } from '../document'; import { ComponentMeta } from '../component-meta'; diff --git a/packages/designer/src/designer/drag-ghost/index.tsx b/packages/designer/src/designer/drag-ghost/index.tsx index 407548610..d32ee526e 100644 --- a/packages/designer/src/designer/drag-ghost/index.tsx +++ b/packages/designer/src/designer/drag-ghost/index.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { observer, obx, Title } from '@ali/lowcode-globals'; +import { observer, obx, Title } from '@ali/lowcode-editor-core'; import { Designer } from '../designer'; import { DragObject, isDragNodeObject, isDragNodeDataObject } from '../dragon'; import './ghost.less'; diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 58c14acea..f58adc19a 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -1,11 +1,11 @@ import { EventEmitter } from 'events'; -import { NodeSchema, obx } from '@ali/lowcode-globals'; +import { obx } from '@ali/lowcode-editor-core'; +import { NodeSchema } from '@ali/lowcode-types'; +import { setNativeSelection, cursor } from '@ali/lowcode-utils'; import { DropLocation } from './location'; import { Node, DocumentModel } from '../document'; import { ISimulatorHost, isSimulatorHost } from '../simulator'; import { Designer } from './designer'; -import { setNativeSelection } from '@ali/lowcode-globals'; -import { cursor } from '@ali/lowcode-globals'; export interface LocateEvent { readonly type: 'LocateEvent'; diff --git a/packages/designer/src/designer/hovering.ts b/packages/designer/src/designer/hovering.ts index 98ce9b2fd..9c27801a7 100644 --- a/packages/designer/src/designer/hovering.ts +++ b/packages/designer/src/designer/hovering.ts @@ -1,4 +1,4 @@ -import { obx } from '@ali/lowcode-globals'; +import { obx } from '@ali/lowcode-editor-core'; import { Node, DocumentModel } from '../document'; export class Hovering { diff --git a/packages/designer/src/designer/offset-observer.ts b/packages/designer/src/designer/offset-observer.ts index 1105b01be..8793317f9 100644 --- a/packages/designer/src/designer/offset-observer.ts +++ b/packages/designer/src/designer/offset-observer.ts @@ -1,5 +1,5 @@ -import { obx, computed } from '@ali/lowcode-globals'; -import { uniqueId } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; +import { uniqueId } from '@ali/lowcode-utils'; import { INodeSelector, IViewport } from '../simulator'; import { isRootNode, Node } from '../document'; diff --git a/packages/designer/src/designer/scroller.ts b/packages/designer/src/designer/scroller.ts index a3c90a46c..a7c93b91f 100644 --- a/packages/designer/src/designer/scroller.ts +++ b/packages/designer/src/designer/scroller.ts @@ -1,4 +1,4 @@ -import { isElement } from '@ali/lowcode-globals'; +import { isElement } from '@ali/lowcode-utils'; export class ScrollTarget { get left() { diff --git a/packages/designer/src/designer/setting/setting-entry.ts b/packages/designer/src/designer/setting/setting-entry.ts index 9ab5831db..8a81b5629 100644 --- a/packages/designer/src/designer/setting/setting-entry.ts +++ b/packages/designer/src/designer/setting/setting-entry.ts @@ -1,4 +1,4 @@ -import { SettingTarget } from '@ali/lowcode-globals'; +import { SettingTarget } from '@ali/lowcode-types'; import { ComponentMeta } from '../../component-meta'; import { Designer } from '../designer'; import { Node } from '../../document'; diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index 2aa748480..e40100ed8 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -1,7 +1,8 @@ -import { TitleContent, computed, isDynamicSetter, SetterType, DynamicSetter, FieldExtraProps, FieldConfig, CustomView, isCustomView, obx } from '@ali/lowcode-globals'; +import { TitleContent, isDynamicSetter, SetterType, DynamicSetter, FieldExtraProps, FieldConfig, CustomView, isCustomView } from '@ali/lowcode-types'; import { Transducer } from './utils'; import { SettingPropEntry } from './setting-prop-entry'; import { SettingEntry } from './setting-entry'; +import { computed, obx } from '@ali/lowcode-editor-core'; export class SettingField extends SettingPropEntry implements SettingEntry { readonly isSettingField = true; diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index 87eae902a..34bf07f9b 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -1,4 +1,6 @@ -import { obx, uniqueId, computed, IEditor } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; +import { IEditor } from '@ali/lowcode-types'; +import { uniqueId } from '@ali/lowcode-utils'; import { SettingEntry } from './setting-entry'; import { Node } from '../../document'; import { ComponentMeta } from '../../component-meta'; diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index 759ece7fe..8595861d4 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,5 +1,6 @@ import { EventEmitter } from 'events'; -import { CustomView, computed, isCustomView, IEditor } from '@ali/lowcode-globals'; +import { CustomView, isCustomView, IEditor } from '@ali/lowcode-types'; +import { computed } from '@ali/lowcode-editor-core'; import { SettingEntry } from './setting-entry'; import { SettingField } from './setting-field'; import { SettingPropEntry } from './setting-prop-entry'; diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index c5cd064d8..6e8c37e24 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -1,17 +1,5 @@ -import { - NodeData, - isJSExpression, - isDOMText, - NodeSchema, - computed, - obx, - autorun, - isNodeSchema, - uniqueId, - PageSchema, - ComponentSchema, - RootSchema, -} from '@ali/lowcode-globals'; +import { computed, obx } from '@ali/lowcode-editor-core'; +import { NodeData, isJSExpression, isDOMText, NodeSchema, isNodeSchema, RootSchema } from '@ali/lowcode-types'; import { Project } from '../project'; import { ISimulatorHost } from '../simulator'; import { ComponentMeta } from '../component-meta'; @@ -20,6 +8,7 @@ import { Node, insertChildren, insertChild, isNode, RootNode, ParentalNode } fro import { Selection } from './selection'; import { History } from './history'; import { TransformStage } from './node'; +import { uniqueId } from '@ali/lowcode-utils'; export type GetDataType = T extends undefined ? NodeType extends { @@ -90,11 +79,13 @@ export class DocumentModel { this._blank = true; } - this.rootNode = this.createNode(schema || { - componentName: 'Page', - id: 'root', - fileName: '' - }); + this.rootNode = this.createNode( + schema || { + componentName: 'Page', + id: 'root', + fileName: '', + }, + ); this.history = new History( () => this.schema, diff --git a/packages/designer/src/document/document-view.tsx b/packages/designer/src/document/document-view.tsx index b9771907f..2565f34fc 100644 --- a/packages/designer/src/document/document-view.tsx +++ b/packages/designer/src/document/document-view.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import { DocumentModel } from './document-model'; import { BuiltinSimulatorHostView } from '../builtin-simulator'; diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 8c6b67e2a..0f283b65b 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -1,5 +1,6 @@ import { EventEmitter } from 'events'; -import { NodeSchema, autorun, Reaction, untracked } from '@ali/lowcode-globals'; +import { autorun, Reaction, untracked } from '@ali/lowcode-editor-core'; +import { NodeSchema } from '@ali/lowcode-types'; // TODO: cache to localStorage diff --git a/packages/designer/src/document/node/exclusive-group.ts b/packages/designer/src/document/node/exclusive-group.ts index 8e3f7b927..cd4b46030 100644 --- a/packages/designer/src/document/node/exclusive-group.ts +++ b/packages/designer/src/document/node/exclusive-group.ts @@ -1,5 +1,6 @@ -import { obx, computed, TitleContent } from '@ali/lowcode-globals'; -import { uniqueId } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; +import { uniqueId } from '@ali/lowcode-utils'; +import { TitleContent } from '@ali/lowcode-types'; import { Node } from './node'; import { intl } from '../../locale'; diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 712ed1374..a8a4a364e 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -1,6 +1,7 @@ -import { NodeData, isNodeSchema, obx, computed } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; import { Node, ParentalNode } from './node'; import { TransformStage } from './transform-stage'; +import { NodeData, isNodeSchema } from '@ali/lowcode-types'; export class NodeChildren { @obx.val private children: Node[]; diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 6f8fe58d8..a4bb4c21a 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -1,3 +1,4 @@ +import { obx, computed } from '@ali/lowcode-editor-core'; import { isDOMText, isJSExpression, @@ -6,12 +7,10 @@ import { PropsList, NodeData, TitleContent, - obx, - computed, SlotSchema, PageSchema, ComponentSchema, -} from '@ali/lowcode-globals'; +} from '@ali/lowcode-types'; import { Props, EXTRA_KEY_PREFIX } from './props/props'; import { DocumentModel } from '../document-model'; import { NodeChildren } from './node-children'; @@ -20,8 +19,6 @@ import { ComponentMeta } from '../../component-meta'; import { ExclusiveGroup, isExclusiveGroup } from './exclusive-group'; import { TransformStage } from './transform-stage'; - - /** * 基础节点 * @@ -175,7 +172,7 @@ export class Node { } isRoot(): this is RootNode { - return this.document.rootNode == this as any; + return this.document.rootNode == (this as any); } isPage(): this is PageNode { @@ -298,7 +295,7 @@ export class Node { @computed get slots() { // TODO: optimize recore/obx, array maked every time, donot as changed const slots: Node[] = []; - this.props.forEach(item => { + this.props.forEach((item) => { if (item.type === 'slot') { slots.push(item.slotNode!); } @@ -563,7 +560,7 @@ export class Node { this.children?.insert(node, ref ? ref.index : null); } insertAfter(node: Node, ref?: Node) { - this.children?.insert(node, ref ? (ref.index + 1) : null); + this.children?.insert(node, ref ? ref.index + 1 : null); } getParent() { return this.parent; @@ -594,9 +591,7 @@ export class Node { /** * @deprecated */ - setStatus() { - - } + setStatus() {} /** * @deprecated */ diff --git a/packages/designer/src/document/node/props/prop-stash.ts b/packages/designer/src/document/node/props/prop-stash.ts index ef57a8afe..0cf754f92 100644 --- a/packages/designer/src/document/node/props/prop-stash.ts +++ b/packages/designer/src/document/node/props/prop-stash.ts @@ -1,4 +1,4 @@ -import { obx, autorun, untracked, computed } from '@ali/lowcode-globals'; +import { obx, autorun, untracked, computed } from '@ali/lowcode-editor-core'; import { Prop, IPropParent, UNSET } from './prop'; import { Props } from './props'; diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index f82eb013a..fcb37a8a3 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -1,16 +1,6 @@ -import { - CompositeValue, - isJSExpression, - isJSSlot, - untracked, - computed, - obx, - JSSlot, - SlotSchema -} from '@ali/lowcode-globals'; -import { uniqueId } from '@ali/lowcode-globals'; -import { isPlainObject } from '@ali/lowcode-globals'; -import { hasOwnProperty } from '@ali/lowcode-globals'; +import { untracked, computed, obx } from '@ali/lowcode-editor-core'; +import { CompositeValue, isJSExpression, isJSSlot, JSSlot, SlotSchema } from '@ali/lowcode-types'; +import { uniqueId, isPlainObject, hasOwnProperty } from '@ali/lowcode-utils'; import { PropStash } from './prop-stash'; import { valueToSource } from './value-to-source'; import { Props } from './props'; diff --git a/packages/designer/src/document/node/props/props.ts b/packages/designer/src/document/node/props/props.ts index bfdead44b..c9d61056a 100644 --- a/packages/designer/src/document/node/props/props.ts +++ b/packages/designer/src/document/node/props/props.ts @@ -1,10 +1,12 @@ -import { PropsMap, PropsList, CompositeValue, computed, obx, uniqueId } from '@ali/lowcode-globals'; +import { computed, obx } from '@ali/lowcode-editor-core'; +import { PropsMap, PropsList, CompositeValue } from '@ali/lowcode-types'; +import { uniqueId } from '@ali/lowcode-utils'; import { PropStash } from './prop-stash'; import { Prop, IPropParent, UNSET } from './prop'; import { Node } from '../node'; import { TransformStage } from '../transform-stage'; -export const EXTRA_KEY_PREFIX = '__'; +export const EXTRA_KEY_PREFIX = '___'; export class Props implements IPropParent { readonly id = uniqueId('props'); diff --git a/packages/designer/src/document/selection.ts b/packages/designer/src/document/selection.ts index caa4e4cef..f1741b48b 100644 --- a/packages/designer/src/document/selection.ts +++ b/packages/designer/src/document/selection.ts @@ -1,5 +1,5 @@ import { EventEmitter } from 'events'; -import { obx } from '@ali/lowcode-globals'; +import { obx } from '@ali/lowcode-editor-core'; import { Node, comparePosition, PositionNO } from './node/node'; import { DocumentModel } from './document-model'; diff --git a/packages/designer/src/icons/clone.tsx b/packages/designer/src/icons/clone.tsx index 374f061df..844b3f5b0 100644 --- a/packages/designer/src/icons/clone.tsx +++ b/packages/designer/src/icons/clone.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; export function IconClone(props: IconProps) { return ( diff --git a/packages/designer/src/icons/component.tsx b/packages/designer/src/icons/component.tsx index 26b99e902..78a3ba1f0 100644 --- a/packages/designer/src/icons/component.tsx +++ b/packages/designer/src/icons/component.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; export function IconComponent(props: IconProps) { return ( diff --git a/packages/designer/src/icons/container.tsx b/packages/designer/src/icons/container.tsx index 62a8cffba..5c46b3f18 100644 --- a/packages/designer/src/icons/container.tsx +++ b/packages/designer/src/icons/container.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; export function IconContainer(props: IconProps) { return ( diff --git a/packages/designer/src/icons/hidden.tsx b/packages/designer/src/icons/hidden.tsx index e3a001ca4..0f944cadf 100644 --- a/packages/designer/src/icons/hidden.tsx +++ b/packages/designer/src/icons/hidden.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; export function IconHidden(props: IconProps) { return ( diff --git a/packages/designer/src/icons/page.tsx b/packages/designer/src/icons/page.tsx index 1762b3d94..a957239fe 100644 --- a/packages/designer/src/icons/page.tsx +++ b/packages/designer/src/icons/page.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; export function IconPage(props: IconProps) { return ( diff --git a/packages/designer/src/icons/remove.tsx b/packages/designer/src/icons/remove.tsx index e10bd8e04..7de39eadb 100644 --- a/packages/designer/src/icons/remove.tsx +++ b/packages/designer/src/icons/remove.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconRemove(props: IconProps) { return ( diff --git a/packages/designer/src/icons/setting.tsx b/packages/designer/src/icons/setting.tsx index d928bda86..4604079cd 100644 --- a/packages/designer/src/icons/setting.tsx +++ b/packages/designer/src/icons/setting.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconSetting(props: IconProps) { return ( diff --git a/packages/designer/src/locale/index.ts b/packages/designer/src/locale/index.ts index 913dd42f8..dfd17521f 100644 --- a/packages/designer/src/locale/index.ts +++ b/packages/designer/src/locale/index.ts @@ -1,4 +1,4 @@ -import { createIntl } from '@ali/lowcode-globals'; +import { createIntl } from '@ali/lowcode-editor-core'; import en_US from './en-US.json'; import zh_CN from './zh-CN.json'; diff --git a/packages/designer/src/project/project-view.tsx b/packages/designer/src/project/project-view.tsx index cfec45792..649358b62 100644 --- a/packages/designer/src/project/project-view.tsx +++ b/packages/designer/src/project/project-view.tsx @@ -1,5 +1,5 @@ import { Component } from 'react'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import { Designer } from '../designer'; import { DocumentView } from '../document'; import { intl } from '../locale'; diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 019c5e780..8217697be 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -1,7 +1,8 @@ import { EventEmitter } from 'events'; -import { ProjectSchema, RootSchema, obx, computed } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; import { Designer } from '../designer'; import { DocumentModel, isDocumentModel } from '../document'; +import { ProjectSchema, RootSchema } from '@ali/lowcode-types'; export class Project { private emitter = new EventEmitter(); diff --git a/packages/designer/src/simulator.ts b/packages/designer/src/simulator.ts index 2fa325f4a..9fe2af78a 100644 --- a/packages/designer/src/simulator.ts +++ b/packages/designer/src/simulator.ts @@ -1,5 +1,5 @@ import { Component as ReactComponent, ComponentType } from 'react'; -import { ComponentMetadata } from '@ali/lowcode-globals'; +import { ComponentMetadata } from '@ali/lowcode-types'; import { ISensor, Point, ScrollTarget, IScrollable } from './designer'; import { Node } from './document'; diff --git a/packages/editor-core/CHANGELOG.md b/packages/editor-core/CHANGELOG.md deleted file mode 100644 index 1f2f83c47..000000000 --- a/packages/editor-core/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - - -## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.5...@ali/lowcode-editor-core@0.8.6) (2020-04-16) - - - - -**Note:** Version bump only for package @ali/lowcode-editor-core - - -## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.4...@ali/lowcode-editor-core@0.8.5) (2020-04-15) - - -### Bug Fixes - -* editor ([ccd9162](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/ccd9162)) - - - - - -## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.3...@ali/lowcode-editor-core@0.8.4) (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-editor-core - - -## 0.8.3 (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-editor-core - - -## 0.8.2 (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-editor-core diff --git a/packages/editor-core/README.md b/packages/editor-core/README.md index 6e9e79f5b..30c3e7d7d 100644 --- a/packages/editor-core/README.md +++ b/packages/editor-core/README.md @@ -1,11 +1,3 @@ -# demo component +shared globals -t-s-demo - -intro component - -## API - -| 参数名 | 说明 | 必填 | 类型 | 默认值 | 备注 | -| ------ | ---- | ---- | ---- | ------ | ---- | -| | | | | | | + 发 CDN diff --git a/packages/editor-core/build.json b/packages/editor-core/build.json index bd5cf18dd..e791d5b6b 100644 --- a/packages/editor-core/build.json +++ b/packages/editor-core/build.json @@ -1,5 +1,9 @@ { "plugins": [ - "build-plugin-component" + "build-plugin-component", + "build-plugin-fusion", + ["build-plugin-moment-locales", { + "locales": ["zh-cn"] + }] ] } diff --git a/packages/globals/cloud-build.json b/packages/editor-core/cloud-build.json similarity index 100% rename from packages/globals/cloud-build.json rename to packages/editor-core/cloud-build.json diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index ff51b4271..c8fcce18c 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,45 +1,56 @@ { - "name": "@ali/lowcode-editor-core", - "version": "0.8.6", - "description": "alibaba lowcode editor core", + "name": "@ali/lowcode-globals", + "version": "0.9.3", + "description": "Globals api for Ali lowCode engine", + "license": "MIT", "main": "lib/index.js", "module": "es/index.js", - "stylePath": "style.js", "files": [ "lib", "es" ], "scripts": { "build": "build-scripts build --skip-demo", + "cloud-build": "build-scripts build --skip-demo --config cloud-build.json", "test": "ava", "test:snapshot": "ava --update-snapshots" }, - "keywords": [ - "lowcode", - "editor" - ], - "author": "xiayang.xy", + "ava": { + "compileEnhancements": false, + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ], + "snapshotDir": "test/fixtures/__snapshots__" + }, "dependencies": { - "@ali/lowcode-globals": "^0.9.3", - "@alifd/next": "1.x", + "@alifd/next": "^1.19.16", + "@recore/obx": "^1.0.8", + "@recore/obx-react": "^1.0.7", + "classnames": "^2.2.6", + "power-di": "^2.2.4", "debug": "^4.1.1", - "events": "^3.1.0", "intl-messageformat": "^8.3.1", "lodash": "^4.17.15", - "prop-types": "^15.5.8", - "react": "^16.8.0", "store": "^2.0.12", - "whatwg-fetch": "^3.0.0" + "react": "^16", + "react-dom": "^16.7.0" }, "devDependencies": { - "@alib/build-scripts": "^0.1.3", + "@alib/build-scripts": "^0.1.18", + "@types/classnames": "^2.2.7", + "@types/node": "^13.7.1", + "@types/react": "^16", + "@types/react-dom": "^16", + "@types/lodash": "^4.14.149", - "@types/react": "^16.9.13", - "@types/react-dom": "^16.9.4", "@types/store": "^2.0.2", - "build-plugin-component": "^0.2.10" + "build-plugin-component": "^0.2.11", + "build-plugin-fusion": "^0.1.0", + "build-plugin-moment-locales": "^0.1.0" }, - "license": "MIT", "publishConfig": { "registry": "https://registry.npm.alibaba-inc.com" } diff --git a/packages/editor-core/src/areaManager.ts b/packages/editor-core/src/areaManager.ts deleted file mode 100644 index 6f162c5cc..000000000 --- a/packages/editor-core/src/areaManager.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { PluginConfig, PluginStatus, PluginClass, HOCPlugin } from './definitions'; -import Editor from './index'; -import { clone, deepEqual } from './utils'; - -export default class AreaManager { - private pluginStatus: PluginStatus; - - private config: PluginConfig[]; - - constructor(private editor: Editor, private name: string) { - this.config = (editor && editor.config && editor.config.plugins && editor.config.plugins[name]) || []; - this.pluginStatus = clone(editor.pluginStatus); - } - - setVisible(flag: boolean) { - - } - - isEnable() { - - } - - isVisible() { - - } - - isEmpty() { - - } - - isPluginStatusUpdate(pluginType?: string, notUpdateStatus?: boolean): boolean { - const { pluginStatus } = this.editor; - const list = pluginType ? this.config.filter((item): boolean => item.type === pluginType) : this.config; - - const isUpdate = list.some( - (item): boolean => !deepEqual(pluginStatus[item.pluginKey], this.pluginStatus[item.pluginKey]), - ); - if (!notUpdateStatus) { - this.pluginStatus = clone(pluginStatus); - } - return isUpdate; - } - - getVisiblePluginList(pluginType?: string): PluginConfig[] { - const res = this.config.filter((item): boolean => { - return !!(!this.pluginStatus[item.pluginKey] || this.pluginStatus[item.pluginKey].visible); - }); - return pluginType ? res.filter((item): boolean => item.type === pluginType) : res; - } - - getPlugin(pluginKey: string): HOCPlugin | void { - if (pluginKey) { - return this.editor && this.editor.plugins && this.editor.plugins[pluginKey]; - } - } - - getPluginConfig(pluginKey?: string): PluginConfig[] | PluginConfig | undefined { - if (pluginKey) { - return this.config.find(item => item.pluginKey === pluginKey); - } - return this.config; - } - - getPluginClass(pluginKey: string): PluginClass | void { - if (pluginKey) { - return this.editor && this.editor.components && this.editor.components[pluginKey]; - } - } - - getPluginStatus(pluginKey: string): PluginStatus | void { - if (pluginKey) { - return this.editor && this.editor.pluginStatus && this.editor.pluginStatus[pluginKey]; - } - } -} diff --git a/packages/editor-core/src/context.ts b/packages/editor-core/src/context.ts deleted file mode 100644 index 859b79dc4..000000000 --- a/packages/editor-core/src/context.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { createContext } from 'react'; - -const context = createContext({}); -export default context; diff --git a/packages/globals/src/di/index.ts b/packages/editor-core/src/di/index.ts similarity index 50% rename from packages/globals/src/di/index.ts rename to packages/editor-core/src/di/index.ts index fafbd578c..d60f74e53 100644 --- a/packages/globals/src/di/index.ts +++ b/packages/editor-core/src/di/index.ts @@ -1,4 +1,3 @@ export * from './setter'; -export * from './transducer'; export * from './ioc-context'; -export * from './editor'; +export * from './tip'; diff --git a/packages/globals/src/di/ioc-context.ts b/packages/editor-core/src/di/ioc-context.ts similarity index 100% rename from packages/globals/src/di/ioc-context.ts rename to packages/editor-core/src/di/ioc-context.ts diff --git a/packages/globals/src/di/setter.ts b/packages/editor-core/src/di/setter.ts similarity index 90% rename from packages/globals/src/di/setter.ts rename to packages/editor-core/src/di/setter.ts index fb162022f..b66bfc06c 100644 --- a/packages/globals/src/di/setter.ts +++ b/packages/editor-core/src/di/setter.ts @@ -1,7 +1,6 @@ import { ReactNode } from 'react'; -import { CustomView, isCustomView } from '../types/setter-config'; -import { createContent } from '../utils/create-content'; -import { TitleContent } from '../types'; +import { CustomView, isCustomView, TitleContent } from '@ali/lowcode-types'; +import { createContent } from '@ali/lowcode-utils'; export type RegisteredSetter = { component: CustomView; diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index 70f1263ad..aa7fe1083 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -1,31 +1,10 @@ import { EventEmitter } from 'events'; -import store from 'store'; -import { IocContext, RegisterOptions } from '@ali/lowcode-globals'; -import { - EditorConfig, - HooksConfig, - LocaleType, - PluginStatusSet, - Utils, - PluginClassSet, - PluginSet, -} from './definitions'; - -import pluginFactory from './pluginFactory'; - -import * as editorUtils from './utils'; - -const { registShortCuts, transformToPromise, unRegistShortCuts } = editorUtils; - -let instance: Editor; - +import { IEditor, EditorConfig, PluginClassSet } from '@ali/lowcode-types'; +import { IocContext, RegisterOptions } from './di'; +import { globalLocale } from './intl'; EventEmitter.defaultMaxListeners = 100; -export interface HooksFuncs { - [idx: number]: (msg: string, handler: (...args: []) => void) => void; -} - -export type KeyType = Function | symbol | string; +export type KeyType = Function | Symbol | string; export type ClassType = Function | (new (...args: any[]) => any); export interface GetOptions { forceNew?: boolean; @@ -41,26 +20,7 @@ export type GetReturnType = T extends undefined const NOT_FOUND = Symbol.for('not_found'); -export default class Editor extends EventEmitter { - static getInstance = (config: EditorConfig, components: PluginClassSet, utils?: Utils): Editor => { - if (!instance) { - instance = new Editor(config, components, utils); - } - return instance; - }; - - private _components?: PluginClassSet; - get components(): PluginClassSet { - if (!this._components) { - this._components = {}; - Object.keys(this.componentsMap).forEach((key) => { - (this._components as any)[key] = pluginFactory(this.componentsMap[key]); - }); - } - return this._components; - } - - readonly utils: Utils; +export class Editor extends EventEmitter implements IEditor { /** * Ioc Container */ @@ -68,18 +28,12 @@ export default class Editor extends EventEmitter { notFoundHandler: (type: KeyType) => NOT_FOUND, }); - pluginStatus?: PluginStatusSet; + get locale() { + return globalLocale.getLocale(); + } - plugins?: PluginSet; - - locale?: LocaleType; - - hooksFuncs?: HooksFuncs; - - constructor(readonly config: EditorConfig = {}, readonly componentsMap: PluginClassSet = {}, utils?: Utils) { + constructor(readonly config: EditorConfig = {}, readonly components: PluginClassSet = {}) { super(); - this.utils = { ...editorUtils, ...utils } as any; - instance = this; } get(keyOrType: KeyOrType, opt?: GetOptions): GetReturnType | undefined { @@ -135,18 +89,15 @@ export default class Editor extends EventEmitter { } async init(): Promise { - const { hooks, shortCuts = [], lifeCycles } = this.config || {}; - this.locale = store.get('lowcode-editor-locale') || 'zh-CN'; - this.pluginStatus = this.initPluginStatus(); - this.initHooks(hooks || []); + const { shortCuts = [], lifeCycles } = this.config || {}; this.emit('editor.beforeInit'); const init = (lifeCycles && lifeCycles.init) || ((): void => {}); // 用户可以通过设置extensions.init自定义初始化流程; try { - await transformToPromise(init(this)); + // await transformToPromise(init(this)); // 注册快捷键 - registShortCuts(shortCuts, this); + // registShortCuts(shortCuts, this); this.emit('editor.afterInit'); return true; } catch (err) { @@ -156,9 +107,8 @@ export default class Editor extends EventEmitter { destroy(): void { try { - const { hooks = [], shortCuts = [], lifeCycles = {} } = this.config; - unRegistShortCuts(shortCuts); - this.destroyHooks(hooks); + const { shortCuts = [], lifeCycles = {} } = this.config; + // unRegistShortCuts(shortCuts); if (lifeCycles.destroy) { lifeCycles.destroy(this); } @@ -167,33 +117,6 @@ export default class Editor extends EventEmitter { } } - batchOn(events: string[], lisenter: (...args: any[]) => void): void { - if (!Array.isArray(events)) { - return; - } - events.forEach((event): void => { - this.on(event, lisenter); - }); - } - - batchOnce(events: string[], lisenter: (...args: any[]) => void): void { - if (!Array.isArray(events)) { - return; - } - events.forEach((event): void => { - this.once(event, lisenter); - }); - } - - batchOff(events: string[], lisenter: (...args: any[]) => void): void { - if (!Array.isArray(events)) { - return; - } - events.forEach((event): void => { - this.off(event, lisenter); - }); - } - private waits = new Map< KeyType, Array<{ @@ -245,50 +168,4 @@ export default class Editor extends EventEmitter { this.waits.delete(key); } } - - // 销毁hooks中的消息监听 - private destroyHooks(hooks: HooksConfig = []): void { - hooks.forEach((item, idx): void => { - if (typeof this.hooksFuncs?.[idx] === 'function') { - this.off(item.message, this.hooksFuncs[idx]); - } - }); - delete this.hooksFuncs; - } - - // 初始化hooks中的消息监听 - private initHooks(hooks: HooksConfig = []): void { - this.hooksFuncs = hooks.map((item): ((...arg: any[]) => void) => { - const func = (...args: any[]): void => { - item.handler(this, ...args); - }; - this[item.type](item.message, func); - return func; - }); - } - - private initPluginStatus(): PluginStatusSet { - const { plugins = {} } = this.config; - const pluginAreas = Object.keys(plugins); - const res: PluginStatusSet = {}; - pluginAreas.forEach((area): void => { - (plugins[area] || []).forEach((plugin): void => { - if (plugin.type === 'Divider') { - return; - } - const { visible, disabled, marked } = plugin.props || {}; - res[plugin.pluginKey] = { - visible: typeof visible === 'boolean' ? visible : true, - disabled: typeof disabled === 'boolean' ? disabled : false, - marked: typeof marked === 'boolean' ? marked : false, - }; - const pluginClass = this.components[plugin.pluginKey]; - // 判断如果编辑器插件有init静态方法,则在此执行init方法 - if (pluginClass && pluginClass.init) { - pluginClass.init(this); - } - }); - }); - return res; - } } diff --git a/packages/globals/src/utils/hotkey.ts b/packages/editor-core/src/hotkey.ts similarity index 100% rename from packages/globals/src/utils/hotkey.ts rename to packages/editor-core/src/hotkey.ts diff --git a/packages/editor-core/src/index.ts b/packages/editor-core/src/index.ts index 89ecdbfda..f8d71e139 100644 --- a/packages/editor-core/src/index.ts +++ b/packages/editor-core/src/index.ts @@ -1,11 +1,6 @@ -import Editor from './editor'; - -import * as utils from './utils'; - -export { default as PluginFactory } from './pluginFactory'; -export { default as EditorContext } from './context'; -export { default as AreaManager } from './areaManager'; - -export default Editor; - -export { Editor, utils }; +export * from './intl'; +export * from './editor'; +export * from './utils'; +export * from './di'; +export * from './hotkey'; +export * from './widgets'; diff --git a/packages/globals/src/intl/ali-global-locale.ts b/packages/editor-core/src/intl/ali-global-locale.ts similarity index 97% rename from packages/globals/src/intl/ali-global-locale.ts rename to packages/editor-core/src/intl/ali-global-locale.ts index 9737a68ba..2a26727dd 100644 --- a/packages/globals/src/intl/ali-global-locale.ts +++ b/packages/editor-core/src/intl/ali-global-locale.ts @@ -1,4 +1,5 @@ import { EventEmitter } from 'events'; +import { obx } from '../utils/obx'; const languageMap: { [key: string]: string } = { en: 'en-US', zh: 'zh-CN', @@ -28,7 +29,7 @@ const languageMap: { [key: string]: string } = { const LowcodeConfigKey = 'ali-lowcode-config'; class AliGlobalLocale { - private locale: string = ''; + @obx.ref private locale: string = ''; private emitter = new EventEmitter(); constructor() { diff --git a/packages/globals/src/intl/index.tsx b/packages/editor-core/src/intl/index.ts similarity index 51% rename from packages/globals/src/intl/index.tsx rename to packages/editor-core/src/intl/index.ts index 2b7619d5c..3deb3e8b4 100644 --- a/packages/globals/src/intl/index.tsx +++ b/packages/editor-core/src/intl/index.ts @@ -1,19 +1,9 @@ +import { ReactNode, Component, createElement } from 'react'; +import { IntlMessageFormat } from 'intl-messageformat'; import { globalLocale } from './ali-global-locale'; -import { PureComponent, ReactNode } from 'react'; -import { isI18nData } from '../types'; +import { isI18nData } from '@ali/lowcode-types'; +import { observer, computed } from '../utils'; -function injectVars(template: string, params: any): string { - if (!template || !params) { - return template; - } - return template.replace(/({\w+})/g, (_, $1) => { - const key = (/\d+/.exec($1) || [])[0] as any; - if (key && params[key] != null) { - return params[key]; - } - return $1; - }); -} function generateTryLocales(locale: string) { const tries = [locale, locale.replace('-', '_')]; if (locale === 'zh-TW' || locale === 'en-US') { @@ -30,44 +20,40 @@ function generateTryLocales(locale: string) { return tries; } -export function localeFormat(data: any, params?: object): string { +function injectVars(msg: string, params: any, locale: string): string { + if (!msg || !params) { + return msg; + } + const formater = new IntlMessageFormat(msg, locale); + return formater.format(params as any) as string; + /* + + return template.replace(/({\w+})/g, (_, $1) => { + const key = (/\d+/.exec($1) || [])[0] as any; + if (key && params[key] != null) { + return params[key]; + } + return $1; + });*/ +} + +export function intl(data: any, params?: object): string { if (!isI18nData(data)) { return data; } const locale = globalLocale.getLocale(); const tries = generateTryLocales(locale); - let tpl: string | undefined; + let msg: string | undefined; for (const lan of tries) { - tpl = data[lan]; - if (tpl != null) { + msg = data[lan]; + if (msg != null) { break; } } - if (tpl == null) { + if (msg == null) { return `##intl@${locale}##`; } - return injectVars(tpl, params); -} - -class Intl extends PureComponent<{ data: any; params?: object }> { - private dispose = globalLocale.onLocaleChange(() => this.forceUpdate()); - componentWillUnmount() { - this.dispose(); - } - render() { - const { data, params } = this.props; - return localeFormat(data, params); - } -} - -export function intl(data: any, params?: object): ReactNode { - if (isI18nData(data)) { - if (data.intl) { - return data.intl; - } - return ; - } - return data; + return injectVars(msg, params, locale); } export function shallowIntl(data: any): any { @@ -76,38 +62,53 @@ export function shallowIntl(data: any): any { } const maps: any = {}; Object.keys(data).forEach(key => { - maps[key] = localeFormat(data[key]); + maps[key] = intl(data[key]); }); return maps; } +export function intlNode(data: any, params?: object): ReactNode { + if (isI18nData(data)) { + if (data.intlNode) { + return data.intlNode; + } + + return createElement(IntlElement, { data, params }); + } + return data; +} + +@observer +class IntlElement extends Component<{ data: any; params?: object }> { + render() { + const { data, params } = this.props; + return intl(data, params); + } +} + export function createIntl( instance: string | object, ): { - intl(id: string, params?: object): ReactNode; - intlString(id: string, params?: object): string; + intlNode(id: string, params?: object): ReactNode; + intl(id: string, params?: object): string; getLocale(): string; setLocale(locale: string): void; } { - let lastLocale: string | undefined; - let data: any = {}; - function useLocale(locale: string) { - lastLocale = locale; + const data = computed(() => { + const locale = globalLocale.getLocale(); if (typeof instance === 'string') { if ((window as any)[instance]) { - data = (window as any)[instance][locale] || {}; + data.messages = (window as any)[instance][locale] || {}; } else { const key = `${instance}_${locale.toLocaleLowerCase()}`; - data = (window as any)[key] || {}; + data.messages = (window as any)[key] || {}; } } else if (instance && typeof instance === 'object') { - data = (instance as any)[locale] || {}; + data.messages = (instance as any)[locale] || {}; } - } + }); - useLocale(globalLocale.getLocale()); - - function intlString(key: string, params?: object): string { + function intl(key: string, params?: object): string { // TODO: tries lost language const str = data[key]; @@ -115,30 +116,22 @@ export function createIntl( return `##intl@${key}##`; } - return injectVars(str, params); + return injectVars(str, params, globalLocale.getLocale()); } - class Intl extends PureComponent<{ id: string; params?: object }> { - private dispose = globalLocale.onLocaleChange(locale => { - if (lastLocale !== locale) { - useLocale(locale); - this.forceUpdate(); - } - }); - componentWillUnmount() { - this.dispose(); - } + @observer + class IntlElement extends Component<{ id: string; params?: object }> { render() { const { id, params } = this.props; - return intlString(id, params); + return intl(id, params); } } return { - intl(id: string, params?: object) { - return ; + intlNode(id: string, params?: object) { + return createElement(IntlElement, { id, params }); }, - intlString, + intl, getLocale() { return globalLocale.getLocale(); }, diff --git a/packages/editor-core/src/pluginFactory.tsx b/packages/editor-core/src/pluginFactory.tsx deleted file mode 100644 index 2eff60e9e..000000000 --- a/packages/editor-core/src/pluginFactory.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import React, { createRef, PureComponent } from 'react'; - -import EditorContext from './context'; -import { I18nFunction, PluginProps, PluginClass, Plugin } from './definitions'; -import Editor from './editor'; -import { acceptsRef, generateI18n, isEmpty, transformToPromise } from './utils'; - -export default function pluginFactory(Comp: PluginClass): React.ComponentType { - class LowcodePlugin extends PureComponent { - public static displayName = 'LowcodeEditorPlugin'; - - public static contextType = EditorContext; - - public static init = Comp.init; - - public ref: React.RefObject & Plugin; - - private editor: Editor; - - private pluginKey: string; - - private i18n: I18nFunction; - - constructor(props, context) { - super(props, context); - if (isEmpty(props.config) || !props.config.pluginKey) { - console.warn('lowcode editor plugin has wrong config'); - return; - } - const { editor } = props; - this.ref = createRef(); - // 注册插件 - this.editor = editor; - this.pluginKey = props.config.pluginKey; - const defaultProps = Comp.defaultProps || {}; - const locale = this.editor.get('locale') || defaultProps.locale || 'zh-CN'; - const editorMessages = this.editor.get('messages') || {}; - const messages = editorMessages[this.pluginKey] || defaultProps.messages || {}; - this.i18n = generateI18n(locale, messages); - - editor.set('plugins', { - ...editor.plugins, - [this.pluginKey]: this, - }); - } - - public componentWillUnmount(): void { - // 销毁插件 - if (this.pluginKey && this.editor && this.editor.plugins) { - delete this.editor.plugins[this.pluginKey]; - } - } - - public open = (): Promise => { - if (this.ref && this.ref.open && typeof this.ref.open === 'function') { - return transformToPromise(this.ref.open()); - } - return Promise.resolve(); - }; - - public close = (): Promise => { - if (this.ref && this.ref.close && typeof this.ref.close === 'function') { - return transformToPromise(this.ref.close()); - } - return Promise.resolve(); - }; - - public render(): React.ReactNode { - const { config } = this.props; - const props = { - i18n: this.i18n, - editor: this.editor, - config, - ...config.pluginProps, - }; - if (acceptsRef(Comp)) { - props.ref = this.ref; - } - return ; - } - } - - return LowcodePlugin; -} diff --git a/packages/editor-core/src/utils.ts b/packages/editor-core/src/utils.ts deleted file mode 100644 index dd6d6d251..000000000 --- a/packages/editor-core/src/utils.ts +++ /dev/null @@ -1,273 +0,0 @@ -import IntlMessageFormat from 'intl-messageformat'; -import keymaster from 'keymaster'; - -import _clone from 'lodash/cloneDeep'; -import _debounce from 'lodash/debounce'; -import _isEmpty from 'lodash/isEmpty'; -import _deepEqual from 'lodash/isEqualWith'; -import _pick from 'lodash/pick'; -import _throttle from 'lodash/throttle'; - -import _serialize from 'serialize-javascript'; -export { get, post, request } from './request'; -import Editor from './editor'; -import { EditorConfig, I18nFunction, I18nMessages, LocaleType, ShortCutsConfig } from './definitions'; - -export const pick = _pick; -export const deepEqual = _deepEqual; -export const clone = _clone; -export const isEmpty = _isEmpty; -export const throttle = _throttle; -export const debounce = _debounce; - -export const serialize = _serialize; - -const ENV = { - TBE: 'TBE', - WEBIDE: 'WEB-IDE', - VSCODE: 'VSCODE', - WEB: 'WEB', -}; - -declare global { - interface Window { - sendIDEMessage?: (params: IDEMessageParams) => void; - goldlog?: { - record: (logKey: string, gmKey: string, goKey: string, method: 'POST' | 'GET') => (...args: any[]) => any; - }; - is_theia?: boolean; - vscode?: boolean; - } -} - -export interface IDEMessageParams { - action: string; - data: { - logKey: string; - gmKey: string; - goKey: string; - }; -} - -/* - * 用于构造国际化字符串处理函数 - */ -export function generateI18n(locale: LocaleType = 'zh-CN', messages: I18nMessages = {}): I18nFunction { - return (key: string, values): string => { - if (!messages || !messages[key]) { - return ''; - } - const formater = new IntlMessageFormat(messages[key], locale); - return formater.format(values); - }; -} - -/** - * 序列化参数 - */ -export function serializeParams(obj: object): string { - if (typeof obj !== 'object') { - return ''; - } - const res: string[] = []; - Object.entries(obj).forEach(([key, val]): void => { - if (val === null || val === undefined || val === '') { - return; - } - if (typeof val === 'object') { - res.push(`${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(val))}`); - } else { - res.push(`${encodeURIComponent(key)}=${encodeURIComponent(val)}`); - } - }); - return res.join('&'); -} - -/** - * 黄金令箭埋点 - * @param {String} gmKey 为黄金令箭业务类型 - * @param {Object} params 参数 - * @param {String} logKey 属性串 - */ -export function goldlog(gmKey: string, params: object = {}, logKey: string = 'other'): void { - const sendIDEMessage = window.sendIDEMessage || window.parent.sendIDEMessage; - const goKey = serializeParams({ - env: getEnv(), - ...params, - }); - if (sendIDEMessage) { - sendIDEMessage({ - action: 'goldlog', - data: { - logKey: `/iceluna.core.${logKey}`, - gmKey, - goKey, - }, - }); - } - if (window.goldlog) { - window.goldlog.record(`/iceluna.core.${logKey}`, gmKey, goKey, 'POST'); - } -} - -/** - * 获取当前编辑器环境 - */ -export function getEnv(): string { - const userAgent = navigator.userAgent; - const isVscode = /Electron\//.test(userAgent); - if (isVscode) { - return ENV.VSCODE; - } - const isTheia = window.is_theia === true; - if (isTheia) { - return ENV.WEBIDE; - } - return ENV.WEB; -} - -// 注册快捷键 -export function registShortCuts(config: ShortCutsConfig, editor: Editor): void { - (config || []).forEach((item): void => { - keymaster(item.keyboard, (ev: Event): void => { - ev.preventDefault(); - item.handler(editor, ev, keymaster); - }); - }); -} - -// 取消注册快捷 -export function unRegistShortCuts(config: ShortCutsConfig): void { - (config || []).forEach((item): void => { - keymaster.unbind(item.keyboard); - }); - if (window.parent.vscode) { - keymaster.unbind('command+c'); - keymaster.unbind('command+v'); - } -} - -/** - * 将函数返回结果转成promise形式,如果函数有返回值则根据返回值的bool类型判断是reject还是resolve,若函数无返回值默认执行resolve - */ -export function transformToPromise(input: any): Promise<{}> { - if (input instanceof Promise) { - return input; - } - return new Promise((resolve, reject): void => { - if (input || input === undefined) { - resolve(); - } else { - reject(); - } - }); -} - -/** - * 将数组类型转换为Map类型 - */ -interface MapOf { - [propName: string]: T; -} -export function transformArrayToMap(arr: T[], key: string, overwrite: boolean = true): MapOf { - if (isEmpty(arr) || !Array.isArray(arr)) { - return {}; - } - const res = {}; - arr.forEach((item): void => { - const curKey = item[key]; - if (item[key] === undefined) { - return; - } - if (res[curKey] && !overwrite) { - return; - } - res[curKey] = item; - }); - return res; -} - -/** - * 解析url的查询参数 - */ -interface Query { - [propName: string]: string; -} -export function parseSearch(search: string): Query { - if (!search || typeof search !== 'string') { - return {}; - } - const str = search.replace(/^\?/, ''); - const paramStr = str.split('&'); - const res = {}; - paramStr.forEach((item): void => { - const regRes = item.split('='); - if (regRes[0] && regRes[1]) { - res[regRes[0]] = decodeURIComponent(regRes[1]); - } - }); - return res; -} - -export function comboEditorConfig(defaultConfig: EditorConfig = {}, customConfig: EditorConfig): EditorConfig { - const { skeleton, theme, plugins, hooks, shortCuts, lifeCycles, constants, utils, i18n } = customConfig || {}; - - if (skeleton && skeleton.handler && typeof skeleton.handler === 'function') { - return skeleton.handler({ - skeleton, - ...defaultConfig, - }); - } - - const defaultShortCuts = transformArrayToMap(defaultConfig.shortCuts || [], 'keyboard'); - const customShortCuts = transformArrayToMap(shortCuts || [], 'keyboard'); - const localeList = ['zh-CN', 'zh-TW', 'en-US', 'ja-JP']; - const i18nConfig = {}; - localeList.forEach((key): void => { - i18nConfig[key] = { - ...(defaultConfig.i18n && defaultConfig.i18n[key]), - ...(i18n && i18n[key]), - }; - }); - return { - skeleton, - theme: { - ...defaultConfig.theme, - ...theme, - }, - plugins: { - ...defaultConfig.plugins, - ...plugins, - }, - hooks: [...(defaultConfig.hooks || []), ...(hooks || [])], - shortCuts: Object.values({ - ...defaultShortCuts, - ...customShortCuts, - }), - lifeCycles: { - ...defaultConfig.lifeCycles, - ...lifeCycles, - }, - constants: { - ...defaultConfig.constants, - ...constants, - }, - utils: [...(defaultConfig.utils || []), ...(utils || [])], - i18n: i18nConfig, - }; -} - -/** - * 判断当前组件是否能够设置ref - * @param {*} Comp 需要判断的组件 - */ -export function acceptsRef(Comp: React.ReactNode): boolean { - const hasSymbol = typeof Symbol === 'function' && Symbol.for; - const REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0; - if (!Comp || typeof Comp !== 'object' || isEmpty(Comp)) { - return false; - } - return ( - (Comp.$$typeof && Comp.$$typeof === REACT_FORWARD_REF_TYPE) || (Comp.prototype && Comp.prototype.isReactComponent) - ); -} diff --git a/packages/editor-core/src/app-preset.ts b/packages/editor-core/src/utils/app-preset.ts similarity index 100% rename from packages/editor-core/src/app-preset.ts rename to packages/editor-core/src/utils/app-preset.ts diff --git a/packages/globals/src/utils/get-public-path.ts b/packages/editor-core/src/utils/get-public-path.ts similarity index 100% rename from packages/globals/src/utils/get-public-path.ts rename to packages/editor-core/src/utils/get-public-path.ts diff --git a/packages/editor-core/src/utils/goldlog.ts b/packages/editor-core/src/utils/goldlog.ts new file mode 100644 index 000000000..4e594b15c --- /dev/null +++ b/packages/editor-core/src/utils/goldlog.ts @@ -0,0 +1,11 @@ +/** + * 黄金令箭埋点 + * @param {String} gmKey 为黄金令箭业务类型 + * @param {Object} params 参数 + * @param {String} logKey 属性串 + */ +export function goldlog(gmKey: string, params: object = {}, logKey: string = 'other'): void { + +} + + diff --git a/packages/editor-core/src/utils/index.ts b/packages/editor-core/src/utils/index.ts new file mode 100644 index 000000000..8e2f1ccfa --- /dev/null +++ b/packages/editor-core/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './get-public-path'; +export * from './goldlog'; +export * from './obx'; +export * from './request'; diff --git a/packages/globals/src/obx/index.ts b/packages/editor-core/src/utils/obx.ts similarity index 100% rename from packages/globals/src/obx/index.ts rename to packages/editor-core/src/utils/obx.ts diff --git a/packages/editor-core/src/request.ts b/packages/editor-core/src/utils/request.ts similarity index 91% rename from packages/editor-core/src/request.ts rename to packages/editor-core/src/utils/request.ts index 85eafabcf..24cde7293 100644 --- a/packages/editor-core/src/request.ts +++ b/packages/editor-core/src/utils/request.ts @@ -1,8 +1,10 @@ -import 'whatwg-fetch'; import Debug from 'debug'; const debug = Debug('request'); -export function serialize(obj: object): string { +export function serialize(obj?: object): string { + if (!obj) { + return ''; + } const rst: string[] = []; Object.entries(obj || {}).forEach(([key, val]): void => { if (val === null || val === undefined || val === '') return; @@ -12,7 +14,7 @@ export function serialize(obj: object): string { return rst.join('&'); } -export function buildUrl(dataAPI: string, params: object): string { +export function buildUrl(dataAPI: string, params?: object): string { const paramStr = serialize(params); if (paramStr) { return dataAPI.indexOf('?') > 0 ? `${dataAPI}&${paramStr}` : `${dataAPI}?${paramStr}`; @@ -25,7 +27,7 @@ export function get(dataAPI: string, params?: object, headers?: object, otherPro Accept: 'application/json', ...headers, }; - return request(buildUrl(dataAPI, params), 'GET', null, fetchHeaders, otherProps); + return request(buildUrl(dataAPI, params), 'GET', undefined, fetchHeaders, otherProps); } export function post(dataAPI: string, params?: object, headers?: object, otherProps?: object): Promise { @@ -50,7 +52,7 @@ export function request( method: string = 'GET', data?: object | string, headers?: object, - otherProps?: object, + otherProps?: any, ): Promise { return new Promise((resolve, reject): void => { if (otherProps && otherProps.timeout) { @@ -109,7 +111,7 @@ export function request( return null; } }) - .then((json: object): void => { + .then((json: any): void => { if (json && json.__success !== false) { resolve(json); } else { diff --git a/packages/globals/src/components/index.ts b/packages/editor-core/src/widgets/index.ts similarity index 63% rename from packages/globals/src/components/index.ts rename to packages/editor-core/src/widgets/index.ts index 196dee25a..d3260bcaa 100644 --- a/packages/globals/src/components/index.ts +++ b/packages/editor-core/src/widgets/index.ts @@ -1,3 +1,3 @@ +// TODO move another place export * from './tip'; export * from './title'; -export * from './svg-icon'; diff --git a/packages/editor-core/src/widgets/tip/index.ts b/packages/editor-core/src/widgets/tip/index.ts new file mode 100644 index 000000000..dba4412c7 --- /dev/null +++ b/packages/editor-core/src/widgets/tip/index.ts @@ -0,0 +1,4 @@ +import './style.less'; + +export * from './tip'; +export * from './tip-container'; diff --git a/packages/globals/src/components/tip/style.less b/packages/editor-core/src/widgets/tip/style.less similarity index 100% rename from packages/globals/src/components/tip/style.less rename to packages/editor-core/src/widgets/tip/style.less diff --git a/packages/globals/src/components/tip/tip-container.tsx b/packages/editor-core/src/widgets/tip/tip-container.tsx similarity index 83% rename from packages/globals/src/components/tip/tip-container.tsx rename to packages/editor-core/src/widgets/tip/tip-container.tsx index 31585c547..35ff58f14 100644 --- a/packages/globals/src/components/tip/tip-container.tsx +++ b/packages/editor-core/src/widgets/tip/tip-container.tsx @@ -1,8 +1,8 @@ import { Component } from 'react'; -import Tip from './tip'; -import tipHandler from './tip-handler'; +import { TipItem } from './tip-item'; +import { tipHandler } from './tip-handler'; -export default class TipContainer extends Component { +export class TipContainer extends Component { shouldComponentUpdate() { return false; } @@ -29,7 +29,7 @@ export default class TipContainer extends Component { render() { return (
- +
); } diff --git a/packages/globals/src/components/tip/tip-handler.ts b/packages/editor-core/src/widgets/tip/tip-handler.ts similarity index 93% rename from packages/globals/src/components/tip/tip-handler.ts rename to packages/editor-core/src/widgets/tip/tip-handler.ts index db347f847..d528a52af 100644 --- a/packages/globals/src/components/tip/tip-handler.ts +++ b/packages/editor-core/src/widgets/tip/tip-handler.ts @@ -1,54 +1,10 @@ import { EventEmitter } from 'events'; -import { TipConfig } from '../../types'; +import { TipConfig } from '@ali/lowcode-types'; export interface TipOptions extends TipConfig { target: HTMLElement; } -function findTip(target: HTMLElement | null): TipOptions | null { - if (!target) { - return null; - } - // optimize deep finding on mouseover - let loopupLimit = 10; - while (target && loopupLimit-- > 0) { - // get tip from target node - if (target.dataset && target.dataset.tip) { - return { - children: target.dataset.tip, - direction: (target.dataset.direction || target.dataset.dir) as any, - theme: target.dataset.theme, - target, - }; - } - - // or get tip from child nodes - let child: HTMLElement | null = target.lastElementChild as HTMLElement; - - while (child) { - if (child.dataset && child.dataset.role === 'tip') { - const tipId = child.dataset.tipId; - if (!tipId) { - return null; - } - const tipProps = tipsMap.get(tipId); - if (!tipProps) { - return null; - } - return { - ...tipProps, - target, - }; - } - child = child.previousElementSibling as HTMLElement; - } - - target = target.parentNode as HTMLElement; - } - - return null; -} - class TipHandler { tip: TipOptions | null = null; private showDelay: number | null = null; @@ -60,7 +16,7 @@ class TipHandler { if (tip) { if (this.tip) { // the some target should return - if (this.tip.target === tip.target) { + if ((this.tip as any).target === (tip as any).target) { this.tip = tip; return; } @@ -127,13 +83,57 @@ class TipHandler { } } +export const tipHandler = new TipHandler(); + +function findTip(target: HTMLElement | null): TipOptions | null { + if (!target) { + return null; + } + // optimize deep finding on mouseover + let loopupLimit = 10; + while (target && loopupLimit-- > 0) { + // get tip from target node + if (target.dataset && target.dataset.tip) { + return { + children: target.dataset.tip, + direction: (target.dataset.direction || target.dataset.dir) as any, + theme: target.dataset.theme, + target, + }; + } + + // or get tip from child nodes + let child: HTMLElement | null = target.lastElementChild as HTMLElement; + + while (child) { + if (child.dataset && child.dataset.role === 'tip') { + const tipId = child.dataset.tipId; + if (!tipId) { + return null; + } + const tipProps = tipsMap.get(tipId); + if (!tipProps) { + return null; + } + return { + ...tipProps, + target, + }; + } + child = child.previousElementSibling as HTMLElement; + } + + target = target.parentNode as HTMLElement; + } + + return null; +} + const tipsMap = new Map(); -export function saveTips(id: string, props: TipConfig | null) { +export function postTip(id: string, props: TipConfig | null) { if (props) { tipsMap.set(id, props); } else { tipsMap.delete(id); } } - -export default new TipHandler(); diff --git a/packages/globals/src/components/tip/tip.tsx b/packages/editor-core/src/widgets/tip/tip-item.tsx similarity index 91% rename from packages/globals/src/components/tip/tip.tsx rename to packages/editor-core/src/widgets/tip/tip-item.tsx index 20d6c7928..558d13768 100644 --- a/packages/globals/src/components/tip/tip.tsx +++ b/packages/editor-core/src/widgets/tip/tip-item.tsx @@ -1,10 +1,11 @@ import { Component } from 'react'; import classNames from 'classnames'; +import { intl } from '@ali/lowcode-editor-core'; +import { TipConfig } from '@ali/lowcode-types'; import { resolvePosition } from './utils'; -import tipHandler, { TipOptions } from './tip-handler'; -import { intl } from '../../intl'; +import { tipHandler } from './tip-handler'; -export default class Tip extends Component { +export class TipItem extends Component { private dispose?: () => void; constructor(props: any) { super(props); @@ -101,7 +102,7 @@ export default class Tip extends Component { } render() { - const tip: TipOptions = tipHandler.tip || ({} as any); + const tip: TipConfig = tipHandler.tip || ({} as any); const className = classNames('lc-tip', tip.className, tip && tip.theme ? `lc-theme-${tip.theme}` : null); this.originClassName = className; diff --git a/packages/editor-core/src/widgets/tip/tip.tsx b/packages/editor-core/src/widgets/tip/tip.tsx new file mode 100644 index 000000000..4da9bdfc9 --- /dev/null +++ b/packages/editor-core/src/widgets/tip/tip.tsx @@ -0,0 +1,17 @@ +import { Component } from 'react'; +import { TipConfig } from '@ali/lowcode-types'; +import { uniqueId } from '@ali/lowcode-utils'; +import { postTip } from './tip-handler'; + +export class Tip extends Component { + private id = uniqueId('tips$'); + + componentWillUnmount() { + postTip(this.id, null); + } + + render() { + postTip(this.id, this.props); + return ; + } +} diff --git a/packages/globals/src/components/tip/utils.ts b/packages/editor-core/src/widgets/tip/utils.ts similarity index 100% rename from packages/globals/src/components/tip/utils.ts rename to packages/editor-core/src/widgets/tip/utils.ts diff --git a/packages/globals/src/components/title/index.tsx b/packages/editor-core/src/widgets/title/index.tsx similarity index 80% rename from packages/globals/src/components/title/index.tsx rename to packages/editor-core/src/widgets/title/index.tsx index 247ec517b..4b19bda72 100644 --- a/packages/globals/src/components/title/index.tsx +++ b/packages/editor-core/src/widgets/title/index.tsx @@ -1,10 +1,10 @@ import { Component, isValidElement } from 'react'; import classNames from 'classnames'; -import EmbedTip from '../tip/embed-tip'; -import './title.less'; -import { createIcon } from '../../utils'; -import { TitleContent, isI18nData } from '../../types'; +import { createIcon } from '@ali/lowcode-utils'; +import { TitleContent, isI18nData } from '@ali/lowcode-types'; import { intl } from '../../intl'; +import { Tip } from '../tip'; +import './title.less'; export class Title extends Component<{ title: TitleContent; className?: string; onClick?: () => void }> { render() { @@ -20,14 +20,14 @@ export class Title extends Component<{ title: TitleContent; className?: string; let tip: any = null; if (title.tip) { - if (isValidElement(title.tip) && title.tip.type === EmbedTip) { + if (isValidElement(title.tip) && title.tip.type === Tip) { tip = title.tip; } else { const tipProps = typeof title.tip === 'object' && !(isValidElement(title.tip) || isI18nData(title.tip)) ? title.tip : { children: title.tip }; - tip = ; + tip = ; } } diff --git a/packages/globals/src/components/title/title.less b/packages/editor-core/src/widgets/title/title.less similarity index 100% rename from packages/globals/src/components/title/title.less rename to packages/editor-core/src/widgets/title/title.less diff --git a/packages/editor-core/tsconfig.json b/packages/editor-core/tsconfig.json index c37b76ecc..91c180bdd 100644 --- a/packages/editor-core/tsconfig.json +++ b/packages/editor-core/tsconfig.json @@ -3,7 +3,5 @@ "compilerOptions": { "outDir": "lib" }, - "include": [ - "./src/" - ] + "include": ["./src/"], } diff --git a/packages/editor-skeleton/src/area.ts b/packages/editor-skeleton/src/area.ts new file mode 100644 index 000000000..aafbab857 --- /dev/null +++ b/packages/editor-skeleton/src/area.ts @@ -0,0 +1,59 @@ +import { obx, computed } from '@ali/lowcode-editor-core'; +import WidgetContainer from './widget/widget-container'; +import { Skeleton } from './skeleton'; +import { IWidget } from './widget/widget'; +import { IWidgetBaseConfig } from './types'; + +export default class Area { + @obx private _visible: boolean = true; + + @computed get visible() { + if (this.exclusive) { + return this.container.current != null; + } + return this._visible; + } + + get current() { + if (this.exclusive) { + return this.container.current; + } + return null; + } + + readonly container: WidgetContainer; + constructor(readonly skeleton: Skeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent: boolean = false) { + this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent); + } + + @computed isEmpty(): boolean { + return this.container.items.length < 1; + } + + add(config: T | C): T { + return this.container.add(config); + } + + private lastCurrent: T | null = null; + setVisible(flag: boolean) { + if (this.exclusive) { + const current = this.container.current; + if (flag && !current) { + this.container.active(this.lastCurrent || this.container.getAt(0)) + } else if (current) { + this.lastCurrent = current; + this.container.unactive(current); + } + return; + } + this._visible = flag; + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } +} diff --git a/packages/editor-skeleton/src/components/LeftPlugin/index.scss b/packages/editor-skeleton/src/components/LeftPlugin/index.scss deleted file mode 100644 index f78fca1ee..000000000 --- a/packages/editor-skeleton/src/components/LeftPlugin/index.scss +++ /dev/null @@ -1,59 +0,0 @@ -.lowcode-left-plugin { - font-size: 20px; - text-align: center; - line-height: 44px; - height: 44px; - position: relative; - cursor: pointer; - transition: all 0.3s ease; - color: $color-text1-3; - &.locked { - color: red !important; - } - &:hover { - color: $color-brand1-6; - &:before { - content: attr(data-tooltip); - display: block; - position: absolute; - left: 45px; - top: 8px; - line-height: 18px; - font-size: 12px; - white-space: nowrap; - padding: 6px 8px; - border-radius: 4px; - background: $balloon-normal-color-bg; - border: 1px solid $balloon-normal-color-border; - color: $color-text1-3; - z-index: 100; - } - &:after { - content: ''; - display: block; - position: absolute; - width: 10px; - height: 10px; - transform: rotate(45deg); - left: 40px; - top: 18px; - background: $balloon-normal-color-bg; - border-left: 1px solid $balloon-normal-color-border; - border-bottom: 1px solid $balloon-normal-color-border; - z-index: 100; - } - } - &.active { - color: $color-brand1-9; - &.disabled { - color: $color-text1-1; - } - &:hover { - color: $color-brand1-6; - } - } - &.disabled { - cursor: not-allowed; - color: $color-text1-1; - } -} diff --git a/packages/editor-skeleton/src/components/LeftPlugin/index.tsx b/packages/editor-skeleton/src/components/LeftPlugin/index.tsx deleted file mode 100644 index 7770c942c..000000000 --- a/packages/editor-skeleton/src/components/LeftPlugin/index.tsx +++ /dev/null @@ -1,221 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; -import classNames from 'classnames'; -import { Balloon, Dialog, Icon, Badge } from '@alifd/next'; -import Editor from '@ali/lowcode-editor-core'; -import { - PluginConfig, - PluginClass, -} from '@ali/lowcode-editor-core/lib/definitions'; -import './index.scss'; - -export interface LeftPluginProps { - active?: boolean; - config: PluginConfig; - disabled?: boolean; - editor: Editor; - locked?: boolean; - marked?: boolean; - onClick?: () => void; - pluginClass: PluginClass | undefined; -} - -export interface LeftPluginState { - dialogVisible: boolean; -} - -export default class LeftPlugin extends PureComponent< - LeftPluginProps, - LeftPluginState -> { - static displayName = 'LowcodeLeftPlugin'; - - static defaultProps = { - active: false, - config: {}, - disabled: false, - marked: false, - locked: false, - onClick: (): void => {}, - }; - - constructor(props, context) { - super(props, context); - this.state = { - dialogVisible: false, - }; - } - - componentDidMount(): void { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (editor && pluginKey) { - editor.on(`${pluginKey}.dialog.show`, this.handleShow); - editor.on(`${pluginKey}.dialog.close`, this.handleClose); - } - } - - componentWillUnmount(): void { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (editor && pluginKey) { - editor.off(`${pluginKey}.dialog.show`, this.handleShow); - editor.off(`${pluginKey}.dialog.close`, this.handleClose); - } - } - - handleClose = (): void => { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - const plugin = editor.plugins && editor.plugins[pluginKey]; - if (plugin) { - plugin.close().then((): void => { - this.setState({ - dialogVisible: false, - }); - }); - } - }; - - handleOpen = (): void => { - // todo 对话框类型的插件初始时拿不到插件实例 - this.setState({ - dialogVisible: true, - }); - }; - - handleShow = (): void => { - const { disabled, config, onClick, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (disabled || !pluginKey) return; - this.handleOpen(); - // 考虑到弹窗情况,延时发送消息 - setTimeout((): void => { - editor.emit(`${pluginKey}.plugin.activate`); - }, 0); - if (onClick) { - onClick(); - } - }; - - renderIcon = (clickCallback): React.ReactNode => { - const { active, disabled, marked, locked, onClick, config } = this.props; - const { pluginKey, props } = config || {}; - const { icon, title } = props || {}; - return ( -
{ - if (disabled) return; - // 考虑到弹窗情况,延时发送消息 - clickCallback && clickCallback(); - - onClick && onClick(); - }} - > - {marked ? ( - - - - ) : ( - - )} -
- ); - }; - - render(): React.ReactNode { - const { - marked, - locked, - active, - disabled, - config, - editor, - pluginClass: Comp, - } = this.props; - const { pluginKey, props, type, pluginProps } = config || {}; - const { onClick, title } = props || {}; - const { dialogVisible } = this.state; - if (!pluginKey || !type || !props) return null; - - const node = Comp ? ( - { - onClick && onClick.call(null, editor); - }} - {...pluginProps} - /> - ) : null; - switch (type) { - case 'LinkIcon': - return ( - - {this.renderIcon((): void => { - onClick && onClick.call(null, editor); - })} - - ); - case 'Icon': - return this.renderIcon((): void => { - onClick && onClick.call(null, editor); - }); - case 'DialogIcon': - return ( - - {this.renderIcon((): void => { - onClick && onClick.call(null, editor); - this.handleOpen(); - })} - { - editor.emit(`${pluginKey}.dialog.onOk`); - this.handleClose(); - }} - onCancel={this.handleClose} - onClose={this.handleClose} - title={title} - style={{ - width: 500, - ...(props.dialogProps && props.dialogProps.style), - }} - {...(props.dialogProps || {})} - visible={dialogVisible} - > - {node} - - - ); - case 'BalloonIcon': - return ( - { - onClick && onClick.call(null, editor); - })} - align="r" - triggerType={['click', 'hover']} - {...(props.balloonProps || {})} - > - {node} - - ); - case 'PanelIcon': - return this.renderIcon((): void => { - onClick && onClick.call(null, editor); - }); - case 'Custom': - return marked ? {node} : node; - default: - return null; - } - } -} diff --git a/packages/editor-skeleton/src/components/Panel/index.scss b/packages/editor-skeleton/src/components/Panel/index.scss deleted file mode 100644 index 8a9660638..000000000 --- a/packages/editor-skeleton/src/components/Panel/index.scss +++ /dev/null @@ -1,52 +0,0 @@ -.lowcode-panel { - user-select: none; - overflow: hidden; - position: relative; - background: $card-background; - transition: width 0.3s ease; - transform: translate3d(0, 0, 0); - height: 100%; - &.visible { - border-right: 1px solid $color-line1-1; - } - .drag-area { - display: none; - } - &.floatable { - position: absolute; - top: 0; - bottom: 0; - z-index: 999; - } - &.draggable { - .drag-area { - display: block; - width: 10px; - position: absolute; - top: 0; - bottom: 0; - cursor: col-resize; - z-index: 9999; - } - &.left { - .drag-area { - right: 0; - } - } - &.right { - .drag-area { - left: 0; - } - } - } - &.left { - &.floatable { - left: 50px; - } - } - &.right { - &.floatable { - right: 48px; - } - } -} diff --git a/packages/editor-skeleton/src/components/Panel/index.tsx b/packages/editor-skeleton/src/components/Panel/index.tsx deleted file mode 100644 index 6cdb1bd40..000000000 --- a/packages/editor-skeleton/src/components/Panel/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { PureComponent } from 'react'; -import classNames from 'classnames'; - -import './index.scss'; - -export interface PanelProps { - align: 'left' | 'right'; - defaultWidth: number; - minWidth: number; - draggable: boolean; - floatable: boolean; - children: Plugin; - visible: boolean; -} - -export interface PanelState { - width: number; -} - -export default class Panel extends PureComponent { - static displayName = 'LowcodePanel'; - - static defaultProps = { - align: 'left', - defaultWidth: 240, - minWidth: 100, - draggable: true, - floatable: false, - visible: true, - }; - - constructor(props) { - super(props); - - this.state = { - width: props.defaultWidth, - }; - } - - render(): React.ReactNode { - const { align, draggable, floatable, visible } = this.props; - const { width } = this.state; - return ( -
- {this.props.children} -
-
- ); - } -} diff --git a/packages/editor-skeleton/src/components/TopIcon/index.scss b/packages/editor-skeleton/src/components/TopIcon/index.scss deleted file mode 100644 index 065fb859e..000000000 --- a/packages/editor-skeleton/src/components/TopIcon/index.scss +++ /dev/null @@ -1,77 +0,0 @@ -.lowcode-top-icon { - display: inline-block; - width: 44px; - font-size: 20px; - line-height: 48px; - color: $color-text1-3; - position: relative; - &.disabled { - cursor: not-allowed; - color: $color-text1-1; - &:hover { - color: $color-text1-1; - } - } - &.active { - color: $color-brand1-9; - &:hover { - color: $color-brand1-6; - } - } - &.locked { - color: red !important; - } - &:hover { - color: $color-brand1-6; - &:before { - content: attr(data-tooltip); - display: block; - height: auto; - width: auto; - position: absolute; - left: 50%; - transform: translate(-50%, 0); - bottom: -32px; - line-height: 18px; - font-size: 12px; - white-space: nowrap; - padding: 6px 8px; - border-radius: 4px; - background: $balloon-normal-color-bg; - border: 1px solid $balloon-normal-color-border; - color: $color-text1-3; - z-index: 100; - } - &:after { - content: ''; - display: block; - position: absolute; - width: 10px; - height: 10px; - left: 50%; - transform: translate(-50%, 0) rotate(45deg); - bottom: -5px; - background: $balloon-normal-color-bg; - border-left: 1px solid $balloon-normal-color-border; - border-top: 1px solid $balloon-normal-color-border; - opacity: 1; - visibility: visible; - z-index: 100; - } - } - i.next-icon { - &:before { - font-size: 16px; - } - margin-right: 0; - line-height: 18px; - } - span { - display: block; - margin: 0px -5px 0; - line-height: 16px; - text-align: center; - font-size: 12px; - transform: scale(0.8); - } -} diff --git a/packages/editor-skeleton/src/components/TopIcon/index.tsx b/packages/editor-skeleton/src/components/TopIcon/index.tsx deleted file mode 100644 index 939f77ffc..000000000 --- a/packages/editor-skeleton/src/components/TopIcon/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { PureComponent } from 'react'; -import classNames from 'classnames'; -import { Icon } from '@alifd/next'; - -import './index.scss'; - -export interface TopIconProps { - active?: boolean; - className?: string; - disabled?: boolean; - icon: string; - id?: string; - locked?: boolean; - marked?: boolean; - onClick?: () => void; - style?: React.CSSProperties; - title?: string; -} - -export default class TopIcon extends PureComponent { - static displayName = 'LowcodeTopIcon'; - - static defaultProps = { - active: false, - className: '', - disabled: false, - icon: '', - id: '', - locked: false, - onClick: (): void => {}, - style: {}, - title: '', - }; - - render(): React.ReactNode { - const { - active, - disabled, - icon, - locked, - title, - className, - id, - style, - onClick, - } = this.props; - return ( -
- -
- ); - } -} diff --git a/packages/editor-skeleton/src/components/TopPlugin/index.scss b/packages/editor-skeleton/src/components/TopPlugin/index.scss deleted file mode 100644 index 4bdd7b8d2..000000000 --- a/packages/editor-skeleton/src/components/TopPlugin/index.scss +++ /dev/null @@ -1,2 +0,0 @@ -.lowcode-top-addon { -} diff --git a/packages/editor-skeleton/src/components/TopPlugin/index.tsx b/packages/editor-skeleton/src/components/TopPlugin/index.tsx deleted file mode 100644 index 71eccf28a..000000000 --- a/packages/editor-skeleton/src/components/TopPlugin/index.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; - -import { Balloon, Badge, Dialog } from '@alifd/next'; -import Editor from '@ali/lowcode-editor-core'; -import { - PluginConfig, - PluginClass, -} from '@ali/lowcode-editor-core/lib/definitions'; -import TopIcon from '../TopIcon'; - -import './index.scss'; - -export interface TopPluginProps { - active?: boolean; - config: PluginConfig; - disabled?: boolean; - editor: Editor; - locked?: boolean; - marked?: boolean; - onClick?: () => void; - pluginClass: PluginClass | undefined; -} - -export interface TopPluginState { - dialogVisible: boolean; -} - -export default class TopPlugin extends PureComponent< - TopPluginProps, - TopPluginState -> { - static displayName = 'LowcodeTopPlugin'; - - static defaultProps = { - active: false, - config: {}, - disabled: false, - marked: false, - locked: false, - onClick: (): void => {}, - }; - - constructor(props, context) { - super(props, context); - this.state = { - dialogVisible: false, - }; - } - - componentDidMount(): void { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (editor && pluginKey) { - editor.on(`${pluginKey}.dialog.show`, this.handleShow); - editor.on(`${pluginKey}.dialog.close`, this.handleClose); - } - } - - componentWillUnmount(): void { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (editor && pluginKey) { - editor.off(`${pluginKey}.dialog.show`, this.handleShow); - editor.off(`${pluginKey}.dialog.close`, this.handleClose); - } - } - - handleShow = (): void => { - const { disabled, config, onClick, editor } = this.props; - const pluginKey = config && config.pluginKey; - if (disabled || !pluginKey) return; - this.handleOpen(); - // 考虑到弹窗情况,延时发送消息 - setTimeout((): void => { - editor.emit(`${pluginKey}.plugin.activate`); - }, 0); - onClick && onClick(); - }; - - handleClose = (): void => { - const { config, editor } = this.props; - const pluginKey = config && config.pluginKey; - const plugin = editor.plugins && editor.plugins[pluginKey]; - if (plugin) { - plugin.close().then((): void => { - this.setState({ - dialogVisible: false, - }); - }); - } - }; - - handleOpen = (): void => { - // todo dialog类型的插件初始时拿不动插件实例 - this.setState({ - dialogVisible: true, - }); - }; - - renderIcon = (clickCallback): React.ReactNode => { - const { - active, - disabled, - marked, - locked, - config, - onClick, - editor, - } = this.props; - const { pluginKey, props } = config || {}; - const { icon, title } = props || {}; - const node = ( - { - if (disabled) return; - // 考虑到弹窗情况,延时发送消息 - setTimeout((): void => { - editor.emit(`${pluginKey}.plugin.activate`); - }, 0); - clickCallback && clickCallback(); - onClick && onClick(); - }} - /> - ); - return marked ? {node} : node; - }; - - render(): React.ReactNode { - const { - active, - marked, - locked, - disabled, - config, - editor, - pluginClass: Comp, - } = this.props; - const { pluginKey, pluginProps, props, type } = config || {}; - const { onClick, title } = props || {}; - const { dialogVisible } = this.state; - if (!pluginKey || !type) return null; - const node = Comp ? ( - { - onClick && onClick.call(null, editor); - }} - {...pluginProps} - /> - ) : null; - - switch (type) { - case 'LinkIcon': - return ( - - {this.renderIcon((): void => { - onClick && onClick.call(null, editor); - })} - - ); - case 'Icon': - return this.renderIcon((): void => { - onClick && onClick.call(null, editor); - }); - case 'DialogIcon': - return ( - - {this.renderIcon((): void => { - onClick && onClick.call(null, editor); - this.handleOpen(); - })} - { - editor.emit(`${pluginKey}.dialog.onOk`); - this.handleClose(); - }} - onCancel={this.handleClose} - onClose={this.handleClose} - title={title} - style={{ - width: 500, - ...(props.dialogProps && props.dialogProps.style), - }} - {...props.dialogProps} - visible={dialogVisible} - > - {node} - - - ); - case 'BalloonIcon': - return ( - { - onClick && onClick.call(null, editor); - })} - triggerType={['click', 'hover']} - {...props.balloonProps} - > - {node} - - ); - case 'Custom': - return marked ? {node} : node; - default: - return null; - } - } -} diff --git a/packages/editor-skeleton/src/components/array-setter/bugs.md b/packages/editor-skeleton/src/components/array-setter/bugs.md new file mode 100644 index 000000000..8fe96cc16 --- /dev/null +++ b/packages/editor-skeleton/src/components/array-setter/bugs.md @@ -0,0 +1,5 @@ +* 拖拽排序有问题 +* forceInline 有问题 +* 部分改变不响应 +* 样式还原 +* autofocus diff --git a/packages/editor-skeleton/src/components/array-setter/index.tsx b/packages/editor-skeleton/src/components/array-setter/index.tsx new file mode 100644 index 000000000..2f12b6e8f --- /dev/null +++ b/packages/editor-skeleton/src/components/array-setter/index.tsx @@ -0,0 +1,280 @@ +import { Component, Fragment } from 'react'; +import { Icon, Button, Message } from '@alifd/next'; +import { Title } from '@ali/lowcode-editor-core'; +import { SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-types'; +import { SettingField } from '@ali/lowcode-designer'; +import { createSettingFieldView } from '../settings/settings-pane'; +import { PopupContext, PopupPipe } from '../popup'; +import Sortable from './sortable'; +import './style.less'; + +interface ArraySetterState { + items: SettingField[]; + itemsMap: Map; + prevLength: number; +} + +interface ArraySetterProps { + value: any[]; + field: SettingField; + itemSetter?: SetterType; + columns?: FieldConfig[]; + multiValue?: boolean; +} + +export class ListSetter extends Component { + static getDerivedStateFromProps(props: ArraySetterProps, state: ArraySetterState) { + const { value, field } = props; + const newLength = value && Array.isArray(value) ? value.length : 0; + if (state && state.prevLength === newLength) { + return null; + } + + // props value length change will go here + const originLength = state ? state.items.length : 0; + if (state && originLength === newLength) { + return { + prevLength: newLength, + }; + } + + const itemsMap = state ? state.itemsMap : new Map(); + let items = state ? state.items.slice() : []; + if (newLength > originLength) { + for (let i = originLength; i < newLength; i++) { + const item = field.createField({ + name: i, + setter: props.itemSetter, + // FIXME: + forceInline: 1, + }); + items[i] = item; + itemsMap.set(item.id, item); + } + } else if (newLength < originLength) { + const deletes = items.splice(newLength); + deletes.forEach((item) => { + itemsMap.delete(item.id); + }); + } + return { + items, + itemsMap, + prevLength: newLength, + }; + } + + state: ArraySetterState = { + items: [], + itemsMap: new Map(), + prevLength: 0, + }; + + onSort(sortedIds: Array) { + const { itemsMap } = this.state; + const items = sortedIds.map((id, index) => { + const item = itemsMap.get(id)!; + item.setKey(index); + return item; + }); + this.setState({ + items, + }); + } + + private scrollToLast: boolean = false; + onAdd() { + const { items, itemsMap } = this.state; + const { itemSetter } = this.props; + const initialValue = typeof itemSetter === 'object' ? (itemSetter as any).initialValue : null; + const item = this.props.field.createField({ + name: items.length, + setter: itemSetter, + // FIXME: + forceInline: 1, + }); + items.push(item); + itemsMap.set(item.id, item); + item.setValue(typeof initialValue === 'function' ? initialValue(item) : initialValue); + this.scrollToLast = true; + this.setState({ + items: items.slice(), + }); + } + + onRemove(field: SettingField) { + const { items } = this.state; + let i = items.indexOf(field); + if (i < 0) { + return; + } + items.splice(i, 1); + const l = items.length; + while (i < l) { + items[i].setKey(i); + i++; + } + field.remove(); + this.setState({ items: items.slice() }); + } + + componentWillUnmount() { + this.state.items.forEach((field) => { + field.purge(); + }); + } + + shouldComponentUpdate(_: any, nextState: ArraySetterState) { + if (nextState.items !== this.state.items) { + return true; + } + return false; + } + + render() { + let columns: any = null; + if (this.props.columns) { + columns = this.props.columns.map((column) => ); + } + + const { items } = this.state; + const scrollToLast = this.scrollToLast; + this.scrollToLast = false; + const lastIndex = items.length - 1; + + const content = + items.length > 0 ? ( + <div className="lc-setter-list-scroll-body"> + <Sortable itemClassName="lc-setter-list-card" onSort={this.onSort.bind(this)}> + {items.map((field, index) => ( + <ArrayItem + key={field.id} + scrollIntoView={scrollToLast && index === lastIndex} + field={field} + onRemove={this.onRemove.bind(this, field)} + /> + ))} + </Sortable> + </div> + ) : this.props.multiValue ? ( + <Message type="warning">当前选择了多个节点,且值不一致,修改会覆盖所有值</Message> + ) : ( + <Message type="notice">当前项目为空</Message> + ); + + return ( + <div className="lc-setter-list lc-block-setter"> + {/*<div className="lc-block-setter-actions"> + <Button size="medium" onClick={this.onAdd.bind(this)}> + <Icon type="add" /> + <span>添加</span> + </Button> + </div>*/} + {columns && <div className="lc-setter-list-columns">{columns}</div>} + {content} + <Button className="lc-setter-list-add" type="primary" onClick={this.onAdd.bind(this)}> + <Icon type="add" /> + <span>添加一项</span> + </Button> + </div> + ); + } +} + +class ArrayItem extends Component<{ + field: SettingField; + onRemove: () => void; + scrollIntoView: boolean; +}> { + shouldComponentUpdate() { + return false; + } + private shell?: HTMLDivElement | null; + componentDidMount() { + if (this.props.scrollIntoView && this.shell) { + this.shell.parentElement!.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + } + } + render() { + const { onRemove, field } = this.props; + return ( + <div className="lc-listitem" ref={(ref) => (this.shell = ref)}> + <div draggable className="lc-listitem-handler"> + <Icon type="ellipsis" size="small" /> + </div> + <div className="lc-listitem-body">{createSettingFieldView(field, field.parent)}</div> + <div className="lc-listitem-actions"> + <div className="lc-listitem-action" onClick={onRemove}> + <Icon type="ashbin" size="small" /> + </div> + </div> + </div> + ); + } +} + +class TableSetter extends ListSetter { + // todo: + // forceInline = 1 + // has more actions +} + +export default class ArraySetter extends Component<{ + value: any[]; + field: SettingField; + itemSetter?: SetterType; + mode?: 'popup' | 'list'; + forceInline?: boolean; + multiValue?: boolean; +}> { + static contextType = PopupContext; + private pipe: any; + render() { + const { mode, forceInline, ...props } = this.props; + const { field, itemSetter } = props; + let columns: FieldConfig[] | undefined; + if ((itemSetter as SetterConfig)?.componentName === 'ObjectSetter') { + const items: FieldConfig[] = (itemSetter as any).props?.config?.items; + if (items && Array.isArray(items)) { + columns = items.filter((item) => item.isRequired || item.important || (item.setter as any)?.isRequired); + if (columns.length > 4) { + columns = columns.slice(0, 4); + } + } + } + + if (mode === 'popup' || forceInline) { + const title = ( + <Fragment> + 编辑: + <Title title={field.title} /> + </Fragment> + ); + if (!this.pipe) { + let width = 360; + if (columns) { + if (columns.length === 3) { + width = 480; + } else if (columns.length > 3) { + width = 600; + } + } + this.pipe = (this.context as PopupPipe).create({ width }); + } + this.pipe.send(<TableSetter key={field.id} {...props} columns={columns} />, title); + return ( + <Button + type={forceInline ? 'normal' : 'primary'} + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon type="edit" /> + {forceInline ? title : '编辑数组'} + </Button> + ); + } else { + return <ListSetter {...props} columns={columns?.slice(0, 2)} />; + } + } +} diff --git a/packages/editor-skeleton/src/components/array-setter/sortable.less b/packages/editor-skeleton/src/components/array-setter/sortable.less new file mode 100644 index 000000000..12e9512cd --- /dev/null +++ b/packages/editor-skeleton/src/components/array-setter/sortable.less @@ -0,0 +1,29 @@ +.lc-sortable { + position: relative; + + .lc-sortable-card { + box-sizing: border-box; + &:after, &:before { + content: ""; + display: table; + } + &:after { + clear: both; + } + + &.lc-dragging { + outline: 2px dashed var(--color-brand); + outline-offset: -2px; + > * { + visibility: hidden; + } + border-color: transparent !important; + box-shadow: none !important; + background: transparent !important; + } + } + + [draggable] { + cursor: ns-resize; + } +} diff --git a/packages/editor-skeleton/src/components/array-setter/sortable.tsx b/packages/editor-skeleton/src/components/array-setter/sortable.tsx new file mode 100644 index 000000000..3329470f1 --- /dev/null +++ b/packages/editor-skeleton/src/components/array-setter/sortable.tsx @@ -0,0 +1,220 @@ +import { Component, Children, ReactElement } from 'react'; +import classNames from 'classnames'; +import './sortable.less'; + +class Sortable extends Component<{ + className?: string; + itemClassName?: string; + onSort?: (sortedIds: Array<string | number>) => void; + dragImageSourceHandler?: (elem: Element) => Element; + children: ReactElement[]; +}> { + private shell?: HTMLDivElement | null; + private items?: Array<string | number>; + private willDetach?: () => void; + componentDidMount() { + const box = this.shell!; + + let isDragEnd: boolean = false; + + /** + * target node to be dragged + */ + let source: Element | null; + + /** + * node to be placed + */ + let ref: Element | null; + + /** + * next sibling of the source node + */ + let origRef: Element | null; + + /** + * accurately locate the node from event + */ + const locate = (e: DragEvent) => { + let y = e.clientY; + if (e.view !== window && e.view!.frameElement) { + y += e.view!.frameElement.getBoundingClientRect().top; + } + let node = box.firstElementChild as HTMLDivElement; + while (node) { + if (node !== source && node.dataset.id) { + const rect = node.getBoundingClientRect(); + + if (rect.height <= 0) continue; + if (y < rect.top + rect.height / 2) { + break; + } + } + node = node.nextElementSibling as HTMLDivElement; + } + return node; + }; + + /** + * find the source node + */ + const getSource = (e: DragEvent) => { + const target = e.target as Element; + if (!target || !box.contains(target) || target === box) { + return null; + } + + let node = box.firstElementChild; + while (node) { + if (node.contains(target)) { + return node; + } + node = node.nextElementSibling; + } + + return null; + }; + + const sort = (beforeId: string | number | null | undefined) => { + if (!source) return; + + const sourceId = (source as HTMLDivElement).dataset.id; + const items = this.items!; + const origIndex = items.findIndex(id => id == sourceId); + + let newIndex = beforeId ? items.findIndex(id => id == beforeId) : items.length; + + if (origIndex < 0 || newIndex < 0) return; + if (this.props.onSort) { + if (newIndex > origIndex) { + newIndex -= 1; + } + if (origIndex === newIndex) return; + const item = items.splice(origIndex, 1); + items.splice(newIndex, 0, item[0]); + + this.props.onSort(items); + } + }; + + const dragstart = (e: DragEvent) => { + isDragEnd = false; + source = getSource(e); + if (!source) { + return false; + } + origRef = source.nextElementSibling; + const rect = source.getBoundingClientRect(); + let dragSource = source; + if (this.props.dragImageSourceHandler) { + dragSource = this.props.dragImageSourceHandler(source); + } + if (e.dataTransfer) { + e.dataTransfer.setDragImage(dragSource, e.clientX - rect.left, e.clientY - rect.top); + e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.dropEffect = 'move'; + try { + e.dataTransfer.setData('application/json', {} as any); + } catch (ex) { + // eslint-disable-line + } + } + + setTimeout(() => { + source!.classList.add('lc-dragging'); + }, 0); + return true; + }; + + const placeAt = (beforeRef: Element | null) => { + if (beforeRef) { + if (beforeRef !== source) { + box.insertBefore(source!, beforeRef); + } + } else { + box.appendChild(source!); + } + }; + + const adjust = (e: DragEvent) => { + if (isDragEnd) return; + ref = locate(e); + placeAt(ref); + }; + + let lastDragEvent: DragEvent | null; + const drag = (e: DragEvent) => { + if (!source) return; + e.preventDefault(); + if (lastDragEvent) { + if (lastDragEvent.clientX === e.clientX && lastDragEvent.clientY === e.clientY) { + return; + } + } + lastDragEvent = e; + if (e.dataTransfer) { + e.dataTransfer.effectAllowed = 'move'; + } + adjust(e); + }; + + const dragend = (e: DragEvent) => { + isDragEnd = true; + if (!source) return; + e.preventDefault(); + source.classList.remove('lc-dragging'); + placeAt(origRef); + sort(ref ? (ref as HTMLDivElement).dataset.id : null); + source = null; + ref = null; + origRef = null; + lastDragEvent = null; + }; + + box.addEventListener('dragstart', dragstart); + document.addEventListener('dragover', drag); + document.addEventListener('drag', drag); + document.addEventListener('dragend', dragend); + + this.willDetach = () => { + box.removeEventListener('dragstart', dragstart); + document.removeEventListener('dragover', drag); + document.removeEventListener('drag', drag); + document.removeEventListener('dragend', dragend); + }; + } + + componentWillUnmount() { + if (this.willDetach) { + this.willDetach(); + } + } + + render() { + const { className, itemClassName, children } = this.props; + const items: Array<string | number> = []; + const cards = Children.map(children, child => { + const id = child.key!; + items.push(id); + return ( + <div key={id} data-id={id} className={classNames('lc-sortable-card', itemClassName)}> + {child} + </div> + ); + }); + this.items = items; + + return ( + <div + className={classNames('lc-sortable', className)} + ref={ref => { + this.shell = ref; + }} + > + {cards} + </div> + ); + } +} + +export default Sortable; diff --git a/packages/editor-skeleton/src/components/array-setter/style.less b/packages/editor-skeleton/src/components/array-setter/style.less new file mode 100644 index 000000000..8e0da024b --- /dev/null +++ b/packages/editor-skeleton/src/components/array-setter/style.less @@ -0,0 +1,103 @@ +.lc-setter-list { + [draggable] { + cursor: move; + } + color: var(--color-text); + + .next-btn { + display: inline-flex; + align-items: center; + line-height: 1 !important; + max-width: 100%; + text-overflow: ellipsis; + } + + .lc-setter-list-add { + display: block; + width: 100%; + margin-top: 8px;; + } + + + .lc-setter-list-columns { + display: flex; + > .lc-title { + flex: 1; + justify-content: center; + } + margin-left: 47px; + margin-right: 28px; + margin-bottom: 5px; + } + + .lc-setter-list-scroll-body { + margin: -8px -5px; + padding: 8px 10px; + overflow-y: auto; + max-height: 300px; + } + + .lc-setter-list-card { + border: 1px solid rgba(31,56,88,.2); + background-color: var(--color-block-background-light); + border-radius: 3px; + &:not(:last-child) { + margin-bottom: 5px; + } + + .lc-listitem { + position: relative; + outline: none; + display: flex; + align-items: stretch; + height: 34px; + + .lc-listitem-actions { + margin: 0 3px; + display: inline-flex; + align-items: center; + justify-content: flex-end; + .lc-listitem-action { + text-align: center; + cursor: pointer; + opacity: 0.6; + &:hover { + opacity: 1; + } + } + } + .lc-listitem-body { + flex: 1; + display: flex; + align-items: stretch; + overflow: hidden; + min-width: 0; + text-overflow: ellipsis; + .lc-field { + padding: 0 !important; + display: flex; + align-items: center; + >.lc-field-body { + justify-content: center; + } + } + > * { + width: 100%; + } + .next-btn { + display: block; + width: 100%; + } + } + .lc-listitem-handler { + margin-left: 2px; + display: inline-flex; + align-items: center; + .next-icon-ellipsis { + transform: rotate(90deg); + } + opacity: 0.6; + } + } + } +} diff --git a/packages/editor-skeleton/src/components/field/fields.tsx b/packages/editor-skeleton/src/components/field/fields.tsx new file mode 100644 index 000000000..59d67df2f --- /dev/null +++ b/packages/editor-skeleton/src/components/field/fields.tsx @@ -0,0 +1,185 @@ +import { Component } from 'react'; +import classNames from 'classnames'; +import { Icon } from '@alifd/next'; +import { Title } from '@ali/lowcode-editor-core'; +import { TitleContent } from '@ali/lowcode-types'; +import { PopupPipe, PopupContext } from '../popup'; +import './index.less'; + +export interface FieldProps { + className?: string; + title?: TitleContent | null; + defaultDisplay?: 'accordion' | 'inline' | 'block'; + collapsed?: boolean; + onExpandChange?: (expandState: boolean) => void; +} + +export class Field extends Component<FieldProps> { + state = { + collapsed: this.props.collapsed, + display: this.props.defaultDisplay || 'inline', + }; + + private toggleExpand = () => { + const { onExpandChange } = this.props; + const collapsed = !this.state.collapsed; + this.setState({ + collapsed, + }); + onExpandChange && onExpandChange(!collapsed); + }; + private body: HTMLDivElement | null = null; + private dispose?: () => void; + private deployBlockTesting() { + if (this.dispose) { + this.dispose(); + } + const body = this.body; + if (!body) { + return; + } + const check = () => { + const setter = body.firstElementChild; + if (setter && setter.classList.contains('lc-block-setter')) { + this.setState({ + display: 'block', + }); + } else { + this.setState({ + display: 'inline', + }); + } + }; + const observer = new MutationObserver(check); + check(); + observer.observe(body, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ['class'], + }); + this.dispose = () => observer.disconnect(); + } + componentDidMount() { + const { defaultDisplay } = this.props; + if (!defaultDisplay || defaultDisplay === 'inline') { + this.deployBlockTesting(); + } + } + componentWillUnmount() { + if (this.dispose) { + this.dispose(); + } + } + + render() { + const { className, children, title } = this.props; + const { display, collapsed } = this.state; + const isAccordion = display === 'accordion'; + return ( + <div + className={classNames(`lc-field lc-${display}-field`, className, { + 'lc-field-is-collapsed': isAccordion && collapsed, + })} + > + <div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}> + <div className="lc-field-title"> + <Title title={title || ''} /> + </div> + {isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />} + </div> + <div key="body" ref={(shell) => (this.body = shell)} className="lc-field-body"> + {children} + </div> + </div> + ); + } +} + +export interface PopupFieldProps extends FieldProps { + width?: number; +} + +export class PopupField extends Component<PopupFieldProps> { + static contextType = PopupContext; + private pipe: any; + + static defaultProps: PopupFieldProps = { + width: 300, + }; + + render() { + const { className, children, title, width } = this.props; + if (!this.pipe) { + this.pipe = (this.context as PopupPipe).create({ width }); + } + + const titleElement = title && ( + <div className="lc-field-title"> + <Title title={title} /> + </div> + ); + + this.pipe.send(<div className="lc-field-body">{children}</div>, titleElement); + + return ( + <div className={classNames('lc-field lc-popup-field', className)}> + {title && ( + <div + className="lc-field-head" + onClick={(e) => { + this.pipe.show((e as any).target); + }} + > + <div className="lc-field-title"> + <Title title={title} /> + </div> + <Icon className="lc-field-icon" type="arrow-left" size="xs" /> + </div> + )} + </div> + ); + } +} + +export interface EntryFieldProps extends FieldProps { + stageName?: string; +} + +export class EntryField extends Component<EntryFieldProps> { + render() { + const { stageName, title, className } = this.props; + const classNameList = classNames('engine-setting-field', 'engine-entry-field', className); + const fieldProps: any = {}; + + if (stageName) { + // 为 stage 切换奠定基础 + fieldProps['data-stage-target'] = stageName; + } + + const innerElements = [ + <span className="engine-field-title" key="field-title"> + {title} + </span>, + // renderTip(tip, { propName }), + // <Icons name="arrow" className="engine-field-arrow" size="12px" key="engine-field-arrow-icon" />, + ]; + + return ( + <div className={classNameList} {...fieldProps}> + {innerElements} + </div> + ); + } +} + +export class PlainField extends Component<FieldProps> { + render() { + const { className, children } = this.props; + return ( + <div className={classNames(`lc-field lc-plain-field`, className)}> + <div className="lc-field-body">{children}</div> + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/components/field/index.less b/packages/editor-skeleton/src/components/field/index.less new file mode 100644 index 000000000..5fecb74d9 --- /dev/null +++ b/packages/editor-skeleton/src/components/field/index.less @@ -0,0 +1,154 @@ +@import '../variables.less'; + +@x-gap: 10px; +@y-gap: 8px; + +.lc-field { + // head + .lc-field-head { + display: flex; + align-items: center; + justify-content: space-between; + + .lc-field-title { + display: flex; + align-items: center; + } + .lc-field-icon { + margin-right: @x-gap; + transform-origin: center; + transition: transform 0.1s; + } + } + + &.lc-plain-field { + // for top-level style + padding: 8px 10px; + > .lc-field-body { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + } + } + + &.lc-inline-field { + display: flex; + align-items: center; + // for top-level style + padding: 8px 10px; + + > .lc-field-head { + width: 70px; + margin-right: 1px; + .lc-title-label { + width: 70px; + word-break: break-all; + } + } + > .lc-field-body { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + } + } + + &.lc-block-field, &.lc-accordion-field { + display: block; + &:not(:first-child) { + border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + } + > .lc-field-head { + padding-left: @x-gap; + height: 32px; + display: flex; + align-items: center; + font-weight: 500; + background: var(--color-block-background-shallow, rgba(31,56,88,.06)); + border-bottom: 1px solid var(--color-line-normal, @dark-alpha-2); + color: var(--color-title, @white-alpha-2); + user-select: none; + } + + > .lc-field-body { + padding: @y-gap @x-gap/2; + } + + + .lc-inline-field { + border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + } + } + + .lc-setter-actions { + display: flex; + align-items: center; + } + + &.lc-block-field { + position: relative; + >.lc-field-body>.lc-block-setter>.lc-setter-actions { + position: absolute; + right: 10px; + top: 0; + height: 32px; + display: flex; + align-items: center; + } + } + + &.lc-accordion-field { + // collapsed + &.lc-field-is-collapsed { + > .lc-field-head .lc-field-icon { + transform: rotate(180deg); + } + > .lc-field-body { + display: none; + } + } + + // 邻近的保持上下距离 + + .lc-field { + margin-top: @y-gap; + } + } + + // 2rd level reset + .lc-field-body { + .lc-inline-field { + padding: @y-gap @x-gap/2 0 @x-gap/2; + &:first-child { + padding-top: 0; + } + + .lc-accordion-field, +.lc-block-field { + margin-top: @y-gap; + } + } + + .lc-field { + border-top: none !important; + } + + .lc-accordion-field, .lc-block-field { + > .lc-field-head { + padding-left: @x-gap/2; + background: var(--color-block-background-light); + border-bottom-color: var(--color-line-light); + > .lc-field-icon { + margin-right: @x-gap/2; + } + } + } + + // 3rd level field title width should short + .lc-field-body .lc-inline-field { + > .lc-field-head { + width: 50px; + .lc-title-label { + width: 50px; + } + } + } + } +} diff --git a/packages/editor-skeleton/src/components/field/index.ts b/packages/editor-skeleton/src/components/field/index.ts new file mode 100644 index 000000000..b0f3c497d --- /dev/null +++ b/packages/editor-skeleton/src/components/field/index.ts @@ -0,0 +1,28 @@ +import { ReactNode, createElement } from 'react'; +import { TitleContent } from '@ali/lowcode-types'; +import './index.less'; +import { Field, PopupField, EntryField, PlainField } from './fields'; + +export interface FieldProps { + className?: string; + title?: TitleContent | null; + display?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry'; + collapsed?: boolean; + onExpandChange?: (collapsed: boolean) => void; + [extra: string]: any; +} + +export function createField(props: FieldProps, children: ReactNode, type?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry') { + if (type === 'popup') { + return createElement(PopupField, props, children); + } + if (type === 'entry') { + return createElement(EntryField, props, children); + } + if (type === 'plain' || !props.title) { + return createElement(PlainField, props, children); + } + return createElement(Field, { ...props, defaultDisplay: type }, children); +} + +export { Field, PopupField, EntryField, PlainField }; diff --git a/packages/editor-skeleton/src/components/mixed-setter/index.tsx b/packages/editor-skeleton/src/components/mixed-setter/index.tsx new file mode 100644 index 000000000..68530e9f8 --- /dev/null +++ b/packages/editor-skeleton/src/components/mixed-setter/index.tsx @@ -0,0 +1,262 @@ +import React, { Component, isValidElement } from 'react'; +import classNames from 'classnames'; +import { Dropdown, Menu } from '@alifd/next'; +import { + SetterConfig, + CustomView, + DynamicProps, + DynamicSetter, + TitleContent, + isSetterConfig, + isDynamicSetter, + isI18nData, +} from '@ali/lowcode-types'; +import { + getSetter, + getSettersMap, + computed, + obx, + Title, + createSetterContent, + observer, + shallowIntl, + Tip, +} from '@ali/lowcode-editor-core'; + +import { IconConvert } from '../../icons/convert'; + +import './style.less'; +import { SettingField } from '@ali/lowcode-designer'; + +export interface SetterItem { + name: string; + title: TitleContent; + setter: string | DynamicSetter | CustomView; + props?: object | DynamicProps; + condition?: (field: SettingField) => boolean; + initialValue?: any | ((field: SettingField) => any); + list: boolean; +} + +function nomalizeSetters(setters?: Array<string | SetterConfig | CustomView | DynamicSetter>): SetterItem[] { + if (!setters) { + const normalized: SetterItem[] = []; + getSettersMap().forEach((setter, name) => { + if (name === 'MixedSetter') { + return; + } + normalized.push({ + name, + title: setter.title || name, + setter: name, + condition: setter.condition, + initialValue: setter.initialValue, + list: setter.recommend || false, + }); + }); + return normalized; + } + const names: string[] = []; + function generateName(n: string) { + let idx = 1; + let got = n; + while (names.indexOf(got) > -1) { + got = `${n}:${idx++}`; + } + names.push(got); + return got; + } + return setters.map((setter) => { + const config: any = { + setter, + list: true, + }; + if (isSetterConfig(setter)) { + config.setter = setter.componentName; + config.props = setter.props; + config.condition = setter.condition; + config.initialValue = setter.initialValue; + config.title = setter.title; + } + if (typeof config.setter === 'string') { + config.name = config.setter; + names.push(config.name); + const info = getSetter(config.setter); + if (!config.title) { + config.title = info?.title || config.setter; + } + if (!config.condition) { + config.condition = info?.condition; + } + if (!config.initialValue) { + config.initialValue = info?.initialValue; + } + } else { + config.name = generateName((config.setter as any).displayName || (config.setter as any).name || 'CustomSetter'); + if (!config.title) { + config.title = config.name; + } + } + return config; + }); +} + +@observer +export default class MixedSetter extends Component<{ + field: SettingField; + setters?: Array<string | SetterConfig | CustomView | DynamicSetter>; + onSetterChange?: (field: SettingField, name: string) => void; + onChange?: (val: any) => void; + value?: any; + className?: string; +}> { + private setters = nomalizeSetters(this.props.setters); + @obx.ref private used?: string; + @computed private getCurrentSetter() { + const { field } = this.props; + let firstMatched: SetterItem | undefined; + for (const setter of this.setters) { + const matched = !setter.condition || setter.condition(field); + if (matched) { + if (setter.name === this.used) { + return setter; + } + if (!firstMatched) { + firstMatched = setter; + } + } + } + return firstMatched; + } + + private useSetter = (name: string) => { + if (name === this.used) { + return; + } + const { field, onChange } = this.props; + const setter = this.setters.find((item) => item.name === name); + this.used = name; + if (setter) { + let newValue: any = setter.initialValue; + if (newValue && typeof newValue === 'function') { + newValue = newValue(field); + } + onChange && onChange(newValue); + } + }; + + private shell: HTMLDivElement | null = null; + private checkIsBlockField() { + if (this.shell) { + const setter = this.shell.firstElementChild; + if (setter && setter.classList.contains('lc-block-setter')) { + this.shell.classList.add('lc-block-setter'); + } else { + this.shell.classList.remove('lc-block-setter'); + } + } + } + componentDidUpdate() { + this.checkIsBlockField(); + } + componentDidMount() { + this.checkIsBlockField(); + } + + render() { + const { className, field, setters, onSetterChange, ...restProps } = this.props; + + const currentSetter = this.getCurrentSetter(); + const isTwoType = this.setters.length < 3; + + let setterContent: any; + const triggerTitle: any = { + tip: { + type: 'i18n', + 'zh-CN': '切换格式', + 'en-US': 'Switch Format', + }, + icon: <IconConvert size={24} />, + }; + if (currentSetter) { + const { setter, title, props } = currentSetter; + let setterProps: any = {}; + let setterType: any; + if (isDynamicSetter(setter)) { + setterType = setter.call(field, field); + } else { + setterType = setter; + } + if (props) { + setterProps = props; + if (typeof setterProps === 'function') { + setterProps = setterProps(field); + } + } + + setterContent = createSetterContent(setterType, { + ...shallowIntl(setterProps), + field, + ...restProps, + }); + if (title) { + if (typeof title !== 'object' || isI18nData(title) || isValidElement(title)) { + triggerTitle.tip = title; + } else { + triggerTitle.tip = title.tip || title.label; + } + } + } else { + // 未匹配的 null 值,显示 NullValue 空值 + // 未匹配的 其它 值,显示 InvalidValue 非法值 + if (restProps.value == null) { + setterContent = <span>NullValue</span>; + } else { + setterContent = <span>InvalidValue</span>; + } + } + const usedName = currentSetter?.name || this.used; + let moreBtnNode = ( + <Title + title={triggerTitle} + className="lc-switch-trigger" + onClick={ + isTwoType + ? () => { + if (this.setters[0]?.name === usedName) { + this.useSetter(this.setters[1]?.name); + } else { + this.useSetter(this.setters[0]?.name); + } + } + : undefined + } + /> + ); + if (!isTwoType) { + moreBtnNode = ( + <Dropdown trigger={moreBtnNode} triggerType="click" align="tr br"> + <Menu selectMode="single" hasSelectedIcon={true} selectedKeys={usedName} onItemClick={this.useSetter}> + {this.setters + .filter((setter) => setter.list || setter.name === usedName) + .map((setter) => { + return ( + <Menu.Item key={setter.name}> + <Title title={setter.title} /> + </Menu.Item> + ); + })} + </Menu> + </Dropdown> + ); + } + + return ( + <div ref={(shell) => (this.shell = shell)} className={classNames('lc-setter-mixed', className)}> + {setterContent} + + <div className="lc-setter-actions">{moreBtnNode}</div> + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/components/mixed-setter/style.less b/packages/editor-skeleton/src/components/mixed-setter/style.less new file mode 100644 index 000000000..6efebb28c --- /dev/null +++ b/packages/editor-skeleton/src/components/mixed-setter/style.less @@ -0,0 +1,30 @@ +.lc-setter-mixed { + flex: 1; + min-width: 0; + margin-right: 26px; + display: block; + position: relative; + >.lc-setter-actions { + position: absolute; + right: -2px; + top: 50%; + transform: translate(100%, -50%); + .lc-switch-trigger { + cursor: pointer; + opacity: 0.6; + &:hover { + opacity: 1; + } + } + } + .next-input,.next-date-picker { + width: 100%; + } + &.lc-block-setter { + position: static; + margin-right: 0; + >.lc-setter-actions { + transform: none; + } + } +} diff --git a/packages/editor-skeleton/src/components/object-setter/index.tsx b/packages/editor-skeleton/src/components/object-setter/index.tsx new file mode 100644 index 000000000..0d8d5e950 --- /dev/null +++ b/packages/editor-skeleton/src/components/object-setter/index.tsx @@ -0,0 +1,181 @@ +import { Component, Fragment } from 'react'; +import { Icon, Button } from '@alifd/next'; +import { SetterType, FieldConfig } from '@ali/lowcode-types'; +import { createSettingFieldView } from '../settings/settings-pane'; +import { PopupContext, PopupPipe } from '../popup'; +import { SettingField } from '@ali/lowcode-designer'; +import './style.less'; +import { Title } from '@ali/lowcode-editor-core'; + +export default class ObjectSetter extends Component<{ + field: SettingField; + descriptor?: string | ((rowField: SettingField) => string); + config: ObjectSetterConfig; + mode?: 'popup' | 'form'; + // 1: in tablerow 2: in listrow 3: in column-cell + forceInline?: number; +}> { + render() { + const { mode, forceInline = 0, ...props } = this.props; + if (forceInline || mode === 'popup') { + if (forceInline > 2 || mode === 'popup') { + // popup + return <RowSetter {...props} primaryButton={forceInline ? false : true} />; + } else { + return <RowSetter columns={forceInline > 1 ? 2 : 4} {...props} />; + } + } else { + // form + return <FormSetter {...props} />; + } + } +} + +interface ObjectSetterConfig { + items?: FieldConfig[]; + extraSetter?: SetterType; +} + +interface RowSetterProps { + field: SettingField; + descriptor?: string | ((rowField: SettingField) => string); + config: ObjectSetterConfig; + columns?: number; + primaryButton?: boolean; +} + +class RowSetter extends Component<RowSetterProps> { + static contextType = PopupContext; + + state: any = { + descriptor: '', + }; + + private items?: SettingField[]; + constructor(props: RowSetterProps) { + super(props); + const { config, descriptor, field, columns } = props; + const items: SettingField[] = []; + if (columns && config.items) { + const l = Math.min(config.items.length, columns); + for (let i = 0; i < l; i++) { + const conf = config.items[i]; + if (conf.isRequired || conf.important || (conf.setter as any)?.isRequired) { + const item = field.createField({ + ...conf, + // in column-cell + forceInline: 3, + }); + items.push(item); + } + } + } + + if (items.length > 0) { + this.items = items; + } + + let firstRun: boolean = true; + field.onEffect(() => { + let state: any = {}; + if (descriptor) { + if (typeof descriptor === 'function') { + state.descriptor = descriptor(field); + } else { + state.descriptor = field.getPropValue(descriptor); + } + } else { + state.descriptor = field.title; + } + + if (firstRun) { + firstRun = false; + this.state = state; + } else { + this.setState(state); + } + }); + } + + shouldComponentUpdate(_: any, nextState: any) { + if (this.state.decriptor !== nextState.decriptor) { + return true; + } + return false; + } + + private pipe: any; + render() { + const items = this.items; + const { field, primaryButton, config } = this.props; + + if (!this.pipe) { + this.pipe = (this.context as PopupPipe).create({ width: 320 }); + } + + const title = ( + <Fragment> + 编辑: + <Title title={this.state.descriptor} /> + </Fragment> + ); + + this.pipe.send(<FormSetter key={field.id} field={field} config={config} />, title); + + if (items) { + return ( + <div className="lc-setter-object-row"> + <div + className="lc-setter-object-row-edit" + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon size="small" type="edit" /> + </div> + <div className="lc-setter-object-row-body">{items.map((item) => createSettingFieldView(item, field))}</div> + </div> + ); + } + + return ( + <Button + type={primaryButton === false ? 'normal' : 'primary'} + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon type="edit" /> + {title} + </Button> + ); + } +} + +interface FormSetterProps { + field: SettingField; + config: ObjectSetterConfig; +} +class FormSetter extends Component<FormSetterProps> { + private items: SettingField[]; + constructor(props: RowSetterProps) { + super(props); + const { config, field } = props; + this.items = (config.items || []).map((conf) => field.createField(conf)); + + // TODO: extraConfig for custom fields + } + + shouldComponentUpdate() { + return false; + } + + render() { + const { field } = this.props; + return ( + <div className="lc-setter-object lc-block-setter"> + {this.items.map((item, index) => createSettingFieldView(item, field, index))} + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/components/object-setter/style.less b/packages/editor-skeleton/src/components/object-setter/style.less new file mode 100644 index 000000000..6d6064df1 --- /dev/null +++ b/packages/editor-skeleton/src/components/object-setter/style.less @@ -0,0 +1,31 @@ +.lc-setter-object-row { + display: flex; + align-items: stretch; + width: 100%; + .lc-setter-object-row-edit { + width: 20px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + } + .lc-setter-object-row-body { + display: flex; + flex: 1; + min-width: 0; + align-items: center; + .lc-field { + padding: 0 !important; + .lc-field-body { + padding: 0 !important; margin: 0 !important; + } + } + > * { + flex: 1; + flex-shrink: 1; + margin-left: 2px; + min-width: 0; + overflow: hidden; + } + } +} diff --git a/packages/editor-skeleton/src/components/popup/index.tsx b/packages/editor-skeleton/src/components/popup/index.tsx new file mode 100644 index 000000000..9018531cb --- /dev/null +++ b/packages/editor-skeleton/src/components/popup/index.tsx @@ -0,0 +1,150 @@ +import { createContext, ReactNode, Component, PureComponent } from 'react'; +import { EventEmitter } from 'events'; +import { Balloon } from '@alifd/next'; +import { uniqueId } from '@ali/lowcode-utils'; +import './style.less'; + +export const PopupContext = createContext<PopupPipe>({} as any); + +export class PopupPipe { + private emitter = new EventEmitter(); + private currentId?: string; + + create(props?: object): { send: (content: ReactNode, title: ReactNode) => void; show: (target: Element) => void } { + let sendContent: ReactNode = null; + let sendTitle: ReactNode = null; + const id = uniqueId('popup'); + return { + send: (content: ReactNode, title: ReactNode) => { + sendContent = content; + sendTitle = title; + if (this.currentId === id) { + this.popup({ + ...props, + content, + title, + }); + } + }, + show: (target: Element, actionKey?: string) => { + this.currentId = id; + this.popup( + { + ...props, + actionKey, + content: sendContent, + title: sendTitle, + }, + target, + ); + }, + }; + } + + private popup(props: object, target?: Element) { + Promise.resolve().then(() => { + this.emitter.emit('popupchange', props, target); + }); + } + + onPopupChange(fn: (props: object, target?: Element) => void): () => void { + this.emitter.on('popupchange', fn); + return () => { + this.emitter.removeListener('popupchange', fn); + }; + } + + purge() { + this.emitter.removeAllListeners(); + } +} + +export default class PopupService extends Component<{ actionKey?: string; safeId?: string }> { + private popupPipe = new PopupPipe(); + + componentWillUnmount() { + this.popupPipe.purge(); + } + + render() { + const { children, actionKey, safeId } = this.props; + return ( + <PopupContext.Provider value={this.popupPipe}> + {children} + <PopupContent key={'pop' + actionKey} safeId={safeId} /> + </PopupContext.Provider> + ); + } +} + +export class PopupContent extends PureComponent<{ safeId?: string }> { + static contextType = PopupContext; + state: any = { + visible: false, + pos: {}, + }; + + private dispose = (this.context as PopupPipe).onPopupChange((props, target) => { + const state: any = { + ...props, + visible: true, + }; + if (target) { + const rect = target.getBoundingClientRect(); + state.pos = { + top: rect.top, + height: rect.height, + }; + // todo: compute the align method + } + this.setState(state); + }); + + componentWillUnmount() { + this.dispose(); + } + + render() { + const { content, visible, width, title, pos, actionKey } = this.state; + if (!visible) { + return null; + } + let avoidLaterHidden = true; + setTimeout(() => { + avoidLaterHidden = false; + }, 10); + + const id = uniqueId('ball'); + + return ( + <Balloon + className="lc-ballon" + align="l" + id={this.props.safeId} + safeNode={id} + visible={visible} + style={{ width }} + onVisibleChange={(visible) => { + if (avoidLaterHidden) { + return; + } + if (!visible) { + this.setState({ visible: false }); + } + }} + trigger={<div className="lc-popup-placeholder" style={pos} />} + triggerType="click" + animation={false} + // needAdjust + shouldUpdatePosition + > + <div className="lc-ballon-title">{title}</div> + <div className="lc-ballon-content"> + <PopupService actionKey={actionKey} safeId={id}> + {content} + </PopupService> + </div> + </Balloon> + ); + } +} diff --git a/packages/editor-skeleton/src/components/popup/style.less b/packages/editor-skeleton/src/components/popup/style.less new file mode 100644 index 000000000..b115fd371 --- /dev/null +++ b/packages/editor-skeleton/src/components/popup/style.less @@ -0,0 +1,22 @@ +.lc-popup-placeholder { + position: fixed; + width: 100%; + pointer-events: none; +} + +.lc-ballon { + padding: 10px; + max-width: 640px; + width: 640px; + .lc-ballon-title { + font-size: 14px; + } + .lc-ballon-content { + margin-top: 10px; + // width: 300px; + } + .next-balloon-close { + top: 4px; + right: 4px; + } +} diff --git a/packages/editor-skeleton/src/components/settings/index.ts b/packages/editor-skeleton/src/components/settings/index.ts new file mode 100644 index 000000000..be0ed6e8d --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/index.ts @@ -0,0 +1,7 @@ +export * from './settings-pane'; +import './transducers/register'; +import './register'; +import './style.less'; +import SettingsMainView from './settings-primary-view'; + +export default SettingsMainView; diff --git a/packages/editor-skeleton/src/components/settings/main.ts b/packages/editor-skeleton/src/components/settings/main.ts new file mode 100644 index 000000000..8296ad7ef --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/main.ts @@ -0,0 +1,84 @@ +import { EventEmitter } from 'events'; +import { Node, Designer, Selection, SettingTopEntry } from '@ali/lowcode-designer'; +import { Editor, obx, computed } from '@ali/lowcode-editor-core'; + +function generateSessionId(nodes: Node[]) { + return nodes + .map((node) => node.id) + .sort() + .join(','); +} + +export class SettingsMain { + private emitter = new EventEmitter(); + private _sessionId = ''; + @obx.ref private _settings?: SettingTopEntry; + + @computed get length(): number | undefined { + return this._settings?.nodes.length; + } + + @computed get componentMeta() { + return this._settings?.componentMeta; + } + + get settings() { + return this._settings; + } + + private disposeListener: () => void; + + private designer?: Designer; + + constructor(readonly editor: Editor) { + this.init(); + } + + private async init() { + const setupSelection = (selection?: Selection) => { + if (selection) { + this.setup(selection.getNodes()); + } else { + this.setup([]); + } + }; + this.editor.on('designer.selection.change', setupSelection); + this.disposeListener = () => { + this.editor.removeListener('designer.selection.change', setupSelection); + }; + const designer = await this.editor.onceGot(Designer); + this.designer = designer; + setupSelection(designer.currentSelection); + } + + private setup(nodes: Node[]) { + // check nodes change + const sessionId = generateSessionId(nodes); + if (sessionId === this._sessionId) { + return; + } + this._sessionId = sessionId; + if (nodes.length < 1) { + this._settings = undefined; + return; + } + + if (!this.designer) { + this.designer = nodes[0].document.designer; + } + + this._settings = this.designer.createSettingEntry(this.editor, nodes); + } + + onceOutlineVisible(fn: () => void): () => void { + this.emitter.on('outline-visible', fn); + return () => { + this.emitter.removeListener('outline-visible', fn); + }; + } + + purge() { + this.disposeListener(); + this.emitter.removeAllListeners(); + } +} diff --git a/packages/editor-skeleton/src/components/settings/package.json b/packages/editor-skeleton/src/components/settings/package.json new file mode 100644 index 000000000..2a0fab24e --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/package.json @@ -0,0 +1,49 @@ +{ + "name": "@ali/lowcode-plugin-settings-pane", + "version": "0.8.10", + "description": "Settings pane for Ali lowCode engine", + "files": [ + "es", + "lib" + ], + "main": "lib/index.js", + "module": "es/index.js", + "scripts": { + "build": "build-scripts build --skip-demo", + "test": "ava", + "test:snapshot": "ava --update-snapshots" + }, + "dependencies": { + "@ali/lowcode-designer": "^0.9.2", + "@ali/lowcode-editor-core": "^0.8.5", + "@ali/lowcode-globals": "^0.9.2", + "@ali/lowcode-plugin-outline-pane": "^0.8.8", + "@ali/ve-stage-box": "^4.0.0", + "@alifd/next": "^1.19.16", + "classnames": "^2.2.6", + "react": "^16" + }, + "devDependencies": { + "@alib/build-scripts": "^0.1.18", + "@types/classnames": "^2.2.7", + "@types/node": "^13.7.1", + "@types/react": "^16", + "build-plugin-component": "^0.2.10", + "build-plugin-fusion": "^0.1.1", + "build-plugin-moment-locales": "^0.1.0" + }, + "ava": { + "compileEnhancements": false, + "snapshotDir": "test/fixtures/__snapshots__", + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + }, + "license": "MIT", + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + } +} diff --git a/packages/editor-skeleton/src/components/settings/register.ts b/packages/editor-skeleton/src/components/settings/register.ts new file mode 100644 index 000000000..1ff61b101 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/register.ts @@ -0,0 +1,30 @@ +import { registerSetter } from '@ali/lowcode-editor-core'; +import ArraySetter from '../array-setter'; +import ObjectSetter from '../object-setter'; +import MixedSetter from '../mixed-setter'; +import { isPlainObject } from '@ali/lowcode-utils'; + +registerSetter('ArraySetter', { + component: ArraySetter, + defaultProps: {}, + title: 'ArraySetter', // TODO + condition: (field: any) => { + const v = field.getValue(); + return v == null || Array.isArray(v); + }, + initialValue: [], + recommend: true, +}); +registerSetter('ObjectSetter', { + component: ObjectSetter, + // todo: defaultProps + defaultProps: {}, + title: 'ObjectSetter', // TODO + condition: (field: any) => { + const v = field.getValue(); + return v == null || isPlainObject(v); + }, + initialValue: {}, + recommend: true, +}); +registerSetter('MixedSetter', MixedSetter); diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx new file mode 100644 index 000000000..9b6e377a6 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -0,0 +1,152 @@ +import { Component } from 'react'; +import { intl, shallowIntl, createSetterContent, observer } from '@ali/lowcode-editor-core'; +import { createContent } from '@ali/lowcode-utils'; +import { Field, createField } from '../field'; +import PopupService from '../popup'; +import { SettingField, isSettingField, SettingTopEntry, SettingEntry } from '@ali/lowcode-designer'; +import { isSetterConfig, CustomView } from '@ali/lowcode-types'; + +@observer +class SettingFieldView extends Component<{ field: SettingField }> { + render() { + const { field } = this.props; + const { extraProps } = field; + const { condition, defaultValue } = extraProps; + const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; + if (!visible) { + return null; + } + const { setter } = field; + + let setterProps: any = {}; + let setterType: any; + if (Array.isArray(setter)) { + setterType = 'MixedSetter'; + setterProps = { + setters: setter, + }; + } else if (isSetterConfig(setter)) { + setterType = setter.componentName; + if (setter.props) { + setterProps = setter.props; + if (typeof setterProps === 'function') { + setterProps = setterProps(field); + } + } + } else if (setter) { + setterType = setter; + } + let value = null; + if (field.type === 'field') { + if (defaultValue != null && !('defaultValue' in setterProps)) { + setterProps.defaultValue = defaultValue; + } + if (field.valueState > 0) { + value = field.getValue(); + } else { + setterProps.multiValue = true; + if (!('placeholder' in setterProps)) { + // FIXME! move to locale file + setterProps.placeholder = intl({ + type: 'i18n', + 'zh-CN': '多种值', + 'en-US': 'Multiple Value', + }); + } + } + } + + // todo: error handling + + return createField( + { + title: field.title, + collapsed: !field.expanded, + onExpandChange: (expandState) => field.setExpanded(expandState), + }, + createSetterContent(setterType, { + ...shallowIntl(setterProps), + forceInline: extraProps.forceInline, + key: field.id, + // === injection + prop: field, // for compatible vision + field, + // === IO + value, // reaction point + onChange: (value: any) => { + this.setState({ + value, + }); + field.setValue(value); + }, + }), + extraProps.forceInline ? 'plain' : extraProps.display, + ); + } +} + +@observer +class SettingGroupView extends Component<{ field: SettingField }> { + shouldComponentUpdate() { + return false; + } + + render() { + const { field } = this.props; + const { extraProps } = field; + const { condition } = extraProps; + const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; + + if (!visible) { + return null; + } + + // todo: split collapsed state | field.items for optimize + return ( + <Field + defaultDisplay="accordion" + title={field.title} + collapsed={!field.expanded} + onExpandChange={(expandState) => { + field.setExpanded(expandState); + }} + > + {field.items.map((item, index) => createSettingFieldView(item, field, index))} + </Field> + ); + } +} + +export function createSettingFieldView(item: SettingField | CustomView, field: SettingEntry, index?: number) { + if (isSettingField(item)) { + if (item.isGroup) { + return <SettingGroupView field={item} key={item.id} />; + } else { + return <SettingFieldView field={item} key={item.id} />; + } + } else { + return createContent(item, { key: index, field }); + } +} + +@observer +export class SettingsPane extends Component<{ target: SettingTopEntry | SettingField }> { + shouldComponentUpdate() { + return false; + } + + render() { + const { target } = this.props; + const items = target.items; + return ( + <div className="lc-settings-pane"> + {/* todo: add head for single use */} + <PopupService> + <div className="lc-settings-content"> + {items.map((item, index) => createSettingFieldView(item, target, index))} + </div> + </PopupService> + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-view.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-view.tsx new file mode 100644 index 000000000..7a4c49815 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/settings-primary-view.tsx @@ -0,0 +1,121 @@ +import React, { Component } from 'react'; +import { Tab, Breadcrumb } from '@alifd/next'; +import { Title, observer, Editor } from '@ali/lowcode-editor-core'; +import { Node, isSettingField, SettingField } from '@ali/lowcode-designer'; +import { SettingsMain } from './main'; +import { SettingsPane } from './settings-pane'; +import { createIcon } from '@ali/lowcode-utils'; + +@observer +export default class SettingsMainView extends Component<{ editor: Editor }> { + private main = new SettingsMain(this.props.editor); + + shouldComponentUpdate() { + return false; + } + + componentWillUnmount() { + this.main.purge(); + } + + renderBreadcrumb() { + const { settings } = this.main; + if (!settings) { + return null; + } + if (settings.isMultiple) { + return ( + <div className="lc-settings-navigator"> + {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} + <Title title={settings.componentMeta!.title} /> + <span>x {settings.nodes.length}</span> + </div> + ); + } + + let node: Node | null = settings.first; + const items = []; + let l = 3; + while (l-- > 0 && node) { + const props = + l === 2 + ? {} + : { + onMouseOver: hoverNode.bind(null, node, true), + onMouseOut: hoverNode.bind(null, node, false), + onClick: selectNode.bind(null, node), + }; + items.unshift(<Breadcrumb.Item {...props} key={node.id}><Title title={node.title} /></Breadcrumb.Item>); + node = node.parent; + } + + return ( + <div className="lc-settings-navigator"> + {createIcon(this.main.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} + <Breadcrumb className="lc-settings-node-breadcrumb">{items}</Breadcrumb> + </div> + ); + } + + render() { + const { settings } = this.main; + if (!settings) { + // 未选中节点,提示选中 或者 显示根节点设置 + return ( + <div className="lc-settings-main"> + <div className="lc-settings-notice"> + <p>请在左侧画布选中节点</p> + </div> + </div> + ); + } + + if (!settings.isSameComponent) { + // todo: future support 获取设置项交集编辑 + return ( + <div className="lc-settings-main"> + <div className="lc-settings-notice"> + <p>请选中同一类型节点编辑</p> + </div> + </div> + ); + } + + const { items } = settings; + if (items.length > 5 || items.some(item => !isSettingField(item) || !item.isGroup)) { + return ( + <div className="lc-settings-main"> + {this.renderBreadcrumb()} + <div className="lc-settings-body"> + <SettingsPane target={settings} /> + </div> + </div> + ); + } + + return ( + <div className="lc-settings-main"> + <Tab + navClassName="lc-settings-tabs" + animation={false} + excessMode="dropdown" + contentClassName="lc-settings-tabs-content" + extra={this.renderBreadcrumb()} + > + {(items as SettingField[]).map(field => ( + <Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}> + <SettingsPane target={field} key={field.id} /> + </Tab.Item> + ))} + </Tab> + </div> + ); + } +} + +function hoverNode(node: Node, flag: boolean) { + node.hover(flag); +} +function selectNode(node: Node) { + node.select(); +} diff --git a/packages/editor-skeleton/src/components/settings/style.less b/packages/editor-skeleton/src/components/settings/style.less new file mode 100644 index 000000000..9b2c2b403 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/style.less @@ -0,0 +1,124 @@ +.lc-settings-main { + position: relative; + height: 100%; + overflow: hidden; + + .lc-settings-notice { + text-align: center; + font-size: 12px; + font-family: PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica,Arial,sans-serif; + color: var(--color-text ,rgba(0,0,0,.6)); + padding: 50px 15px 0; + } + + .lc-settings-navigator { + height: 30px; + display: flex; + align-items: center; + padding-left: 5px; + border-bottom: 1px solid var(--color-line-normal); + .lc-settings-navigator-icon { + width: 16px; + height: 16px; + * { + fill: var(--color-icon-normal, rgba(31, 56, 88, 0.4)); + } + } + .lc-settings-node-breadcrumb { + margin-left: 5px; + .next-breadcrumb { + display: inline-flex; + align-items: stretch; + height: 24px; + } + .next-breadcrumb-item { + display: inline-flex; + align-items: center; + cursor: default; + &:not(:last-child):hover { + cursor: pointer; + } + .next-breadcrumb-text { + font-size: 12px; + } + } + } + } + + .lc-settings-body { + position: absolute; + top: 30px; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + } + + // ====== reset fusion-tabs ===== + .lc-settings-tabs { + position: relative; + overflow: visible; + > .next-tabs-nav-extra { + position: absolute !important; + top: 40px !important; + left: 0 !important; + height: 30px; + right: 0; + transform: none !important; + + } + .next-tabs-nav-container { + .next-tabs-nav { + display: flex; + .next-tabs-tab.lc-settings-tab-item { + flex: 1; + min-width: 0; + outline: none; + .next-tabs-tab-inner { + text-align: center; + padding: 12px 0; + } + } + } + } + } + + .lc-settings-tabs-content { + position: absolute; + top: 70px; + left:0; + right: 0; + bottom: 0; + .next-tabs-tabpane { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + outline: none !important; + box-shadow: none !important; + } + } + .lc-outline-pane { + position: absolute; + z-index: 100; + background-color: white; + top: 0; + bottom: 0; + display: none; + } +} + +.lc-settings-pane { + padding-bottom: 50px; + .next-btn { + line-height: 1 !important; + } +} + +html.lc-cursor-dragging:not(.lowcode-has-fixed-tree) { + .lc-settings-main .lc-outline-pane { + display: block; + } +} diff --git a/packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts b/packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts new file mode 100644 index 000000000..c3072df54 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts @@ -0,0 +1,255 @@ +import { TransformedComponentMetadata, FieldConfig, SettingTarget } from '@ali/lowcode-types'; + +export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { + const { componentName, configure = {} } = metadata; + if (componentName === 'Leaf') { + return { + ...metadata, + configure: { + ...configure, + combined: [ + { + name: 'children', + title: { type: 'i18n', 'zh-CN': '内容设置', 'en-US': 'Content' }, + setter: { + componentName: 'MixinSetter', + props: { + // TODO: + setters: [ + { + componentName: 'StringSetter', + props: { + // TODO: textarea mode + multiline: true, + }, + initialValue: '', + }, + { + componentName: 'ExpressionSetter', + initialValue: { + type: 'JSExpression', + value: '', + }, + }, + ], + }, + }, + }, + ], + }, + }; + } + + const { props, events = {}, styles } = configure as any; + const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; + const eventsDefinition: any[] = []; + const supportedLifecycles = + events.supportedLifecycles || + (isRoot + ? [ + { + description: '初始化时', + name: 'constructor', + }, + { + description: '装载后', + name: 'componentDidMount', + }, + { + description: '更新时', + name: 'componentDidMount', + }, + { + description: '卸载时', + name: 'componentWillUnmount', + }, + ] + : null); + if (supportedLifecycles) { + eventsDefinition.push({ + type: 'lifeCycleEvent', + title: '生命周期', + list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); + } + if (events.supportedEvents) { + eventsDefinition.push({ + type: 'events', + title: '事件', + list: (events.supportedEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); + } + // 通用设置 + const propsGroup = props || []; + propsGroup.push({ + name: '#generals', + title: { type: 'i18n', 'zh-CN': '通用', 'en-US': 'General' }, + items: [ + { + name: 'id', + title: 'ID', + setter: 'StringSetter', + }, + { + name: 'key', + title: 'Key', + // todo: use Mixin + setter: 'StringSetter', + }, + { + name: 'ref', + title: 'Ref', + setter: 'StringSetter', + }, + /* + { + name: '!more', + title: '更多', + setter: 'PropertiesSetter', + },*/ + ], + }); + const combined: FieldConfig[] = [ + { + title: { type: 'i18n', 'zh-CN': '属性', 'en-US': 'Props' }, + name: '#props', + items: propsGroup, + }, + ]; + const stylesGroup: FieldConfig[] = []; + if (styles?.supportClassName) { + stylesGroup.push({ + name: 'className', + title: { type: 'i18n', 'zh-CN': '类名绑定', 'en-US': 'ClassName' }, + setter: 'ClassNameSetter', + }); + } + if (styles?.supportInlineStyle) { + stylesGroup.push({ + name: 'style', + title: { type: 'i18n', 'zh-CN': '行内样式', 'en-US': 'Style' }, + setter: 'StyleSetter', + }); + } + if (stylesGroup.length > 0) { + combined.push({ + name: '#styles', + title: { type: 'i18n', 'zh-CN': '样式', 'en-US': 'Styles' }, + items: stylesGroup, + }); + } + + if (eventsDefinition.length > 0) { + combined.push({ + name: '#events', + title: { type: 'i18n', 'zh-CN': '事件', 'en-US': 'Events' }, + items: [ + { + name: '!events', + title: { type: 'i18n', 'zh-CN': '事件设置', 'en-US': 'Events' }, + setter: { + componentName: 'EventsSetter', + props: { + definition: eventsDefinition, + }, + }, + getValue(field: SettingTarget, val?: any[]) { + // todo: + return val; + }, + + setValue(field: SettingTarget, eventDataList: any[]) { + // todo: + return; + }, + }, + ], + }); + } + + if (isRoot) { + /* + combined.push({ + name: '#advanced', + title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, + items: [], + }); + */ + } else { + combined.push({ + name: '#advanced', + title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, + items: [ + { + name: '__condition', + title: { type: 'i18n', 'zh-CN': '条件显示', 'en-US': 'Condition' }, + setter: 'ExpressionSetter', + }, + { + name: '#loop', + title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' }, + items: [ + { + name: '__loop', + title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, + setter: { + componentName: 'MixinSetter', + props: { + // TODO: + setters: [ + { + componentName: 'JSONSetter', + props: { + mode: 'popup', + placeholder: { type: 'i18n', 'zh-CN': '编辑数据', 'en-US': 'Edit Data' }, + }, + }, + { + componentName: 'ExpressionSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '绑定数据', 'en-US': 'Bind Data' }, + }, + }, + ], + }, + }, + }, + { + name: '__loopArgs.0', + title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' }, + setter: { + componentName: 'StringSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '默认为: item', 'en-US': 'Defaults: item' }, + } + }, + }, + { + name: '__loopArgs.1', + title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' }, + setter: { + componentName: 'StringSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '默认为: index', 'en-US': 'Defaults: index' }, + } + }, + }, + { + name: 'key', + title: 'Key', + setter: 'ExpressionSetter', + }, + ], + }, + ], + }); + } + + return { + ...metadata, + configure: { + ...configure, + combined, + }, + }; +} diff --git a/packages/editor-skeleton/src/components/settings/transducers/parse-props.ts b/packages/editor-skeleton/src/components/settings/transducers/parse-props.ts new file mode 100644 index 000000000..bbf107a81 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/transducers/parse-props.ts @@ -0,0 +1,232 @@ +import { + FieldConfig, + PropConfig, + PropType, + SetterType, + OneOf, + Shape, + ObjectOf, + ArrayOf, + TransformedComponentMetadata, +} from '@ali/lowcode-types'; + +function propConfigToFieldConfig(propConfig: PropConfig): FieldConfig { + const { name, description } = propConfig; + const title = { + label: { + type: 'i18n', + 'en-US': name, + 'zh-CN': description?.slice(0, 10) || name, + }, + tip: description ? `${name} | ${description}` : undefined, + }; + return { + title, + ...propConfig, + setter: propTypeToSetter(propConfig.propType), + }; +} + +function propTypeToSetter(propType: PropType): SetterType { + let typeName: string; + let isRequired: boolean | undefined = false; + if (typeof propType === 'string') { + typeName = propType; + } else { + typeName = propType.type; + isRequired = propType.isRequired; + } + // TODO: use mixinSetter wrapper + switch (typeName) { + case 'string': + return { + componentName: 'StringSetter', + isRequired, + initialValue: '', + }; + + case 'number': + return { + componentName: 'NumberSetter', + isRequired, + initialValue: 0, + }; + case 'bool': + return { + componentName: 'NumberSetter', + isRequired, + initialValue: false, + }; + case 'oneOf': + const dataSource = ((propType as OneOf).value || []).map((value, index) => { + const t = typeof value; + return { + label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`, + value, + }; + }); + const componentName = dataSource.length > 4 ? 'SelectSetter' : 'RadioGroupSetter'; + return { + componentName, + props: { dataSource }, + isRequired, + initialValue: dataSource[0] ? dataSource[0].value : null, + }; + + case 'element': + case 'node': // TODO: use Mixin + return { + // slotSetter + componentName: 'NodeSetter', + props: { + mode: typeName, + }, + isRequired, + initialValue: { + type: 'JSSlot', + value: '', + }, + }; + case 'shape': + case 'exact': + const items = (propType as Shape).value.map((item) => propConfigToFieldConfig(item)); + return { + componentName: 'ObjectSetter', + props: { + config: { + items, + extraSetter: typeName === 'shape' ? propTypeToSetter('any') : null, + }, + }, + isRequired, + initialValue: (field: any) => { + const data: any = {}; + items.forEach((item) => { + let initial = item.defaultValue; + if (initial == null && item.setter && typeof item.setter === 'object') { + initial = (item.setter as any).initialValue; + } + data[item.name] = initial ? (typeof initial === 'function' ? initial(field) : initial) : null; + }); + return data; + }, + }; + case 'object': + case 'objectOf': + return { + componentName: 'ObjectSetter', + props: { + config: { + extraSetter: propTypeToSetter(typeName === 'objectOf' ? (propType as ObjectOf).value : 'any'), + }, + }, + isRequired, + }; + case 'array': + case 'arrayOf': + return { + componentName: 'ArraySetter', + props: { + itemSetter: propTypeToSetter(typeName === 'arrayOf' ? (propType as ArrayOf).value : 'any'), + }, + isRequired, + initialValue: [], + }; + case 'func': + return { + componentName: 'FunctionSetter', + isRequired, + initialValue: { + type: 'JSFunction', + value: 'function(){}', + }, + }; + case 'oneOfType': + return { + componentName: 'MixinSetter', + props: { + // TODO: + // setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), + }, + isRequired, + }; + } + + return { + componentName: 'MixinSetter', + isRequired, + }; +} + +const EVENT_RE = /^on[A-Z][\w]*$/; + +export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { + const { configure } = metadata; + if (configure.props) { + return metadata; + } + + if (!metadata.props) { + return { + ...metadata, + configure: { + ...configure, + props: [], + }, + }; + } + const { component = {}, events = {}, styles = {} } = configure; + const supportedEvents: any[] | null = (events as any).supportedEvents ? null : []; + const props: FieldConfig[] = []; + + metadata.props.forEach((prop) => { + const { name, propType, description } = prop; + if ( + name === 'children' && + (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') + ) { + if (component.isContainer !== false) { + component.isContainer = true; + return; + } + } + + if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) { + if (supportedEvents) { + supportedEvents.push({ + name, + description, + }); + (events as any).supportedEvents = supportedEvents; + } + return; + } + + if (name === 'className' && (propType === 'string' || propType === 'any')) { + if ((styles as any).supportClassName == null) { + (styles as any).supportClassName = true; + } + return; + } + + if (name === 'style' && (propType === 'object' || propType === 'any')) { + if ((styles as any).supportInlineStyle == null) { + (styles as any).supportInlineStyle = true; + } + return; + } + + props.push(propConfigToFieldConfig(prop)); + }); + + return { + ...metadata, + configure: { + ...configure, + props, + events, + styles, + component, + }, + }; +} diff --git a/packages/editor-skeleton/src/components/settings/transducers/register.ts b/packages/editor-skeleton/src/components/settings/transducers/register.ts new file mode 100644 index 000000000..0ac451c52 --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/transducers/register.ts @@ -0,0 +1,9 @@ +import { registerMetadataTransducer } from '@ali/lowcode-designer'; +import parseProps from './parse-props'; +import addonCombine from './addon-combine'; + +// parseProps +registerMetadataTransducer(parseProps, 10, 'parse-props'); + +// addon/platform custom +registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/editor-skeleton/src/components/settings/utils.js b/packages/editor-skeleton/src/components/settings/utils.js new file mode 100644 index 000000000..b8f5bbdcc --- /dev/null +++ b/packages/editor-skeleton/src/components/settings/utils.js @@ -0,0 +1,41 @@ +function getHotterFromSetter(setter) { + return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line +} + +function getTransducerFromSetter(setter) { + return setter && ( + setter.transducer || setter.Transducer + || (setter.type && (setter.type.transducer || setter.type.Transducer)) + ) || null; // eslint-disable-line +} + +function combineTransducer(transducer, arr, context) { + if (!transducer && Array.isArray(arr)) { + const [toHot, toNative] = arr; + transducer = { toHot, toNative }; + } + + return { + toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line + toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line + }; +} + +export class Transducer { + constructor(context, config) { + this.setterTransducer = combineTransducer( + getTransducerFromSetter(config.setter), + getHotterFromSetter(config.setter), + context, + ); + this.context = context; + } + + toHot(data) { + return this.setterTransducer.toHot(data); + } + + toNative(data) { + return this.setterTransducer.toNative(data); + } +} diff --git a/packages/editor-skeleton/src/components/widget-views.tsx b/packages/editor-skeleton/src/components/widget-views.tsx new file mode 100644 index 000000000..e097c3407 --- /dev/null +++ b/packages/editor-skeleton/src/components/widget-views.tsx @@ -0,0 +1,236 @@ +import { Component, ReactElement } from 'react'; +import classNames from 'classnames'; +import { Title, observer } from '@ali/lowcode-editor-core'; +import { DockProps } from '../types'; +import PanelDock from '../widget/panel-dock'; +import { composeTitle } from '../widget/utils'; +import WidgetContainer from '../widget/widget-container'; +import Panel from '../widget/panel'; +import { IWidget } from '../widget/widget'; +import { SkeletonEvents } from '../skeleton'; + +export function DockView({ title, icon, description, size, className, onClick }: DockProps) { + return ( + <Title + title={composeTitle(title, icon, description)} + className={classNames('lc-dock', className, { + [`lc-dock-${size}`]: size, + })} + onClick={onClick} + /> + ); +} + +@observer +export class PanelDockView extends Component<DockProps & { dock: PanelDock }> { + componentDidMount() { + this.checkActived(); + } + componentDidUpdate() { + this.checkActived(); + } + private lastActived: boolean = false; + checkActived() { + const { dock } = this.props; + if (dock.actived !== this.lastActived) { + this.lastActived = dock.actived; + if (this.lastActived) { + dock.skeleton.postEvent(SkeletonEvents.PANEL_DOCK_ACTIVE, dock.name, dock); + } else { + dock.skeleton.postEvent(SkeletonEvents.PANEL_DOCK_UNACTIVE, dock.name, dock); + } + } + } + + render() { + const { dock, className, onClick, ...props } = this.props; + return DockView({ + ...props, + className: classNames(className, { + actived: dock.actived, + }), + onClick: () => { + onClick && onClick(); + dock.togglePanel(); + }, + }); + } +} + +export class DialogDockView extends Component { + +} + +@observer +export class TitledPanelView extends Component<{ panel: Panel }> { + shouldComponentUpdate() { + return false; + } + componentDidMount() { + this.checkVisible(); + } + componentDidUpdate() { + this.checkVisible(); + } + private lastVisible: boolean = false; + checkVisible() { + const { panel } = this.props; + const currentVisible = panel.inited && panel.visible; + if (currentVisible !== this.lastVisible) { + this.lastVisible = currentVisible; + if (this.lastVisible) { + panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); + } else { + panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); + } + } + } + render() { + const { panel } = this.props; + if (!panel.inited) { + return null; + } + return ( + <div className={classNames('lc-titled-panel', { + hidden: !panel.visible, + })}> + <PanelTitle panel={panel} /> + <div className="lc-pane-body">{panel.body}</div> + </div> + ); + } +} + +@observer +export class PanelView extends Component<{ panel: Panel }> { + shouldComponentUpdate() { + return false; + } + componentDidMount() { + this.checkVisible(); + } + componentDidUpdate() { + this.checkVisible(); + } + private lastVisible: boolean = false; + checkVisible() { + const { panel } = this.props; + const currentVisible = panel.inited && panel.visible; + if (currentVisible !== this.lastVisible) { + this.lastVisible = currentVisible; + if (this.lastVisible) { + panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); + // FIXME! remove this line + panel.skeleton.postEvent('leftPanel.show' as any, panel.name, panel); + } else { + panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); + // FIXME! remove this line + panel.skeleton.postEvent('leftPanel.hide' as any, panel.name, panel); + } + } + } + render() { + const { panel } = this.props; + if (!panel.inited) { + return null; + } + return ( + <div + className={classNames('lc-panel', { + hidden: !panel.visible, + })} + > + {panel.body} + </div> + ); + } +} + +@observer +export class TabsPanelView extends Component<{ container: WidgetContainer<Panel> }> { + render() { + const { container } = this.props; + const titles: ReactElement[] = []; + const contents: ReactElement[] = []; + container.items.forEach((item: any) => { + titles.push(<PanelTitle key={item.id} panel={item} className="lc-tab-title" />); + contents.push(<PanelView key={item.id} panel={item} />); + }); + + return ( + <div className="lc-tabs"> + <div + className="lc-tabs-title" + onClick={(e) => { + const shell = e.currentTarget; + const t = e.target as Element; + let elt = shell.firstElementChild; + while (elt) { + if (elt.contains(t)) { + break; + } + elt = elt.nextElementSibling; + } + if (elt) { + container.active((elt as any).dataset.name); + } + }} + > + {titles} + </div> + <div className="lc-tabs-content">{contents}</div> + </div> + ); + } +} + +@observer +class PanelTitle extends Component<{ panel: Panel; className?: string }> { + render() { + const { panel, className } = this.props; + return ( + <div + className={classNames('lc-panel-title', className, { + actived: panel.actived, + })} + data-name={panel.name} + > + <Title title={panel.title || panel.name} /> + {/*pane.help ? <HelpTip tip={panel.help} /> : null*/} + </div> + ); + } +} + +@observer +export class WidgetView extends Component<{ widget: IWidget }> { + shouldComponentUpdate() { + return false; + } + componentDidMount() { + this.checkVisible(); + } + componentDidUpdate() { + this.checkVisible(); + } + private lastVisible: boolean = false; + checkVisible() { + const { widget } = this.props; + const currentVisible = widget.visible; + if (currentVisible !== this.lastVisible) { + this.lastVisible = currentVisible; + if (this.lastVisible) { + widget.skeleton.postEvent(SkeletonEvents.WIDGET_SHOW, widget.name, widget); + } else { + widget.skeleton.postEvent(SkeletonEvents.WIDGET_SHOW, widget.name, widget); + } + } + } + render() { + const { widget } = this.props; + if (!widget.visible) { + return null; + } + return widget.body; + } +} diff --git a/packages/editor-skeleton/src/config/skeleton.ts b/packages/editor-skeleton/src/config/skeleton.ts deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/config/skeleton.ts +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/config/utils.ts b/packages/editor-skeleton/src/config/utils.ts deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/config/utils.ts +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/dock.ts b/packages/editor-skeleton/src/dock.ts new file mode 100644 index 000000000..affa84d98 --- /dev/null +++ b/packages/editor-skeleton/src/dock.ts @@ -0,0 +1,87 @@ +import { ReactNode, createElement } from 'react'; +import { obx } from '@ali/lowcode-editor-core'; +import { uniqueId, createContent } from '@ali/lowcode-utils'; +import { DockConfig } from "./types"; +import { Skeleton } from './skeleton'; +import { DockView, WidgetView } from './components/widget-views'; +import { IWidget } from './widget/widget'; + +/** + * 带图标(主要)/标题(次要)的扩展 + */ +export default class Dock implements IWidget { + readonly isWidget = true; + readonly id = uniqueId('dock'); + readonly name: string; + readonly align?: string; + + @obx.ref private _visible: boolean = true; + get visible(): boolean { + return this._visible; + } + + get content(): ReactNode { + return createElement(WidgetView, { + widget: this, + key: this.id, + }); + } + + private inited: boolean = false; + private _body: ReactNode; + get body() { + if (this.inited) { + return this._body; + } + + const { props, content, contentProps } = this.config; + + if (content) { + this._body = createContent(content, { + ...contentProps, + config: this.config, + editor: this.skeleton.editor, + }); + } else { + this._body = createElement(DockView, props); + } + return this._body; + } + + constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { + const { props = {}, name } = config; + this.name = name; + this.align = props.align; + } + + setVisible(flag: boolean) { + if (flag === this._visible) { + return; + } + if (flag) { + this._visible = true; + } else if (this.inited) { + this._visible = false; + } + } + + getContent() { + return this.content; + } + + getName() { + return this.name; + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } + + toggle() { + this.setVisible(!this._visible); + } +} diff --git a/packages/editor-skeleton/src/global.scss b/packages/editor-skeleton/src/global.scss deleted file mode 100644 index 6ea0487ea..000000000 --- a/packages/editor-skeleton/src/global.scss +++ /dev/null @@ -1,33 +0,0 @@ -body { - font-family: PingFangSC-Regular, Roboto, Helvetica Neue, Helvetica, Tahoma, - Arial, PingFang SC-Light, Microsoft YaHei; - font-size: 12px; - padding: 0; - margin: 0; - * { - box-sizing: border-box; - } - color: $color-text1-3; -} - -.next-loading { - .next-loading-wrap { - height: 100%; - } -} -.lowcode-editor { - .lowcode-main-content { - position: absolute; - top: 50px; - left: 0; - right: 0; - bottom: 0; - display: flex; - background-color: rgba(31, 56, 88, 0.06); - } - .lowcode-center-area { - flex: 1; - display: flex; - flex-direction: column; - } -} diff --git a/packages/editor-skeleton/src/icons/convert.tsx b/packages/editor-skeleton/src/icons/convert.tsx new file mode 100644 index 000000000..2db5e2063 --- /dev/null +++ b/packages/editor-skeleton/src/icons/convert.tsx @@ -0,0 +1,16 @@ +import { SVGIcon, IconProps } from "@ali/lowcode-utils"; + +export function IconConvert(props: IconProps) { + return ( + <SVGIcon viewBox="0 0 1024 1024" {...props}> + <path d="M508.16 889.6C291.84 889.6 115.2 714.24 115.2 497.92 115.2 281.6 291.84 106.24 509.44 106.24c43.52 0 85.76 6.4 124.16 20.48l-10.24 30.72c-35.84-11.52-72.96-17.92-113.92-17.92-199.68 0-362.24 161.28-362.24 359.68s162.56 358.4 360.96 358.4 359.68-161.28 359.68-359.68c0-66.56-17.92-131.84-51.2-185.6L844.8 294.4c37.12 60.16 56.32 130.56 56.32 203.52-1.28 216.32-176.64 391.68-392.96 391.68z" /> + <path d="M627.2 140.8m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> + <path d="M832 304.64m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> + <path d="M348.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + <path d="M508.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + <path d="M668.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + </SVGIcon> + ); +} + +IconConvert.displayName = 'Convert'; diff --git a/packages/editor-skeleton/src/index.ts b/packages/editor-skeleton/src/index.ts index 061621d42..923bd59cb 100644 --- a/packages/editor-skeleton/src/index.ts +++ b/packages/editor-skeleton/src/index.ts @@ -1,9 +1 @@ -import Skeleton from './skeleton'; -import Panel from './components/Panel'; -import TopIcon from './components/TopIcon'; -import TopPlugin from './components/TopPlugin'; -import LeftPlugin from './components/LeftPlugin'; - -export default Skeleton; - -export { Panel, TopIcon, TopPlugin, LeftPlugin }; +export { Workbench } from './layouts/workbench'; diff --git a/packages/editor-skeleton/src/layouts/CenterArea/index.scss b/packages/editor-skeleton/src/layouts/CenterArea/index.scss deleted file mode 100644 index 40a1806a6..000000000 --- a/packages/editor-skeleton/src/layouts/CenterArea/index.scss +++ /dev/null @@ -1,3 +0,0 @@ -.lowcode-center-area { - padding: 0; -} diff --git a/packages/editor-skeleton/src/layouts/CenterArea/index.tsx b/packages/editor-skeleton/src/layouts/CenterArea/index.tsx deleted file mode 100644 index 3261b4bbe..000000000 --- a/packages/editor-skeleton/src/layouts/CenterArea/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React, { PureComponent } from 'react'; -import Editor, { AreaManager } from '@ali/lowcode-editor-core'; -import './index.scss'; - -export interface CenterAreaProps { - editor: Editor; -} - -export default class CenterArea extends PureComponent<CenterAreaProps> { - static displayName = 'LowcodeCenterArea'; - - private editor: Editor; - - private areaManager: AreaManager; - - constructor(props) { - super(props); - this.editor = props.editor; - this.areaManager = new AreaManager(this.editor, 'centerArea'); - } - - componentDidMount(): void { - this.editor.on('skeleton.update', this.handleSkeletonUpdate); - } - - componentWillUnmount(): void { - this.editor.off('skeleton.update', this.handleSkeletonUpdate); - } - - handleSkeletonUpdate = (): void => { - // 当前区域插件状态改变是更新区域 - if (this.areaManager.isPluginStatusUpdate()) { - this.forceUpdate(); - } - }; - - render(): React.ReactNode { - const visiblePluginList = this.areaManager.getVisiblePluginList(); - return ( - <div className="lowcode-center-area"> - {visiblePluginList.map( - (item): React.ReactNode => { - const Comp = this.areaManager.getPluginClass(item.pluginKey); - if (Comp) { - return ( - <Comp - key={item.pluginKey} - editor={this.editor} - config={item} - {...item.pluginProps} - /> - ); - } - return null; - }, - )} - </div> - ); - } -} diff --git a/packages/editor-skeleton/src/layouts/LeftArea/index.scss b/packages/editor-skeleton/src/layouts/LeftArea/index.scss deleted file mode 100644 index 8c69f42fc..000000000 --- a/packages/editor-skeleton/src/layouts/LeftArea/index.scss +++ /dev/null @@ -1,23 +0,0 @@ -.lowcode-left-area-nav { - width: 50px; - height: 100%; - background-color: $card-background; - border-right: 2px solid $color-line1-1; - position: relative; - .top-area { - position: absolute; - top: 0; - width: 100%; - padding: 12px 0; - background-color: $card-background; - max-height: 100%; - } - .bottom-area { - position: absolute; - bottom: 0; - width: 100%; - padding: 12px 0; - background-color: $card-background; - max-height: calc(100% - 20px); - } -} diff --git a/packages/editor-skeleton/src/layouts/LeftArea/index.tsx b/packages/editor-skeleton/src/layouts/LeftArea/index.tsx deleted file mode 100644 index 805a5e014..000000000 --- a/packages/editor-skeleton/src/layouts/LeftArea/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import Nav from './nav'; -import Panel from './panel'; - -export default { - Nav, - Panel, -}; diff --git a/packages/editor-skeleton/src/layouts/LeftArea/nav.tsx b/packages/editor-skeleton/src/layouts/LeftArea/nav.tsx deleted file mode 100644 index 735b77a27..000000000 --- a/packages/editor-skeleton/src/layouts/LeftArea/nav.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { PureComponent } from 'react'; -import LeftPlugin from '../../components/LeftPlugin'; -import Editor, { utils, AreaManager } from '@ali/lowcode-editor-core'; -import { PluginConfig } from '@ali/lowcode-editor-core/lib/definitions'; - -import './index.scss'; - -const { isEmpty } = utils; - -export interface LeftAreaNavProps { - editor: Editor; -} - -export interface LeftAreaNavState { - activeKey: string; -} - -export default class LeftAreaNav extends PureComponent< - LeftAreaNavProps, - LeftAreaNavState -> { - static displayName = 'LowcodeLeftAreaNav'; - - private editor: Editor; - - private areaManager: AreaManager; - - constructor(props) { - super(props); - this.editor = props.editor; - this.areaManager = new AreaManager(this.editor, 'leftArea'); - - this.state = { - activeKey: 'none', - }; - } - - componentDidMount(): void { - this.editor.on('skeleton.update', this.handleSkeletonUpdate); - this.editor.on('leftNav.change', this.handlePluginChange); - const visiblePanelPluginList = this.areaManager.getVisiblePluginList( - 'IconPanel', - ); - const defaultKey = - (visiblePanelPluginList[0] && visiblePanelPluginList[0].pluginKey) || - 'componentAttr'; - this.handlePluginChange(defaultKey); - } - - componentWillUnmount(): void { - this.editor.off('skeleton.update', this.handleSkeletonUpdate); - this.editor.off('leftNav.change', this.handlePluginChange); - } - - handleSkeletonUpdate = (): void => { - // 当前区域插件状态改变是更新区域 - if (this.areaManager.isPluginStatusUpdate()) { - this.forceUpdate(); - } - }; - - handlePluginChange = (key: string): void => { - const { activeKey } = this.state; - const plugins = this.editor.plugins; - const prePlugin = plugins[activeKey]; - const nextPlugin = plugins[key]; - if (activeKey === 'none') { - if (nextPlugin) { - nextPlugin.open().then((): void => { - this.updateActiveKey(key); - }); - } - } else if (activeKey === key) { - if (prePlugin) { - prePlugin.close().then((): void => { - this.updateActiveKey('none'); - }); - } - } else if (prePlugin) { - // 先关后开 - prePlugin.close().then((): void => { - if (nextPlugin) { - nextPlugin.open().then((): void => { - this.updateActiveKey(key); - }); - } - }); - } - }; - - handlePluginClick = (item: PluginConfig): void => { - if (item.type === 'PanelIcon') { - this.handlePluginChange(item.pluginKey); - } - }; - - updateActiveKey = (key: string): void => { - this.editor.set('leftNav', key); - this.setState({ activeKey: key }); - this.editor.emit('leftPanel.show', key); - }; - - renderPluginList = (list: PluginConfig[] = []): React.ReactElement[] => { - const { activeKey } = this.state; - return list.map( - (item): React.ReactElement => { - const pluginStatus = this.areaManager.getPluginStatus(item.pluginKey); - const pluginClass = this.areaManager.getPluginClass(item.pluginKey); - return ( - <LeftPlugin - key={item.pluginKey} - config={item} - editor={this.editor} - pluginClass={pluginClass} - onClick={(): void => this.handlePluginClick(item)} - active={activeKey === item.pluginKey} - {...pluginStatus} - /> - ); - }, - ); - }; - - render(): React.ReactNode { - const topList: PluginConfig[] = []; - const bottomList: PluginConfig[] = []; - const visiblePluginList = this.areaManager.getVisiblePluginList(); - if (isEmpty(visiblePluginList)) { - return null; - } - visiblePluginList.forEach((item): void => { - const align = - item.props && item.props.align === 'bottom' ? 'bottom' : 'top'; - if (align === 'bottom') { - bottomList.push(item); - } else { - topList.push(item); - } - }); - - return ( - <div className="lowcode-left-area-nav"> - <div className="bottom-area">{this.renderPluginList(bottomList)}</div> - <div className="top-area">{this.renderPluginList(topList)}</div> - </div> - ); - } -} diff --git a/packages/editor-skeleton/src/layouts/LeftArea/panel.tsx b/packages/editor-skeleton/src/layouts/LeftArea/panel.tsx deleted file mode 100644 index ccb81cfe0..000000000 --- a/packages/editor-skeleton/src/layouts/LeftArea/panel.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { PureComponent, Fragment } from 'react'; -import Editor, { AreaManager } from '@ali/lowcode-editor-core'; -import Panel from '../../components/Panel'; - -import './index.scss'; - -export interface LeftAreaPanelProps { - editor: Editor; -} - -export interface LeftAreaPanelState { - activeKey: string; -} - -export default class LeftAreaPanel extends PureComponent< - LeftAreaPanelProps, - LeftAreaPanelState -> { - static displayName = 'LowcodeLeftAreaPanel'; - - private editor: Editor; - - private areaManager: AreaManager; - - constructor(props) { - super(props); - this.editor = props.editor; - this.areaManager = new AreaManager(this.editor, 'leftArea'); - - this.state = { - activeKey: 'none', - }; - } - - componentDidMount(): void { - this.editor.on('skeleton.update', this.handleSkeletonUpdate); - this.editor.on('leftPanel.show', this.handlePluginChange); - } - - componentWillUnmount(): void { - this.editor.off('skeleton.update', this.handleSkeletonUpdate); - this.editor.off('leftPanel.show', this.handlePluginChange); - } - - handleSkeletonUpdate = (): void => { - // 当前区域插件状态改变是更新区域 - if (this.areaManager.isPluginStatusUpdate('PanelIcon')) { - this.forceUpdate(); - } - }; - - handlePluginChange = (key: string): void => { - this.setState({ - activeKey: key, - }); - }; - - render(): React.ReactNode { - const { activeKey } = this.state; - const list = this.areaManager.getVisiblePluginList('PanelIcon'); - - return ( - <Fragment> - {list.map( - (item): React.ReactNode => { - const Comp = this.areaManager.getPluginClass(item.pluginKey); - if (Comp) { - return ( - <Panel - key={item.pluginKey} - visible={item.pluginKey === activeKey} - {...(item.props && item.props.panelProps)} - > - <Comp - editor={this.editor} - config={item} - {...item.pluginProps} - /> - </Panel> - ); - } - return null; - }, - )} - </Fragment> - ); - } -} diff --git a/packages/editor-skeleton/src/layouts/RightArea/index.scss b/packages/editor-skeleton/src/layouts/RightArea/index.scss deleted file mode 100644 index 7373933b0..000000000 --- a/packages/editor-skeleton/src/layouts/RightArea/index.scss +++ /dev/null @@ -1,39 +0,0 @@ -.lowcode-right-area { - width: 262px; - height: 100%; - background-color: $card-background; - border-left: 2px solid $color-line1-1; - - .right-panel { - overflow: auto; - // border-top: 2px solid $color-line1-1; - } - - //tab定义 - .right-tabs.next-tabs { - .next-tabs-nav { - width: 100%; - .next-tabs-tab-inner { - padding-left: 0; - padding-right: 0; - } - .right-plugin-title { - text-align: center; - &.locked { - color: red !important; - } - &.active { - color: $color-brand1-9 !important; - } - &.disabled { - cursor: not-allowed; - color: $color-text1-1; - } - .next-icon { - line-height: 15px; - margin-right: 2px; - } - } - } - } -} diff --git a/packages/editor-skeleton/src/layouts/RightArea/index.tsx b/packages/editor-skeleton/src/layouts/RightArea/index.tsx deleted file mode 100644 index 5925284da..000000000 --- a/packages/editor-skeleton/src/layouts/RightArea/index.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Tab, Badge, Icon } from '@alifd/next'; -import classNames from 'classnames'; -import Editor, { AreaManager, utils } from '@ali/lowcode-editor-core'; -import { PluginConfig } from '@ali/lowcode-editor-core/lib/definitions'; -import './index.scss'; - -const { isEmpty } = utils; - -export interface RightAreaProps { - editor: Editor; -} - -export interface RightAreaState { - activeKey: string; -} - -export default class RightArea extends PureComponent< - RightAreaProps, - RightAreaState -> { - static displayName = 'LowcodeRightArea'; - - private editor: Editor; - - private areaManager: AreaManager; - - constructor(props) { - super(props); - this.editor = props.editor; - this.areaManager = new AreaManager(this.editor, 'rightArea'); - this.state = { - activeKey: '', - }; - } - - componentDidMount(): void { - this.editor.on('skeleton.update', this.handleSkeletonUpdate); - this.editor.on('rightNav.change', this.handlePluginChange); - const visiblePluginList = this.areaManager.getVisiblePluginList('TabPanel'); - const defaultKey = - (visiblePluginList[0] && visiblePluginList[0].pluginKey) || - 'componentAttr'; - this.handlePluginChange(defaultKey, true); - } - - componentWillUnmount(): void { - this.editor.off('skeleton.update', this.handleSkeletonUpdate); - this.editor.off('rightNav.change', this.handlePluginChange); - } - - handleSkeletonUpdate = (): void => { - // 当前区域插件状态改变是更新区域 - if (this.areaManager.isPluginStatusUpdate()) { - const activeKey = this.state.activeKey; - const activePluginStatus = this.areaManager.getPluginStatus(activeKey); - if (activePluginStatus && activePluginStatus.visible) { - this.forceUpdate(); - } else { - const currentPlugin = this.areaManager.getPlugin(activeKey); - if (currentPlugin) { - currentPlugin.close().then((): void => { - this.setState( - { - activeKey: '', - }, - (): void => { - const visiblePluginList = this.areaManager.getVisiblePluginList( - 'TabPanel', - ); - const firstPlugin = visiblePluginList && visiblePluginList[0]; - if (firstPlugin) { - this.handlePluginChange(firstPlugin.pluginKey); - } - }, - ); - }); - } - } - } - }; - - handlePluginChange = (key: string, isinit?: boolean): void => { - const activeKey = this.state.activeKey; - const currentPlugin = this.areaManager.getPlugin(activeKey); - const nextPlugin = this.areaManager.getPlugin(key); - const openPlugin = (): void => { - if (!nextPlugin) { - console.error(`plugin ${key} has not regist in the editor`); - return; - } - nextPlugin.open().then((): void => { - this.editor.set('rightNav', key); - this.setState({ - activeKey: key, - }); - }); - }; - if (key === activeKey && !isinit) return; - if (currentPlugin) { - currentPlugin.close().then((): void => { - openPlugin(); - }); - } else { - openPlugin(); - } - }; - - renderTabTitle = (config: PluginConfig): React.ReactElement => { - const { icon, title } = config.props || {}; - const pluginStatus = this.editor.pluginStatus[config.pluginKey]; - const { marked, disabled, locked } = pluginStatus; - const active = this.state.activeKey === config.pluginKey; - - const renderTitle = (): React.ReactElement => ( - <div - className={classNames('right-plugin-title', { - active, - locked, - disabled, - })} - > - {!!icon && <Icon size="xs" type={icon} />} - {title} - </div> - ); - if (marked) { - return <Badge dot>{renderTitle()}</Badge>; - } - return renderTitle(); - }; - - renderTabPanels = (list: PluginConfig[], height: string): React.ReactNode => { - if (isEmpty(list)) { - return null; - } - return ( - <Tab - className="right-tabs" - style={{ - height, - }} - activeKey={this.state.activeKey} - lazyLoad={false} - onChange={this.handlePluginChange} - > - {list.map( - (item): React.ReactNode => { - const Comp = this.areaManager.getPluginClass(item.pluginKey); - if (Comp) { - return ( - <Tab.Item - key={item.pluginKey} - title={this.renderTabTitle(item)} - disabled={this.editor.pluginStatus[item.pluginKey].disabled} - style={{ - width: `${100 / list.length}%`, - }} - > - <Comp - editor={this.editor} - config={item} - {...item.pluginProps} - /> - </Tab.Item> - ); - } - return null; - }, - )} - </Tab> - ); - }; - - renderPanels = (list: PluginConfig[], height: string): React.ReactNode => { - return list.map( - (item): React.ReactNode => { - const Comp = this.areaManager.getPluginClass(item.pluginKey); - if (Comp) { - return ( - <div - className="right-panel" - style={{ height }} - key={item.pluginKey} - > - <Comp editor={this.editor} config={item} {...item.pluginProps} /> - </div> - ); - } - return null; - }, - ); - }; - - render(): React.ReactNode { - const tabList = this.areaManager.getVisiblePluginList('TabPanel'); - const panelList = this.areaManager.getVisiblePluginList('Panel'); - if (isEmpty(panelList) && isEmpty(tabList)) { - return null; - } else if (tabList.length === 1) { - panelList.unshift(tabList[0]); - tabList.splice(0, 1); - } - const height = `${Math.floor( - 100 / (panelList.length + (tabList.length > 0 ? 1 : 0)), - )}%`; - return ( - <div className="lowcode-right-area"> - {this.renderTabPanels(tabList, height)} - {this.renderPanels(panelList, height)} - </div> - ); - } -} diff --git a/packages/editor-skeleton/src/layouts/TopArea/index.scss b/packages/editor-skeleton/src/layouts/TopArea/index.scss deleted file mode 100644 index c0a132f84..000000000 --- a/packages/editor-skeleton/src/layouts/TopArea/index.scss +++ /dev/null @@ -1,30 +0,0 @@ -.lowcode-top-area { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 50px; - background-color: $card-background; - border-bottom: 2px solid $color-line1-1; - user-select: none; - .divider { - max-width: 0; - margin: 12px 16px; - height: 24px; - border-right: 1px solid $color-line1-2; - } - .next-col { - text-align: center; - } - .left-area { - padding: 0 16px; - } - .right-area { - position: absolute; - right: 0; - top: 0; - padding: 0 16px; - height: 100%; - background: $card-background; - } -} diff --git a/packages/editor-skeleton/src/layouts/TopArea/index.tsx b/packages/editor-skeleton/src/layouts/TopArea/index.tsx deleted file mode 100644 index 68c73f202..000000000 --- a/packages/editor-skeleton/src/layouts/TopArea/index.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import React, { PureComponent } from 'react'; -import { Grid } from '@alifd/next'; -import Editor, { AreaManager } from '@ali/lowcode-editor-core'; -import { PluginConfig } from '@ali/lowcode-editor-core/lib/definitions'; -import TopPlugin from '../../components/TopPlugin'; -import './index.scss'; - -const { Row, Col } = Grid; - -export interface TopAreaProps { - editor: Editor; -} - -export default class TopArea extends PureComponent<TopAreaProps> { - static displayName = 'LowcodeTopArea'; - - private areaManager: AreaManager; - - private editor: Editor; - - constructor(props) { - super(props); - this.editor = props.editor; - this.areaManager = new AreaManager(props.editor, 'topArea'); - } - - componentDidMount(): void { - this.editor.on('skeleton.update', this.handleSkeletonUpdate); - } - - componentWillUnmount(): void { - this.editor.off('skeleton.update', this.handleSkeletonUpdate); - } - - handleSkeletonUpdate = (): void => { - // 当前区域插件状态改变是更新区域 - if (this.areaManager.isPluginStatusUpdate()) { - this.forceUpdate(); - } - }; - - renderPluginList = (list: PluginConfig[] = []): React.ReactElement[] => { - return list.map( - (item, idx): React.ReactElement => { - const isDivider = item.type === 'Divider'; - const PluginClass = this.areaManager.getPluginClass(item.pluginKey); - return ( - <Col - className={isDivider ? 'divider' : ''} - key={isDivider ? idx : item.pluginKey} - style={{ - width: (item.props && item.props.width) || 36, - flex: 'none', - }} - > - {!isDivider && ( - <TopPlugin - config={item} - pluginClass={PluginClass} - editor={this.editor} - /> - )} - </Col> - ); - }, - ); - }; - - render(): React.ReactNode { - const leftList: PluginConfig[] = []; - const rightList: PluginConfig[] = []; - const visiblePluginList = this.areaManager.getVisiblePluginList(); - visiblePluginList.forEach((item): void => { - const align = - item.props && item.props.align === 'right' ? 'right' : 'left'; - // 分隔符不允许相邻 - if (item.type === 'Divider') { - const currList = align === 'right' ? rightList : leftList; - if ( - currList.length === 0 || - currList[currList.length - 1].type === 'Divider' - ) - return; - } - if (align === 'right') { - rightList.push(item); - } else { - leftList.push(item); - } - }); - return ( - <div className="lowcode-top-area"> - <div className="left-area"> - <Row>{this.renderPluginList(leftList)}</Row> - </div> - <div className="right-area"> - <Row justify="end">{this.renderPluginList(rightList)}</Row> - </div> - </div> - ); - } -} diff --git a/packages/editor-skeleton/src/layouts/bottom-area.tsx b/packages/editor-skeleton/src/layouts/bottom-area.tsx new file mode 100644 index 000000000..08bc337e2 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/bottom-area.tsx @@ -0,0 +1,37 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; +import Panel from '../widget/panel'; + +@observer +export default class BottomArea extends Component<{ area: Area<any, Panel> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + if (area.isEmpty()) { + return null; + } + return ( + <div className={classNames('lc-bottom-area', { + 'lc-area-visible': area.visible, + })}> + <Contents area={area} /> + </div> + ); + } +} + +@observer +class Contents extends Component<{ area: Area<any, Panel> }> { + render() { + const { area } = this.props; + return ( + <Fragment> + {area.container.items.map((item) => item.content)} + </Fragment> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/left-area.tsx b/packages/editor-skeleton/src/layouts/left-area.tsx new file mode 100644 index 000000000..00a83a328 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/left-area.tsx @@ -0,0 +1,41 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; + +@observer +export default class LeftArea extends Component<{ area: Area }> { + render() { + const { area } = this.props; + return ( + <div className={classNames("lc-left-area", { + 'lc-area-visible': area.visible + })}> + <Contents area={area} /> + </div> + ); + } +} + + +@observer +class Contents extends Component<{ area: Area }> { + render() { + const { area } = this.props; + const top: any[] = []; + const bottom: any[] = []; + area.container.items.forEach(item => { + if (item.align === 'bottom') { + bottom.push(item.content); + } else { + top.push(item.content); + } + }); + return ( + <Fragment> + <div className="lc-left-area-top">{top}</div> + <div className="lc-left-area-bottom">{bottom}</div> + </Fragment> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx new file mode 100644 index 000000000..c5ea01b53 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/left-fixed-pane.tsx @@ -0,0 +1,50 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import { Button, Icon } from '@alifd/next'; +import Area from '../area'; +import { PanelConfig } from '../types'; +import Panel from '../widget/panel'; + +@observer +export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + return ( + <div + className={classNames('lc-left-fixed-pane', { + 'lc-area-visible': area.visible, + })} + > + <Button + text + className="lc-pane-close" + onClick={() => { + area.setVisible(false); + }} + > + <Icon type="close" /> + </Button> + <Contents area={area} /> + </div> + ); + } +} + +@observer +class Contents extends Component<{ area: Area<PanelConfig, Panel> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + return ( + <Fragment> + {area.container.items.map((panel) => panel.content)} + </Fragment> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx new file mode 100644 index 000000000..84feacd6f --- /dev/null +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -0,0 +1,73 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import { Button, Icon } from '@alifd/next'; +import Area from '../area'; +import Panel from '../widget/panel'; + +@observer +export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { + shouldComponentUpdate() { + return false; + } + + private dispose?: () => void; + componentDidMount() { + const { area } = this.props; + const triggerClose = () => area.setVisible(false); + area.skeleton.editor.on('designer.dragstart', triggerClose); + this.dispose = () => { + area.skeleton.editor.removeListener('designer.dragstart', triggerClose); + } + } + + componentWillUnmount() { + this.dispose?.(); + } + + render() { + const { area } = this.props; + // TODO: add focusingManager + // focusin set focus (push|replace) + // focusout remove focus + // onEsc + const width = area.current?.config.props?.width; + const style = width ? { + width + } : undefined; + return ( + <div + className={classNames('lc-left-float-pane', { + 'lc-area-visible': area.visible, + })} + style={style} + > + <Button + text + className="lc-pane-close" + onClick={() => { + area.setVisible(false); + }} + > + <Icon type="close" /> + </Button> + <Contents area={area} /> + </div> + ); + } +} + +@observer +class Contents extends Component<{ area: Area<any, Panel> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + return ( + <Fragment> + {area.container.items.map((panel) => panel.content)} + </Fragment> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/main-area.tsx b/packages/editor-skeleton/src/layouts/main-area.tsx new file mode 100644 index 000000000..891053427 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/main-area.tsx @@ -0,0 +1,21 @@ +import { Component } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; +import Panel from '../widget/panel'; +import Widget from '../widget/widget'; + +@observer +export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + return ( + <div className={classNames('lc-main-area')}> + {area.container.items.map((item) => item.content)} + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/right-area.tsx b/packages/editor-skeleton/src/layouts/right-area.tsx new file mode 100644 index 000000000..9379f55b1 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/right-area.tsx @@ -0,0 +1,35 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; +import Panel from '../widget/panel'; + +@observer +export default class RightArea extends Component<{ area: Area<any, Panel> }> { + shouldComponentUpdate() { + return false; + } + render() { + const { area } = this.props; + return ( + <div className={classNames('lc-right-area', { + 'lc-area-visible': area.visible, + })}> + <Contents area={area} /> + </div> + ); + } +} + + +@observer +class Contents extends Component<{ area: Area<any, Panel> }> { + render() { + const { area } = this.props; + return ( + <Fragment> + {area.container.items.map((item) => item.content)} + </Fragment> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/theme.less b/packages/editor-skeleton/src/layouts/theme.less similarity index 100% rename from packages/vision-polyfill/src/skeleton/theme.less rename to packages/editor-skeleton/src/layouts/theme.less diff --git a/packages/editor-skeleton/src/layouts/toolbar.tsx b/packages/editor-skeleton/src/layouts/toolbar.tsx new file mode 100644 index 000000000..c266203c8 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/toolbar.tsx @@ -0,0 +1,49 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; + +@observer +export default class Toolbar extends Component<{ area: Area }> { + render() { + const { area } = this.props; + if (area.isEmpty()) { + return null; + } + return ( + <div + className={classNames('lc-toolbar', { + 'lc-area-visible': area.visible, + })} + > + <Contents area={area} /> + </div> + ); + } +} + +@observer +class Contents extends Component<{ area: Area }> { + render() { + const { area } = this.props; + const left: any[] = []; + const center: any[] = []; + const right: any[] = []; + area.container.items.forEach((item) => { + if (item.align === 'center') { + center.push(item.content); + } else if (item.align === 'right') { + right.push(item.content); + } else { + left.push(item.content); + } + }); + return ( + <Fragment> + <div className="lc-toolbar-left">{left}</div> + <div className="lc-toolbar-center">{center}</div> + <div className="lc-toolbar-right">{right}</div> + </Fragment> + ); + } +} diff --git a/packages/editor-skeleton/src/layouts/top-area.tsx b/packages/editor-skeleton/src/layouts/top-area.tsx new file mode 100644 index 000000000..532fc1fef --- /dev/null +++ b/packages/editor-skeleton/src/layouts/top-area.tsx @@ -0,0 +1,44 @@ +import { Component, Fragment } from 'react'; +import classNames from 'classnames'; +import { observer } from '@ali/lowcode-editor-core'; +import Area from '../area'; + +@observer +export default class TopArea extends Component<{ area: Area }> { + render() { + const { area } = this.props; + return ( + <div className={classNames("lc-top-area", { + 'lc-area-visible': area.visible + })}> + <Contents area={area} /> + </div> + ); + } +} + +@observer +class Contents extends Component<{ area: Area }> { + render() { + const { area } = this.props; + const left: any[] = []; + const center: any[] = []; + const right: any[] = []; + area.container.items.forEach(item => { + if (item.align === 'center') { + center.push(item.content); + } else if (item.align === 'left') { + left.push(item.content); + } else { + right.push(item.content); + } + }); + return ( + <Fragment> + <div className="lc-top-area-left">{left}</div> + <div className="lc-top-area-center">{center}</div> + <div className="lc-top-area-right">{right}</div> + </Fragment> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/workbench.less b/packages/editor-skeleton/src/layouts/workbench.less similarity index 100% rename from packages/vision-polyfill/src/skeleton/workbench.less rename to packages/editor-skeleton/src/layouts/workbench.less diff --git a/packages/editor-skeleton/src/layouts/workbench.tsx b/packages/editor-skeleton/src/layouts/workbench.tsx new file mode 100644 index 000000000..857fb8540 --- /dev/null +++ b/packages/editor-skeleton/src/layouts/workbench.tsx @@ -0,0 +1,40 @@ +import { Component } from 'react'; +import { TipContainer, observer } from '@ali/lowcode-editor-core'; +import { Skeleton } from '../skeleton'; +import TopArea from './top-area'; +import LeftArea from './left-area'; +import LeftFixedPane from './left-fixed-pane'; +import LeftFloatPane from './left-float-pane'; +import Toolbar from './toolbar'; +import MainArea from './main-area'; +import BottomArea from './bottom-area'; +import RightArea from './right-area'; +import './workbench.less'; + +@observer +export class Workbench extends Component<{ skeleton: Skeleton}> { + shouldComponentUpdate() { + return false; + } + + render() { + const { skeleton } = this.props; + return ( + <div className="lc-workbench"> + <TopArea area={skeleton.topArea} /> + <div className="lc-workbench-body"> + <LeftArea area={skeleton.leftArea} /> + <LeftFloatPane area={skeleton.leftFloatArea} /> + <LeftFixedPane area={skeleton.leftFixedArea} /> + <div className="lc-workbench-center"> + <Toolbar area={skeleton.toolbar} /> + <MainArea area={skeleton.mainArea} /> + <BottomArea area={skeleton.bottomArea} /> + </div> + <RightArea area={skeleton.rightArea} /> + </div> + <TipContainer /> + </div> + ); + } +} diff --git a/packages/editor-skeleton/src/locale/en-US.js b/packages/editor-skeleton/src/locale/en-US.js deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/locale/en-US.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/locale/ja-JP.js b/packages/editor-skeleton/src/locale/ja-JP.js deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/locale/ja-JP.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/locale/zh-CN.js b/packages/editor-skeleton/src/locale/zh-CN.js deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/locale/zh-CN.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/locale/zh-TW.js b/packages/editor-skeleton/src/locale/zh-TW.js deleted file mode 100644 index ff8b4c563..000000000 --- a/packages/editor-skeleton/src/locale/zh-TW.js +++ /dev/null @@ -1 +0,0 @@ -export default {}; diff --git a/packages/editor-skeleton/src/panel.ts b/packages/editor-skeleton/src/panel.ts new file mode 100644 index 000000000..fd8a5de46 --- /dev/null +++ b/packages/editor-skeleton/src/panel.ts @@ -0,0 +1,166 @@ +import { createElement, ReactNode } from 'react'; +import { TitleContent } from '@ali/lowcode-types'; +import { uniqueId, createContent } from '@ali/lowcode-utils'; +import { obx } from '@ali/lowcode-editor-core'; +import WidgetContainer from './widget/widget-container'; +import { PanelConfig, HelpTipConfig } from './types'; +import { TitledPanelView, TabsPanelView, PanelView } from './components/widget-views'; +import { Skeleton } from './skeleton'; +import { composeTitle } from './widget/utils'; +import { IWidget } from './widget/widget'; + +export default class Panel implements IWidget { + readonly isWidget = true; + readonly name: string; + readonly id: string; + @obx.ref inited: boolean = false; + @obx.ref private _actived: boolean = false; + get actived(): boolean { + return this._actived; + } + + get visible(): boolean { + if (this.parent?.visible) { + return this._actived; + } + return false; + } + + readonly isPanel = true; + + private _body?: ReactNode; + get body() { + this.initBody(); + return this._body; + } + + get content(): ReactNode { + if (this.plain) { + return createElement(PanelView, { + panel: this, + key: this.id, + }); + } + return createElement(TitledPanelView, { panel: this, key: this.id }); + } + + readonly title: TitleContent; + readonly help?: HelpTipConfig; + private plain: boolean = false; + + private container?: WidgetContainer<Panel, PanelConfig>; + private parent?: WidgetContainer; + + constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { + const { name, content, props = {} } = config; + const { hideTitleBar, title, icon, description, help, shortcut } = props; + this.name = name; + this.id = uniqueId(`pane:${name}$`); + this.title = composeTitle(title || name, icon, description); + this.plain = hideTitleBar || !title; + this.help = help; + if (Array.isArray(content)) { + this.container = this.skeleton.createContainer( + name, + (item) => { + if (isPanel(item)) { + return item; + } + return this.skeleton.createPanel(item); + }, + true, + () => this.visible, + true, + ); + content.forEach((item) => this.add(item)); + } + // todo: process shortcut + } + + private initBody() { + if (this.inited) { + return; + } + this.inited = true; + if (this.container) { + this._body = createElement(TabsPanelView, { + container: this.container, + }); + } else { + const { content, contentProps } = this.config; + this._body = createContent(content, { + ...contentProps, + editor: this.skeleton.editor, + config: this.config, + panel: this, + }); + } + } + + setParent(parent: WidgetContainer) { + if (parent === this.parent) { + return; + } + if (this.parent) { + this.parent.remove(this); + } + this.parent = parent; + } + + add(item: Panel | PanelConfig) { + return this.container?.add(item); + } + + getPane(name: string): Panel | null { + return this.container?.get(name) || null; + } + + remove(item: Panel | string) { + return this.container?.remove(item); + } + + active(item?: Panel | string | null) { + this.container?.active(item); + } + + getName() { + return this.name; + } + + getContent() { + return this.content; + } + + setActive(flag: boolean) { + if (flag === this._actived) { + // TODO: 如果移动到另外一个 container,会有问题 + return; + } + if (flag) { + if (!this.inited) { + this.initBody(); + } + this._actived = true; + this.parent?.active(this); + } else if (this.inited) { + this._actived = false; + this.parent?.unactive(this); + } + } + + toggle() { + this.setActive(!this._actived); + } + + hide() { + this.setActive(false); + } + + show() { + this.setActive(true); + } +} + +export function isPanel(obj: any): obj is Panel { + return obj && obj.isPanel; +} diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts new file mode 100644 index 000000000..2dcf9470a --- /dev/null +++ b/packages/editor-skeleton/src/skeleton.ts @@ -0,0 +1,318 @@ +import { Editor } from '@ali/lowcode-editor-core'; +import { + DockConfig, + PanelConfig, + WidgetConfig, + IWidgetBaseConfig, + PanelDockConfig, + DialogDockConfig, + isDockConfig, + isPanelDockConfig, + isPanelConfig, + DividerConfig, + isDividerConfig +} from './types'; +import Panel, { isPanel } from './widget/panel'; +import WidgetContainer from './widget/widget-container'; +import Area from './area'; +import Widget, { isWidget, IWidget } from './widget/widget'; +import PanelDock from './widget/panel-dock'; +import Dock from './widget/dock'; +import { Stage, StageConfig } from './widget/stage'; +import { isValidElement } from 'react'; +import { isPlainObject } from '@ali/lowcode-utils'; +import { Divider } from '@alifd/next'; + +export enum SkeletonEvents { + PANEL_DOCK_ACTIVE = 'skeleton.panel-dock.active', + PANEL_DOCK_UNACTIVE = 'skeleton.panel-dock.unactive', + PANEL_SHOW = 'skeleton.panel.show', + PANEL_HIDE = 'skeleton.panel.hide', + WIDGET_SHOW = 'skeleton.widget.show', + WIDGET_HIDE = 'skeleton.widget.hide', +} + +export class Skeleton { + private panels = new Map<string, Panel>(); + private containers = new Map<string, WidgetContainer<any>>(); + readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; + readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; + readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; + readonly leftFixedArea: Area<PanelConfig, Panel>; + readonly leftFloatArea: Area<PanelConfig, Panel>; + readonly rightArea: Area<PanelConfig, Panel>; + readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>; + readonly bottomArea: Area<PanelConfig, Panel>; + readonly stages: Area<StageConfig, Stage>; + + constructor(readonly editor: Editor) { + this.leftArea = new Area( + this, + 'leftArea', + (config) => { + if (isWidget(config)) { + return config; + } + return this.createWidget(config); + }, + false, + ); + this.topArea = new Area( + this, + 'topArea', + (config) => { + if (isWidget(config)) { + return config; + } + return this.createWidget(config); + }, + false, + ); + this.toolbar = new Area( + this, + 'toolbar', + (config) => { + if (isWidget(config)) { + return config; + } + return this.createWidget(config); + }, + false, + ); + this.leftFixedArea = new Area( + this, + 'leftFixedArea', + (config) => { + if (isPanel(config)) { + return config; + } + return this.createPanel(config); + }, + true, + ); + this.leftFloatArea = new Area( + this, + 'leftFloatArea', + (config) => { + if (isPanel(config)) { + return config; + } + return this.createPanel(config); + }, + true, + ); + this.rightArea = new Area( + this, + 'rightArea', + (config) => { + if (isPanel(config)) { + return config; + } + return this.createPanel(config); + }, + true, + true, + ); + this.mainArea = new Area( + this, + 'mainArea', + (config) => { + if (isWidget(config)) { + return config as Widget; + } + return this.createWidget(config) as Widget; + }, + true, + true, + ); + this.bottomArea = new Area( + this, + 'bottomArea', + (config) => { + if (isPanel(config)) { + return config; + } + return this.createPanel(config); + }, + true, + ); + this.stages = new Area(this, 'stages', (config) => { + if (isWidget(config)) { + return config; + } + return new Stage(this, config); + }); + + this.setupPlugins(); + } + + private setupPlugins() { + const { config, components: componentsMap } = this.editor; + const { plugins } = config; + if (!plugins) { + return; + } + Object.keys(plugins).forEach((area) => { + plugins[area].forEach((item) => { + const { pluginKey, type, props = {}, pluginProps } = item; + const config: any = { + area, + type: 'Widget', + name: pluginKey, + contentProps: pluginProps, + }; + const { dialogProps, balloonProps, panelProps, linkProps, ...restProps } = props; + config.props = restProps; + if (dialogProps) { + config.dialogProps = dialogProps; + } + if (balloonProps) { + config.balloonProps = balloonProps; + } + if (panelProps) { + config.panelProps = panelProps; + } + if (linkProps) { + config.linkProps = linkProps; + } + if (type === 'TabPanel') { + config.type = 'Panel'; + } else if (/Icon$/.test(type)) { + config.type = type.replace('Icon', 'Dock'); + } + if (pluginKey in componentsMap) { + config.content = componentsMap[pluginKey]; + } + this.add(config); + }); + }); + } + + postEvent(event: SkeletonEvents, ...args: any[]) { + this.editor.emit(event, ...args); + } + + createWidget(config: IWidgetBaseConfig | IWidget) { + if (isWidget(config)) { + return config; + } + + config = this.parseConfig(config); + let widget: IWidget; + if (isDockConfig(config)) { + if (isPanelDockConfig(config)) { + widget = new PanelDock(this, config); + } else if (false) { + // DialogDock + // others... + } else { + + widget = new Dock(this, config); + } + } else if (isDividerConfig(config)) { + widget = new Widget(this, { + ...config, + type: 'Widget', + content: Divider, + }); + } else if (isPanelConfig(config)) { + widget = this.createPanel(config); + } else { + widget = new Widget(this, config as WidgetConfig); + } + return widget; + } + + createPanel(config: PanelConfig) { + config = this.parseConfig(config); + const panel = new Panel(this, config); + this.panels.set(panel.name, panel); + return panel; + } + + getPanel(name: string): Panel | undefined { + return this.panels.get(name); + } + + createContainer( + name: string, + handle: (item: any) => any, + exclusive = false, + checkVisible: () => boolean = () => true, + defaultSetCurrent = false, + ) { + const container = new WidgetContainer(name, handle, exclusive, checkVisible, defaultSetCurrent); + this.containers.set(name, container); + return container; + } + + private parseConfig(config: IWidgetBaseConfig): any { + if ((config as any).parsed) { + return config; + } + const { content, ...restConfig } = config; + if (content) { + if (isPlainObject(content) && !isValidElement(content)) { + Object.keys(content).forEach((key) => { + if (/props$/i.test(key) && restConfig[key]) { + restConfig[key] = { + ...restConfig[key], + ...content[key], + }; + } else { + restConfig[key] = content[key]; + } + }); + } else { + restConfig.content = content; + } + } + restConfig.pluginKey = restConfig.name; + restConfig.parsed = true; + return restConfig; + } + + add(config: IWidgetBaseConfig & { area?: string }, extraConfig?: object) { + const parsedConfig: any = { + ...this.parseConfig(config), + ...extraConfig, + }; + let { area } = parsedConfig; + if (!area) { + if (parsedConfig.type === 'Panel') { + area = 'leftFloatArea' + } else if (parsedConfig.type === 'Widget') { + area = 'mainArea'; + } else { + area = 'leftArea'; + } + } + switch (area) { + case 'leftArea': + case 'left': + return this.leftArea.add(parsedConfig); + case 'rightArea': + case 'right': + return this.rightArea.add(parsedConfig); + case 'topArea': + case 'top': + return this.topArea.add(parsedConfig); + case 'toolbar': + return this.toolbar.add(parsedConfig); + case 'mainArea': + case 'main': + case 'center': + case 'centerArea': + return this.mainArea.add(parsedConfig); + case 'bottomArea': + case 'bottom': + return this.bottomArea.add(parsedConfig); + case 'leftFixedArea': + return this.leftFixedArea.add(parsedConfig); + case 'leftFloatArea': + return this.leftFloatArea.add(parsedConfig); + case 'stages': + return this.stages.add(parsedConfig); + } + } +} diff --git a/packages/editor-skeleton/src/skeleton.tsx b/packages/editor-skeleton/src/skeleton.tsx deleted file mode 100644 index ddcd842a0..000000000 --- a/packages/editor-skeleton/src/skeleton.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import React, { PureComponent } from 'react'; - -import { Loading, ConfigProvider } from '@alifd/next'; -import { HashRouter as Router, Route } from 'react-router-dom'; -import Editor, { utils } from '@ali/lowcode-editor-core'; -import { - EditorConfig, - Utils, - PluginClassSet, -} from '@ali/lowcode-editor-core/lib/definitions'; -import defaultConfig from './config/skeleton'; -import skeletonUtils from './config/utils'; - -import TopArea from './layouts/TopArea'; -import LeftArea from './layouts/LeftArea'; -import CenterArea from './layouts/CenterArea'; -import RightArea from './layouts/RightArea'; -import './global.scss'; - -const { comboEditorConfig, parseSearch } = utils; - -let renderIdx = 0; - -declare global { - interface Window { - __ctx: { - editor: Editor; - appHelper: Editor; - }; - } -} - -export interface SkeletonProps { - components?: PluginClassSet; - config?: EditorConfig; - history?: object; - location?: object; - match?: object; - utils?: Utils; - editor?: Editor; -} - -export interface SkeletonState { - initReady?: boolean; - skeletonKey?: string; - __hasError?: boolean; -} - -export class Skeleton extends PureComponent<SkeletonProps, SkeletonState> { - static displayName = 'LowcodeEditorSkeleton'; - - static getDerivedStateFromError(): SkeletonState { - return { - __hasError: true, - }; - } - - private editor: Editor; - - constructor(props) { - super(props); - - this.state = { - initReady: false, - skeletonKey: `skeleton${renderIdx}`, - }; - - this.init(); - } - - componentWillUnmount(): void { - this.editor && this.editor.destroy(); - } - - componentDidCatch(err): void { - console.error(err); - } - - init = (isReset: boolean = false): void => { - if (this.editor) { - this.editor.destroy(); - } - const { utils, config, components, editor } = this.props; - if (!editor) { - this.editor = new Editor( - comboEditorConfig(defaultConfig, config), - components, - { - ...skeletonUtils, - ...utils, - }, - ); - this.editor.once('editor.reset', (): void => { - this.setState({ - initReady: false, - }); - this.editor.emit('editor.beforeReset'); - this.init(true); - }); - } else { - this.editor = editor; - } - - // eslint-disable-next-line no-underscore-dangle - window.__ctx = { - editor: this.editor, - appHelper: this.editor, - }; - this.editor.init().then((): void => { - this.setState( - { - initReady: true, - // 刷新IDE时生成新的skeletonKey保证插件生命周期重新执行 - skeletonKey: isReset - ? `skeleton${++renderIdx}` - : this.state.skeletonKey, - }, - (): void => { - editor.emit('editor.ready'); - isReset && editor.emit('editor.afterReset'); - }, - ); - }); - }; - - render(): React.ReactNode { - const { initReady, skeletonKey, __hasError } = this.state; - const { location, history, match } = this.props; - if (__hasError || !this.editor) { - return 'error'; - } - - location.query = parseSearch(location.search); - this.editor.set('location', location); - this.editor.set('history', history); - this.editor.set('match', match); - - return ( - <ConfigProvider> - <Loading tip="Loading" size="large" visible={!initReady} fullScreen> - <div className="lowcode-editor" key={skeletonKey}> - <TopArea editor={this.editor} /> - <div className="lowcode-main-content"> - <LeftArea.Nav editor={this.editor} /> - <LeftArea.Panel editor={this.editor} /> - <CenterArea editor={this.editor} /> - <RightArea editor={this.editor} /> - </div> - </div> - </Loading> - </ConfigProvider> - ); - } -} - -// 通过React-Router包裹,支持编辑器内页面根据路由切换 -export interface SkeletonWithRouterProps { - components?: PluginClassSet; - config?: EditorConfig; - utils?: Utils; - editor?: Editor; -} - -const SkeletonWithRouter: React.FC<SkeletonWithRouterProps> = ( - props, -): React.ReactElement => { - const { config, ...otherProps } = props; - return ( - <Router> - <Route - path="/*" - component={routerProps => ( - <Skeleton - {...routerProps} - {...otherProps} - {...(config && config.skeleton && config.skeleton.props)} - config={config} - /> - )} - /> - </Router> - ); -}; - -export default SkeletonWithRouter; diff --git a/packages/editor-skeleton/src/types.ts b/packages/editor-skeleton/src/types.ts new file mode 100644 index 000000000..09c669985 --- /dev/null +++ b/packages/editor-skeleton/src/types.ts @@ -0,0 +1,114 @@ +import { ReactElement, ComponentType } from 'react'; +import { TitleContent, IconType, I18nData, TipContent } from '@ali/lowcode-types'; + +export interface IWidgetBaseConfig { + type: string; + name: string; + area?: string; // 停靠位置, 默认 float, 如果添加非固定区, + props?: object; + content?: any; + contentProps?: object; + // index?: number; + [extra: string]: any; +} + +export interface WidgetConfig extends IWidgetBaseConfig { + type: "Widget"; + props?: { + align?: "left" | "right" | "bottom" | "center" | "top"; + }; + content?: string | ReactElement | ComponentType<any>; // children +} + +export function isWidgetConfig(obj: any): obj is WidgetConfig { + return obj && obj.type === "Widget"; +} + +export interface DockProps { + title?: TitleContent; + icon?: IconType; + size?: 'small' | 'medium' | 'large'; + className?: string; + description?: TipContent; + onClick?: () => void; +} + +export interface DividerConfig extends IWidgetBaseConfig { + type: "Divider"; + props?: { + align?: "left" | "right" | "center"; + }; +} + +export function isDividerConfig(obj: any): obj is DividerConfig { + return obj && obj.type === "Divider"; +} + +export interface IDockBaseConfig extends IWidgetBaseConfig { + props?: DockProps & { + align?: "left" | "right" | "bottom" | "center" | "top"; + }; +} + +export interface DockConfig extends IDockBaseConfig { + type: "Dock"; + content?: string | ReactElement | ComponentType<any>; +} + +export function isDockConfig(obj: any): obj is DockConfig { + return obj && /Dock$/.test(obj.type); +} + +// 按钮弹窗扩展 +export interface DialogDockConfig extends IDockBaseConfig { + type: "DialogDock"; + dialogProps?: { + title?: TitleContent; + [key: string]: any; + }; +} + +export function isDialogDockConfig(obj: any): obj is DialogDockConfig { + return obj && obj.type === 'DialogDock'; +} + +// 窗格扩展 +export interface PanelConfig extends IWidgetBaseConfig { + type: "Panel"; + content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // as children + props?: PanelProps; +} + +export function isPanelConfig(obj: any): obj is PanelConfig { + return obj && obj.type === 'Panel'; +} + +export type HelpTipConfig = string | { url?: string; content?: string | ReactElement }; + +export interface PanelProps { + title?: TitleContent; + icon?: any; // 冗余字段 + description?: string | I18nData; + hideTitleBar?: boolean; // panel.props 兼容,不暴露 + help?: HelpTipConfig; // 显示问号帮助 + width?: number; // panel.props + height?: number; // panel.props + maxWidth?: number; // panel.props + maxHeight?: number; // panel.props + onInit?: () => any; + onDestroy?: () => any; + shortcut?: string; // 只有在特定位置,可触发 toggle show +} + +export interface PanelDockConfig extends IDockBaseConfig { + type: "PanelDock"; + panelName?: string; + panelProps?: PanelProps & { + area?: string; + }; + content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // content for pane +} + +export function isPanelDockConfig(obj: any): obj is PanelDockConfig { + return obj && obj.type === 'PanelDock'; +} diff --git a/packages/vision-polyfill/src/skeleton/dialog-dock.ts b/packages/editor-skeleton/src/widget/dialog-dock.ts similarity index 100% rename from packages/vision-polyfill/src/skeleton/dialog-dock.ts rename to packages/editor-skeleton/src/widget/dialog-dock.ts diff --git a/packages/editor-skeleton/src/widget/dock.ts b/packages/editor-skeleton/src/widget/dock.ts new file mode 100644 index 000000000..c63bbdc2c --- /dev/null +++ b/packages/editor-skeleton/src/widget/dock.ts @@ -0,0 +1,87 @@ +import { ReactNode, createElement } from 'react'; +import { obx } from '@ali/lowcode-editor-core'; +import { uniqueId, createContent } from '@ali/lowcode-utils'; +import { DockConfig } from '../types'; +import { Skeleton } from '../skeleton'; +import { DockView, WidgetView } from '../components/widget-views'; +import { IWidget } from './widget'; + +/** + * 带图标(主要)/标题(次要)的扩展 + */ +export default class Dock implements IWidget { + readonly isWidget = true; + readonly id = uniqueId('dock'); + readonly name: string; + readonly align?: string; + + @obx.ref private _visible: boolean = true; + get visible(): boolean { + return this._visible; + } + + get content(): ReactNode { + return createElement(WidgetView, { + widget: this, + key: this.id, + }); + } + + private inited: boolean = false; + private _body: ReactNode; + get body() { + if (this.inited) { + return this._body; + } + + const { props, content, contentProps } = this.config; + + if (content) { + this._body = createContent(content, { + ...contentProps, + config: this.config, + editor: this.skeleton.editor, + }); + } else { + this._body = createElement(DockView, props); + } + return this._body; + } + + constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { + const { props = {}, name } = config; + this.name = name; + this.align = props.align; + } + + setVisible(flag: boolean) { + if (flag === this._visible) { + return; + } + if (flag) { + this._visible = true; + } else if (this.inited) { + this._visible = false; + } + } + + getContent() { + return this.content; + } + + getName() { + return this.name; + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } + + toggle() { + this.setVisible(!this._visible); + } +} diff --git a/packages/editor-skeleton/src/widget/panel-dock.ts b/packages/editor-skeleton/src/widget/panel-dock.ts new file mode 100644 index 000000000..7b06882fe --- /dev/null +++ b/packages/editor-skeleton/src/widget/panel-dock.ts @@ -0,0 +1,118 @@ +import { obx, computed } from '@ali/lowcode-editor-core'; +import { uniqueId } from '@ali/lowcode-utils'; +import { createElement, ReactNode } from 'react'; +import { Skeleton } from '../skeleton'; +import { PanelDockConfig } from '../types'; +import Panel from './panel'; +import { PanelDockView, WidgetView } from '../components/widget-views'; +import { IWidget } from './widget'; + +export default class PanelDock implements IWidget { + readonly isWidget = true; + readonly id: string; + readonly name: string; + readonly align?: string; + + private inited: boolean = false; + private _body: ReactNode; + get body() { + if (this.inited) { + return this._body; + } + this.inited = true; + const { props } = this.config; + + this._body = createElement(PanelDockView, { + ...props, + dock: this, + }); + + return this._body; + } + + get content(): ReactNode { + return createElement(WidgetView, { + widget: this, + key: this.id, + }); + } + + @obx.ref private _visible: boolean = true; + get visible() { + return this._visible; + } + + @computed get actived(): boolean { + return this.panel?.visible || false; + } + + readonly panelName: string; + private _panel?: Panel; + @computed get panel() { + return this._panel || this.skeleton.getPanel(this.panelName); + } + + constructor(readonly skeleton: Skeleton, readonly config: PanelDockConfig) { + const { content, contentProps, panelProps, name, props } = config; + this.name = name; + this.id = uniqueId(`dock:${name}$`); + this.panelName = config.panelName || name; + if (content) { + this._panel = this.skeleton.add({ + type: "Panel", + name: this.panelName, + props: { + // FIXME! give default title for panel + // title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '', + ...panelProps, + }, + contentProps, + content, + area: panelProps?.area + }) as Panel; + } + } + + setVisible(flag: boolean) { + if (flag === this._visible) { + return; + } + if (flag) { + this._visible = true; + } else if (this.inited) { + this._visible = false; + } + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } + + toggle() { + this.setVisible(!this._visible); + } + + togglePanel() { + this.panel?.toggle(); + } + + getName() { + return this.name; + } + + getContent() { + return this.content; + } + + hidePanel() { + this.panel?.setActive(false); + } + + showPanel() { + this.panel?.setActive(true); + } +} diff --git a/packages/editor-skeleton/src/widget/panel.ts b/packages/editor-skeleton/src/widget/panel.ts new file mode 100644 index 000000000..f75e69a3d --- /dev/null +++ b/packages/editor-skeleton/src/widget/panel.ts @@ -0,0 +1,166 @@ +import { createElement, ReactNode } from 'react'; +import { obx } from '@ali/lowcode-editor-core'; +import { uniqueId, createContent } from '@ali/lowcode-utils'; +import { TitleContent } from '@ali/lowcode-types'; +import WidgetContainer from './widget-container'; +import { PanelConfig, HelpTipConfig } from '../types'; +import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views'; +import { Skeleton } from '../skeleton'; +import { composeTitle } from './utils'; +import { IWidget } from './widget'; + +export default class Panel implements IWidget { + readonly isWidget = true; + readonly name: string; + readonly id: string; + @obx.ref inited: boolean = false; + @obx.ref private _actived: boolean = false; + get actived(): boolean { + return this._actived; + } + + get visible(): boolean { + if (this.parent?.visible) { + return this._actived; + } + return false; + } + + readonly isPanel = true; + + private _body?: ReactNode; + get body() { + this.initBody(); + return this._body; + } + + get content(): ReactNode { + if (this.plain) { + return createElement(PanelView, { + panel: this, + key: this.id, + }); + } + return createElement(TitledPanelView, { panel: this, key: this.id }); + } + + readonly title: TitleContent; + readonly help?: HelpTipConfig; + private plain: boolean = false; + + private container?: WidgetContainer<Panel, PanelConfig>; + private parent?: WidgetContainer; + + constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { + const { name, content, props = {} } = config; + const { hideTitleBar, title, icon, description, help, shortcut } = props; + this.name = name; + this.id = uniqueId(`pane:${name}$`); + this.title = composeTitle(title || name, icon, description); + this.plain = hideTitleBar || !title; + this.help = help; + if (Array.isArray(content)) { + this.container = this.skeleton.createContainer( + name, + (item) => { + if (isPanel(item)) { + return item; + } + return this.skeleton.createPanel(item); + }, + true, + () => this.visible, + true, + ); + content.forEach((item) => this.add(item)); + } + // todo: process shortcut + } + + private initBody() { + if (this.inited) { + return; + } + this.inited = true; + if (this.container) { + this._body = createElement(TabsPanelView, { + container: this.container, + }); + } else { + const { content, contentProps } = this.config; + this._body = createContent(content, { + ...contentProps, + editor: this.skeleton.editor, + config: this.config, + panel: this, + }); + } + } + + setParent(parent: WidgetContainer) { + if (parent === this.parent) { + return; + } + if (this.parent) { + this.parent.remove(this); + } + this.parent = parent; + } + + add(item: Panel | PanelConfig) { + return this.container?.add(item); + } + + getPane(name: string): Panel | null { + return this.container?.get(name) || null; + } + + remove(item: Panel | string) { + return this.container?.remove(item); + } + + active(item?: Panel | string | null) { + this.container?.active(item); + } + + getName() { + return this.name; + } + + getContent() { + return this.content; + } + + setActive(flag: boolean) { + if (flag === this._actived) { + // TODO: 如果移动到另外一个 container,会有问题 + return; + } + if (flag) { + if (!this.inited) { + this.initBody(); + } + this._actived = true; + this.parent?.active(this); + } else if (this.inited) { + this._actived = false; + this.parent?.unactive(this); + } + } + + toggle() { + this.setActive(!this._actived); + } + + hide() { + this.setActive(false); + } + + show() { + this.setActive(true); + } +} + +export function isPanel(obj: any): obj is Panel { + return obj && obj.isPanel; +} diff --git a/packages/vision-polyfill/src/skeleton/stage.ts b/packages/editor-skeleton/src/widget/stage.ts similarity index 92% rename from packages/vision-polyfill/src/skeleton/stage.ts rename to packages/editor-skeleton/src/widget/stage.ts index f5c59a557..a4bf483f2 100644 --- a/packages/vision-polyfill/src/skeleton/stage.ts +++ b/packages/editor-skeleton/src/widget/stage.ts @@ -1,6 +1,6 @@ import Widget from './widget'; -import { Skeleton } from './skeleton'; -import { WidgetConfig } from './types'; +import { Skeleton } from '../skeleton'; +import { WidgetConfig } from '../types'; export interface StageConfig extends WidgetConfig { isRoot?: boolean; diff --git a/packages/vision-polyfill/src/skeleton/utils.ts b/packages/editor-skeleton/src/widget/utils.ts similarity index 100% rename from packages/vision-polyfill/src/skeleton/utils.ts rename to packages/editor-skeleton/src/widget/utils.ts diff --git a/packages/vision-polyfill/src/skeleton/widget-container.ts b/packages/editor-skeleton/src/widget/widget-container.ts similarity index 100% rename from packages/vision-polyfill/src/skeleton/widget-container.ts rename to packages/editor-skeleton/src/widget/widget-container.ts diff --git a/packages/editor-skeleton/src/widget/widget.ts b/packages/editor-skeleton/src/widget/widget.ts new file mode 100644 index 000000000..91bd90344 --- /dev/null +++ b/packages/editor-skeleton/src/widget/widget.ts @@ -0,0 +1,101 @@ +import { ReactNode, createElement } from 'react'; +import { obx } from '@ali/lowcode-editor-core'; +import { createContent, uniqueId } from '@ali/lowcode-utils'; +import { WidgetConfig, IWidgetBaseConfig } from '../types'; +import { Skeleton } from '../skeleton'; +import { WidgetView } from '../components/widget-views'; + +export interface IWidget { + readonly name: string; + readonly content: ReactNode; + readonly align?: string; + readonly isWidget: true; + readonly visible: boolean; + readonly body: ReactNode; + readonly skeleton: Skeleton; + readonly config: IWidgetBaseConfig; + + getName(): string; + getContent(): any; + show(): void; + hide(): void; + toggle(): void; +} + +export default class Widget implements IWidget { + readonly isWidget = true; + readonly id = uniqueId('widget'); + readonly name: string; + readonly align?: string; + + @obx.ref private _visible: boolean = true; + get visible(): boolean { + return this._visible; + } + + @obx.ref inited: boolean = false; + private _body: ReactNode; + get body() { + if (this.inited) { + return this._body; + } + this.inited = true; + const { content, contentProps } = this.config; + this._body = createContent(content, { + ...contentProps, + config: this.config, + editor: this.skeleton.editor, + }); + return this._body; + } + + get content(): ReactNode { + return createElement(WidgetView, { + widget: this, + key: this.id, + }); + } + + constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) { + const { props = {}, name } = config; + this.name = name; + this.align = props.align; + } + + getName() { + return this.name; + } + + getContent() { + return this.content; + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } + + setVisible(flag: boolean) { + if (flag === this._visible) { + return; + } + if (flag) { + this._visible = true; + } else if (this.inited) { + this._visible = false; + } + } + + toggle() { + this.setVisible(!this._visible); + } +} + +export function isWidget(obj: any): obj is IWidget { + return obj && obj.isWidget; +} + + diff --git a/packages/globals/CHANGELOG.md b/packages/globals/CHANGELOG.md deleted file mode 100644 index 74216bad2..000000000 --- a/packages/globals/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -<a name="0.9.3"></a> -## [0.9.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.9.2...@ali/lowcode-globals@0.9.3) (2020-04-16) - - - - -**Note:** Version bump only for package @ali/lowcode-globals - -<a name="0.9.2"></a> -## [0.9.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.9.1...@ali/lowcode-globals@0.9.2) (2020-04-15) - - - - -**Note:** Version bump only for package @ali/lowcode-globals - -<a name="0.9.1"></a> -## [0.9.1](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.9.0...@ali/lowcode-globals@0.9.1) (2020-03-31) - - - - -**Note:** Version bump only for package @ali/lowcode-globals - -<a name="0.9.0"></a> -# [0.9.0](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.8.4...@ali/lowcode-globals@0.9.0) (2020-03-30) - - -### Features - -* **designer:** add builtin hotkeys ([2ec5883](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/2ec5883)) - - - - -<a name="0.8.4"></a> -## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.8.3...@ali/lowcode-globals@0.8.4) (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-globals - -<a name="0.8.3"></a> -## [0.8.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-globals@0.8.2...@ali/lowcode-globals@0.8.3) (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-globals - -<a name="0.8.2"></a> -## 0.8.2 (2020-03-30) - - -### Features - -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7)) - - - - -<a name="0.8.1"></a> -## 0.8.1 (2020-03-30) - - -### Features - -<<<<<<< HEAD -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7)) -======= -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7c0c488ef24f825760750a13d3fa083c96)) ->>>>>>> df955e1db90ff104cd11160def80113cfd6faccc diff --git a/packages/globals/README.md b/packages/globals/README.md deleted file mode 100644 index 30c3e7d7d..000000000 --- a/packages/globals/README.md +++ /dev/null @@ -1,3 +0,0 @@ -shared globals - - 发 CDN diff --git a/packages/globals/build.json b/packages/globals/build.json deleted file mode 100644 index e791d5b6b..000000000 --- a/packages/globals/build.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "plugins": [ - "build-plugin-component", - "build-plugin-fusion", - ["build-plugin-moment-locales", { - "locales": ["zh-cn"] - }] - ] -} diff --git a/packages/globals/src/components/tip/embed-tip.tsx b/packages/globals/src/components/tip/embed-tip.tsx deleted file mode 100644 index 290cf2f9a..000000000 --- a/packages/globals/src/components/tip/embed-tip.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { uniqueId } from '../../utils'; -import { Component } from 'react'; -import { saveTips } from './tip-handler'; -import { TipConfig } from '../../types'; - -export default class EmbedTip extends Component<TipConfig> { - private id = uniqueId('tips$'); - - componentWillUnmount() { - saveTips(this.id, null); - } - - render() { - saveTips(this.id, this.props); - return <meta data-role="tip" data-tip-id={this.id} />; - } -} diff --git a/packages/globals/src/components/tip/index.ts b/packages/globals/src/components/tip/index.ts deleted file mode 100644 index ea80c70ac..000000000 --- a/packages/globals/src/components/tip/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import './style.less'; - -export { default as EmbedTip } from './embed-tip'; -export { default as TipContainer } from './tip-container'; diff --git a/packages/globals/src/di/editor.ts b/packages/globals/src/di/editor.ts deleted file mode 100644 index f3f7f2214..000000000 --- a/packages/globals/src/di/editor.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { EventEmitter } from 'events'; -import { RegisterOptions } from 'power-di'; - -export type KeyType = Function | symbol | string; -export type ClassType = Function | (new (...args: any[]) => any); -export interface GetOptions { - forceNew?: boolean; - sourceCls?: ClassType; -} -export type GetReturnType<T, ClsType> = T extends undefined - ? ClsType extends { - prototype: infer R; - } - ? R - : any - : T; - -export interface IEditor extends EventEmitter { - get<T = undefined, KeyOrType = any>(keyOrType: KeyOrType, opt?: GetOptions): GetReturnType<T, KeyOrType> | undefined; - - has(keyOrType: KeyType): boolean; - - set(key: KeyType, data: any): void; - - onceGot<T = undefined, KeyOrType extends KeyType = any>(keyOrType: KeyOrType): Promise<GetReturnType<T, KeyOrType>>; - - onGot<T = undefined, KeyOrType extends KeyType = any>( - keyOrType: KeyOrType, - fn: (data: GetReturnType<T, KeyOrType>) => void, - ): () => void; - - register(data: any, key?: KeyType, options?: RegisterOptions): void; -} diff --git a/packages/globals/src/di/transducer.ts b/packages/globals/src/di/transducer.ts deleted file mode 100644 index 93e079bf7..000000000 --- a/packages/globals/src/di/transducer.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { TransformedComponentMetadata } from '../types'; - -export interface MetadataTransducer { - (prev: TransformedComponentMetadata): TransformedComponentMetadata; - /** - * 0 - 9 system - * 10 - 99 builtin-plugin - * 100 - app & plugin - */ - level?: number; - /** - * use to replace TODO - */ - id?: string; -} -const metadataTransducers: MetadataTransducer[] = []; - -export function registerMetadataTransducer(transducer: MetadataTransducer, level: number = 100, id?: string) { - transducer.level = level; - transducer.id = id; - const i = metadataTransducers.findIndex(item => item.level != null && item.level > level); - if (i < 0) { - metadataTransducers.push(transducer); - } else { - metadataTransducers.splice(i, 0, transducer); - } -} - -export function getRegisteredMetadataTransducers(): MetadataTransducer[] { - return metadataTransducers; -} diff --git a/packages/globals/src/index.ts b/packages/globals/src/index.ts deleted file mode 100644 index 51d80c5da..000000000 --- a/packages/globals/src/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './intl'; -export * from './components'; -export * from './utils'; -export * from './types'; -export * from './di'; -export * from './obx'; diff --git a/packages/plugin-components-pane/src/index.tsx b/packages/plugin-components-pane/src/index.tsx index 24581199f..3dc8ccd5a 100644 --- a/packages/plugin-components-pane/src/index.tsx +++ b/packages/plugin-components-pane/src/index.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import { Icon, Search, Select } from '@alifd/next'; import MaterialShow from '@ali/iceluna-comp-material-show'; -import { PluginProps } from '@ali/lowcode-editor-core'; +import { PluginProps } from '@ali/lowcode-types'; import { Designer } from '@ali/lowcode-designer'; import './index.scss'; diff --git a/packages/plugin-event-bind-dialog/src/index.tsx b/packages/plugin-event-bind-dialog/src/index.tsx index 32cf6e474..4aedba085 100644 --- a/packages/plugin-event-bind-dialog/src/index.tsx +++ b/packages/plugin-event-bind-dialog/src/index.tsx @@ -1,6 +1,6 @@ import { Component, isValidElement, ReactElement, ReactNode } from 'react'; import { Dialog, Search, Input } from '@alifd/next'; -import Editor from '@ali/lowcode-editor-core'; +import { Editor } from '@ali/lowcode-editor-core'; import './index.scss'; export default class EventBindDialog extends Component<{ diff --git a/packages/plugin-outline-pane/src/helper/indent-track.ts b/packages/plugin-outline-pane/src/helper/indent-track.ts index 373b59931..37ed540b8 100644 --- a/packages/plugin-outline-pane/src/helper/indent-track.ts +++ b/packages/plugin-outline-pane/src/helper/indent-track.ts @@ -1,4 +1,4 @@ -import { DropLocation, ParentalNode, isLocationChildrenDetail } from '@ali/lowcode-designer'; +import { DropLocation, ParentalNode, isLocationChildrenDetail, Node } from '@ali/lowcode-designer'; const IndentSensitive = 15; export class IndentTrack { @@ -33,10 +33,10 @@ export class IndentTrack { const index = loc.detail.index; if (direction === 'left') { - if (parent.isSlot() || !parent.parent || index < parent.children.size) { + if (!parent.parent || index < parent.children.size || parent.isSlot()) { return null; } - return [parent.parent, parent.index + 1]; + return [(parent as any).parent, parent.index + 1]; } else { if (index === 0) { return null; diff --git a/packages/plugin-outline-pane/src/icons/arrow-right.tsx b/packages/plugin-outline-pane/src/icons/arrow-right.tsx index 78772d656..1f4562606 100644 --- a/packages/plugin-outline-pane/src/icons/arrow-right.tsx +++ b/packages/plugin-outline-pane/src/icons/arrow-right.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconArrowRight(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/cond.tsx b/packages/plugin-outline-pane/src/icons/cond.tsx index 53ef29295..915efebec 100644 --- a/packages/plugin-outline-pane/src/icons/cond.tsx +++ b/packages/plugin-outline-pane/src/icons/cond.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconCond(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/eye-close.tsx b/packages/plugin-outline-pane/src/icons/eye-close.tsx index 7eb56129e..4502d1f93 100644 --- a/packages/plugin-outline-pane/src/icons/eye-close.tsx +++ b/packages/plugin-outline-pane/src/icons/eye-close.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconEyeClose(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/eye.tsx b/packages/plugin-outline-pane/src/icons/eye.tsx index aa2f16cd5..5490e11a5 100644 --- a/packages/plugin-outline-pane/src/icons/eye.tsx +++ b/packages/plugin-outline-pane/src/icons/eye.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconEye(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/lock.tsx b/packages/plugin-outline-pane/src/icons/lock.tsx index e123741d1..7a12db4a7 100644 --- a/packages/plugin-outline-pane/src/icons/lock.tsx +++ b/packages/plugin-outline-pane/src/icons/lock.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconLock(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/loop.tsx b/packages/plugin-outline-pane/src/icons/loop.tsx index 85b184a32..ba86e1c86 100644 --- a/packages/plugin-outline-pane/src/icons/loop.tsx +++ b/packages/plugin-outline-pane/src/icons/loop.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconLoop(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/outline.tsx b/packages/plugin-outline-pane/src/icons/outline.tsx index 29e0d111b..78658c867 100644 --- a/packages/plugin-outline-pane/src/icons/outline.tsx +++ b/packages/plugin-outline-pane/src/icons/outline.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconOutline(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/slot.tsx b/packages/plugin-outline-pane/src/icons/slot.tsx index 973bd3ecd..ed27e74c7 100644 --- a/packages/plugin-outline-pane/src/icons/slot.tsx +++ b/packages/plugin-outline-pane/src/icons/slot.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconSlot(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/icons/unlock.tsx b/packages/plugin-outline-pane/src/icons/unlock.tsx index 5384822fd..5695db95d 100644 --- a/packages/plugin-outline-pane/src/icons/unlock.tsx +++ b/packages/plugin-outline-pane/src/icons/unlock.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconUnlock(props: IconProps) { return ( diff --git a/packages/plugin-outline-pane/src/locale/index.ts b/packages/plugin-outline-pane/src/locale/index.ts index 913dd42f8..dfd17521f 100644 --- a/packages/plugin-outline-pane/src/locale/index.ts +++ b/packages/plugin-outline-pane/src/locale/index.ts @@ -1,4 +1,4 @@ -import { createIntl } from '@ali/lowcode-globals'; +import { createIntl } from '@ali/lowcode-editor-core'; import en_US from './en-US.json'; import zh_CN from './zh-CN.json'; diff --git a/packages/plugin-outline-pane/src/main.ts b/packages/plugin-outline-pane/src/main.ts index c3c94ce0f..3903f166d 100644 --- a/packages/plugin-outline-pane/src/main.ts +++ b/packages/plugin-outline-pane/src/main.ts @@ -1,4 +1,5 @@ -import { computed, obx, uniqueId } from '@ali/lowcode-globals'; +import { EventEmitter } from 'events'; +import { computed, obx, Editor } from '@ali/lowcode-editor-core'; import { Designer, ISensor, @@ -17,12 +18,11 @@ import { contains, Node, } from '@ali/lowcode-designer'; -import { Editor } from '@ali/lowcode-editor-core'; import { Tree } from './tree'; import TreeNode from './tree-node'; import { IndentTrack } from './helper/indent-track'; import DwellTimer from './helper/dwell-timer'; -import { EventEmitter } from 'events'; +import { uniqueId } from '@ali/lowcode-utils'; export interface IScrollBoard { scrollToNode(treeNode: TreeNode, detail?: any): void; diff --git a/packages/plugin-outline-pane/src/tree-node.ts b/packages/plugin-outline-pane/src/tree-node.ts index c7d5f24d5..e80a51146 100644 --- a/packages/plugin-outline-pane/src/tree-node.ts +++ b/packages/plugin-outline-pane/src/tree-node.ts @@ -1,4 +1,5 @@ -import { computed, obx, TitleContent, isI18nData, localeFormat } from '@ali/lowcode-globals'; +import { TitleContent, isI18nData } from '@ali/lowcode-types'; +import { computed, obx, intl } from '@ali/lowcode-editor-core'; import { Node, DocumentModel, isLocationChildrenDetail, LocationChildrenDetail, Designer } from '@ali/lowcode-designer'; import { Tree } from './tree'; @@ -121,7 +122,7 @@ export default class TreeNode { return title; } if (isI18nData(title)) { - return localeFormat(title); + return intl(title); } return this.node.componentName; } diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index d18e1cfef..f539b51be 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -1,5 +1,5 @@ import React, { Component } from 'react'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import { intl } from '../locale'; import { OutlineMain } from '../main'; import TreeView from './tree'; diff --git a/packages/plugin-outline-pane/src/views/tree-branches.tsx b/packages/plugin-outline-pane/src/views/tree-branches.tsx index 6193652d0..de8308514 100644 --- a/packages/plugin-outline-pane/src/views/tree-branches.tsx +++ b/packages/plugin-outline-pane/src/views/tree-branches.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import classNames from 'classnames'; -import { observer, Title } from '@ali/lowcode-globals'; +import { observer, Title } from '@ali/lowcode-editor-core'; import { ExclusiveGroup } from '@ali/lowcode-designer'; import TreeNode from '../tree-node'; import TreeNodeView from './tree-node'; diff --git a/packages/plugin-outline-pane/src/views/tree-node.tsx b/packages/plugin-outline-pane/src/views/tree-node.tsx index b99d2201e..7688b67c6 100644 --- a/packages/plugin-outline-pane/src/views/tree-node.tsx +++ b/packages/plugin-outline-pane/src/views/tree-node.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; import TreeNode from '../tree-node'; import TreeTitle from './tree-title'; import TreeBranches from './tree-branches'; diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 516314f3c..3d7c6b373 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -1,6 +1,6 @@ import { Component, KeyboardEvent, FocusEvent, Fragment } from 'react'; import classNames from 'classnames'; -import { observer, createIcon, Title, EmbedTip } from '@ali/lowcode-globals'; +import { observer, Title, Tip } from '@ali/lowcode-editor-core'; import { IconArrowRight } from '../icons/arrow-right'; import { IconEyeClose } from '../icons/eye-close'; import { IconLock } from '../icons/lock'; @@ -11,6 +11,7 @@ import { IconEye } from '../icons/eye'; import { IconCond } from '../icons/cond'; import { IconLoop } from '../icons/loop'; import { IconSlot } from '../icons/slot'; +import { createIcon } from '@ali/lowcode-utils'; @observer export default class TreeTitle extends Component<{ @@ -104,21 +105,21 @@ export default class TreeTitle extends Component<{ <a className="tree-node-tag slot"> {/* todo: click redirect to prop */} <IconSlot /> - <EmbedTip>{intl('Slot for {prop}', { prop: node.slotFor.key })}</EmbedTip> + <Tip>{intl('Slot for {prop}', { prop: node.slotFor.key })}</Tip> </a> )} {node.hasLoop() && ( <a className="tree-node-tag loop"> {/* todo: click todo something */} <IconLoop /> - <EmbedTip>{intl('Loop')}</EmbedTip> + <Tip>{intl('Loop')}</Tip> </a> )} {node.hasCondition() && !node.conditionGroup && ( <a className="tree-node-tag cond"> {/* todo: click todo something */} <IconCond /> - <EmbedTip>{intl('Conditional')}</EmbedTip> + <Tip>{intl('Conditional')}</Tip> </a> )} </Fragment> @@ -147,7 +148,7 @@ class LockBtn extends Component<{ treeNode: TreeNode }> { }} > {treeNode.locked ? <IconLock /> : <IconUnlock />} - <EmbedTip>{treeNode.locked ? intl('Unlock') : intl('Lock')}</EmbedTip> + <Tip>{treeNode.locked ? intl('Unlock') : intl('Lock')}</Tip> </div> ); } @@ -169,7 +170,7 @@ class HideBtn extends Component<{ treeNode: TreeNode }> { }} > {treeNode.hidden ? <IconEyeClose /> : <IconEye />} - <EmbedTip>{treeNode.hidden ? intl('Show') : intl('Hide')}</EmbedTip> + <Tip>{treeNode.hidden ? intl('Show') : intl('Hide')}</Tip> </div> ); } diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx index 2ebce693e..04d98c496 100644 --- a/packages/plugin-outline-pane/src/views/tree.tsx +++ b/packages/plugin-outline-pane/src/views/tree.tsx @@ -1,8 +1,9 @@ import { Component, MouseEvent as ReactMouseEvent } from 'react'; -import { observer, isFormEvent } from '@ali/lowcode-globals'; +import { observer } from '@ali/lowcode-editor-core'; +import { isRootNode, Node, DragObjectType, isShaken } from '@ali/lowcode-designer'; +import { isFormEvent } from '@ali/lowcode-utils'; import { Tree } from '../tree'; import TreeNodeView from './tree-node'; -import { isRootNode, Node, DragObjectType, isShaken } from '@ali/lowcode-designer'; function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string { let target: Element | null = e.target as Element; diff --git a/packages/plugin-sample-logo/src/index.tsx b/packages/plugin-sample-logo/src/index.tsx index fdd780e9c..4170481fc 100644 --- a/packages/plugin-sample-logo/src/index.tsx +++ b/packages/plugin-sample-logo/src/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import './index.scss'; -import { PluginProps } from '@ali/lowcode-editor-core'; +import { PluginProps } from '@ali/lowcode-types'; export interface IProps { logo?: string; diff --git a/packages/plugin-sample-preview/src/index.tsx b/packages/plugin-sample-preview/src/index.tsx index cac06d8ca..df10c5466 100644 --- a/packages/plugin-sample-preview/src/index.tsx +++ b/packages/plugin-sample-preview/src/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Button } from '@alifd/next'; -import { PluginProps } from '@ali/lowcode-editor-core'; +import { PluginProps } from '@ali/lowcode-types'; import { Designer } from '@ali/lowcode-designer'; import './index.scss'; diff --git a/packages/plugin-source-editor/src/index.tsx b/packages/plugin-source-editor/src/index.tsx index e90f30e51..9039c2a67 100644 --- a/packages/plugin-source-editor/src/index.tsx +++ b/packages/plugin-source-editor/src/index.tsx @@ -3,7 +3,7 @@ import { Tab, Search, Input, Button } from '@alifd/next'; import Editor from '@ali/lowcode-editor-core'; import { js_beautify, css_beautify } from 'js-beautify'; import MonacoEditor from 'react-monaco-editor'; -import Panel from '../../vision-polyfill/src/skeleton/panel'; +import Panel from '../../vision-polyfill/src/skeleton/widget/panel'; // import lolizer from './sorceEditorPlugin', diff --git a/packages/plugin-variable-bind-dialog/src/index.tsx b/packages/plugin-variable-bind-dialog/src/index.tsx index 4beded5bd..75ee084bd 100644 --- a/packages/plugin-variable-bind-dialog/src/index.tsx +++ b/packages/plugin-variable-bind-dialog/src/index.tsx @@ -1,11 +1,9 @@ -import { Component, isValidElement, ReactElement, ReactNode } from 'react'; -import { Dialog, Search, Input ,Button} from '@alifd/next'; -import Editor from '@ali/lowcode-editor-core'; +import { Component } from 'react'; +import { Dialog, Input, Button } from '@alifd/next'; +import { PluginProps } from '@ali/lowcode-types'; import './index.scss'; -export default class VariableBindDialog extends Component<{ - editor: Editor; -}> { +export default class VariableBindDialog extends Component<PluginProps> { private loopVariableList: any[] = [ { name: 'item', diff --git a/packages/plugin-zh-en/src/index.tsx b/packages/plugin-zh-en/src/index.tsx index 7c44ae362..eebbe37b8 100644 --- a/packages/plugin-zh-en/src/index.tsx +++ b/packages/plugin-zh-en/src/index.tsx @@ -1,6 +1,6 @@ import { PureComponent } from 'react'; -import { globalLocale, EmbedTip } from '@ali/lowcode-globals'; -import { PluginProps } from '@ali/lowcode-editor-core'; +import { globalLocale, Tip } from '@ali/lowcode-editor-core'; +import { PluginProps } from '@ali/lowcode-types'; import { intl } from './locale'; import { IconZh } from './icons/zh'; import { IconEn } from './icons/en'; @@ -29,7 +29,7 @@ export default class ZhEn extends PureComponent<PluginProps> { globalLocale.setLocale(isZh ? 'en-US' : 'zh-CN'); }}> {isZh ? <IconZh size={20} /> : <IconEn size={20} />} - <EmbedTip direction="right">{intl('To Locale')}</EmbedTip> + <Tip direction="right">{intl('To Locale')}</Tip> </div> ); } diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx index 1665889d8..8036d21c7 100644 --- a/packages/react-simulator-renderer/src/renderer-view.tsx +++ b/packages/react-simulator-renderer/src/renderer-view.tsx @@ -2,8 +2,8 @@ import LowCodeRenderer from '@ali/lowcode-react-renderer'; import { ReactInstance, Fragment, Component, createElement } from 'react'; import { observer } from '@recore/obx-react'; import { SimulatorRenderer } from './renderer'; -import './renderer.less'; import { host } from './host'; +import './renderer.less'; export default class SimulatorRendererView extends Component<{ renderer: SimulatorRenderer }> { render() { diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index 9cf819df0..1aa4ba534 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -3,15 +3,13 @@ import { render as reactRender } from 'react-dom'; import { host } from './host'; import SimulatorRendererView from './renderer-view'; import { computed, obx } from '@recore/obx'; -import { Asset, isReactComponent } from '@ali/lowcode-globals'; +import { Asset, isReactComponent } from '@ali/lowcode-utils'; import { getClientRects } from './utils/get-client-rects'; import loader from './utils/loader'; import { reactFindDOMNodes, FIBER_KEY } from './utils/react-find-dom-nodes'; -import { isESModule } from '@ali/lowcode-globals'; -import { isElement } from '@ali/lowcode-globals'; -import { cursor } from '@ali/lowcode-globals'; -import { setNativeSelection } from '@ali/lowcode-globals'; -import { RootSchema, NpmInfo } from '@ali/lowcode-globals'; +import { isESModule, isElement, cursor, setNativeSelection } from '@ali/lowcode-utils'; +import { RootSchema, NpmInfo } from '@ali/lowcode-types'; +// just use types import { BuiltinSimulatorRenderer, NodeInstance } from '@ali/lowcode-designer'; import Slot from './builtin-components/slot'; import Leaf from './builtin-components/leaf'; diff --git a/packages/react-simulator-renderer/src/utils/get-client-rects.ts b/packages/react-simulator-renderer/src/utils/get-client-rects.ts index 8de6b9dd9..f514c0a39 100644 --- a/packages/react-simulator-renderer/src/utils/get-client-rects.ts +++ b/packages/react-simulator-renderer/src/utils/get-client-rects.ts @@ -1,4 +1,4 @@ -import { isElement } from '@ali/lowcode-globals'; +import { isElement } from '@ali/lowcode-utils'; // a range for test TextNode clientRect const cycleRange = document.createRange(); diff --git a/packages/react-simulator-renderer/src/utils/loader.ts b/packages/react-simulator-renderer/src/utils/loader.ts index 8fe87912b..3bba55ba1 100644 --- a/packages/react-simulator-renderer/src/utils/loader.ts +++ b/packages/react-simulator-renderer/src/utils/loader.ts @@ -11,7 +11,7 @@ import { assetItem, AssetItem, isCSSUrl, -} from '@ali/lowcode-globals'; +} from '@ali/lowcode-utils'; function parseAssetList(scripts: any, styles: any, assets: AssetList, level?: AssetLevel) { for (const asset of assets) { diff --git a/packages/react-simulator-renderer/src/utils/react-find-dom-nodes.ts b/packages/react-simulator-renderer/src/utils/react-find-dom-nodes.ts index 38fdd378f..f7dde3925 100644 --- a/packages/react-simulator-renderer/src/utils/react-find-dom-nodes.ts +++ b/packages/react-simulator-renderer/src/utils/react-find-dom-nodes.ts @@ -1,5 +1,5 @@ import { ReactInstance } from 'react'; -import { isElement } from '@ali/lowcode-globals'; +import { isElement } from '@ali/lowcode-utils'; import { isDOMNode } from './is-dom-node'; export const FIBER_KEY = '_reactInternalFiber'; diff --git a/packages/setters/package.json b/packages/setters/package.json index 218fed58d..4f6441d3d 100644 --- a/packages/setters/package.json +++ b/packages/setters/package.json @@ -22,7 +22,7 @@ "@ali/iceluna-comp-react-node": "^1.0.5", "@ali/iceluna-sdk": "^1.0.5-beta.24", "@ali/lc-style-setter": "^0.0.1", - "@ali/lowcode-globals": "^0.9.3", + "@ali/lowcode-editor-core": "^0.9.3", "@alifd/next": "^1.19.16", "acorn": "^6.4.1", "classnames": "^2.2.6", diff --git a/packages/setters/src/index.tsx b/packages/setters/src/index.tsx index 21371311e..90ee52426 100644 --- a/packages/setters/src/index.tsx +++ b/packages/setters/src/index.tsx @@ -1,7 +1,6 @@ import { registerSetter, isJSSlot } from '@ali/lowcode-globals'; import { DatePicker, Input, Radio, Select, Switch, NumberPicker } from '@alifd/next'; import ExpressionSetter from './expression-setter'; -import MixinSetter from './mixin-setter'; import ColorSetter from './color-setter'; import JsonSetter from './json-setter'; import EventsSetter from './events-setter'; @@ -70,7 +69,6 @@ const builtinSetters: any = { }, recommend: true, }, - MixinSetter, RadioGroupSetter, TextAreaSetter, DateSetter, diff --git a/packages/setters/src/mixin-setter/index.tsx b/packages/setters/src/mixin-setter/index.tsx index 843c099af..a77664758 100644 --- a/packages/setters/src/mixin-setter/index.tsx +++ b/packages/setters/src/mixin-setter/index.tsx @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { Dropdown, Button, Menu, Icon } from '@alifd/next'; -import { getSetter } from '@ali/lowcode-globals'; +import { getSetter } from '@ali/lowcode-editor-core'; import { generateI18n } from './locale/utils'; import zhCN from './locale/zh-CN'; diff --git a/packages/setters/src/style-setter/index.tsx b/packages/setters/src/style-setter/index.tsx index a32e25142..be7001d63 100644 --- a/packages/setters/src/style-setter/index.tsx +++ b/packages/setters/src/style-setter/index.tsx @@ -2,7 +2,7 @@ import './style.less'; import React, { Component } from 'react'; import PropTypes from 'prop-types'; import LowStyleSetter from '@ali/lc-style-setter'; -import { globalLocale } from '@ali/lowcode-globals'; +import { globalLocale } from '@ali/lowcode-editor-core'; export default class StyleSetter extends Component{ diff --git a/packages/types/README.md b/packages/types/README.md new file mode 100644 index 000000000..ea73f17c2 --- /dev/null +++ b/packages/types/README.md @@ -0,0 +1 @@ +类型集合 diff --git a/packages/types/build.json b/packages/types/build.json new file mode 100644 index 000000000..bd5cf18dd --- /dev/null +++ b/packages/types/build.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + "build-plugin-component" + ] +} diff --git a/packages/globals/package.json b/packages/types/package.json similarity index 66% rename from packages/globals/package.json rename to packages/types/package.json index 99d853a7b..9bbd9d826 100644 --- a/packages/globals/package.json +++ b/packages/types/package.json @@ -1,36 +1,22 @@ { - "name": "@ali/lowcode-globals", - "version": "0.9.3", - "description": "Globals api for Ali lowCode engine", - "license": "MIT", + "name": "@ali/lowcode-types", + "version": "0.8.0", + "description": "Types for Ali lowCode engine", + "files": [ + "es", + "lib" + ], "main": "lib/index.js", "module": "es/index.js", - "files": [ - "lib", - "es" - ], "scripts": { "build": "build-scripts build --skip-demo", - "cloud-build": "build-scripts build --skip-demo --config cloud-build.json", "test": "ava", "test:snapshot": "ava --update-snapshots" }, - "ava": { - "compileEnhancements": false, - "extensions": [ - "ts" - ], - "require": [ - "ts-node/register" - ], - "snapshotDir": "test/fixtures/__snapshots__" - }, "dependencies": { "@alifd/next": "^1.19.16", - "@recore/obx": "^1.0.8", - "@recore/obx-react": "^1.0.7", "classnames": "^2.2.6", - "power-di": "^2.2.4", + "monaco-editor": "^0.20.0", "react": "^16", "react-dom": "^16.7.0" }, @@ -40,10 +26,20 @@ "@types/node": "^13.7.1", "@types/react": "^16", "@types/react-dom": "^16", - "build-plugin-component": "^0.2.11", + "build-plugin-component": "^0.2.10", "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0" }, + "ava": { + "compileEnhancements": false, + "snapshotDir": "test/fixtures/__snapshots__", + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + }, "publishConfig": { "registry": "https://registry.npm.alibaba-inc.com" } diff --git a/packages/globals/src/types/data-source.ts b/packages/types/src/data-source.ts similarity index 100% rename from packages/globals/src/types/data-source.ts rename to packages/types/src/data-source.ts diff --git a/packages/editor-core/src/definitions.ts b/packages/types/src/editor.ts similarity index 60% rename from packages/editor-core/src/definitions.ts rename to packages/types/src/editor.ts index 52fff0e7b..9932a174a 100644 --- a/packages/editor-core/src/definitions.ts +++ b/packages/types/src/editor.ts @@ -1,5 +1,38 @@ -import * as React from 'react'; -import Editor from './editor'; +import { EventEmitter } from 'events'; +import { ReactNode, ReactElement, RefObject, ComponentType } from 'react'; +import { NpmInfo } from './npm'; +import { RegisterOptions } from 'power-di'; + +export type KeyType = Function | symbol | string; +export type ClassType = Function | (new (...args: any[]) => any); +export interface GetOptions { + forceNew?: boolean; + sourceCls?: ClassType; +} +export type GetReturnType<T, ClsType> = T extends undefined + ? ClsType extends { + prototype: infer R; + } + ? R + : any + : T; + +export interface IEditor extends EventEmitter { + get<T = undefined, KeyOrType = any>(keyOrType: KeyOrType, opt?: GetOptions): GetReturnType<T, KeyOrType> | undefined; + + has(keyOrType: KeyType): boolean; + + set(key: KeyType, data: any): void; + + onceGot<T = undefined, KeyOrType extends KeyType = any>(keyOrType: KeyOrType): Promise<GetReturnType<T, KeyOrType>>; + + onGot<T = undefined, KeyOrType extends KeyType = any>( + keyOrType: KeyOrType, + fn: (data: GetReturnType<T, KeyOrType>) => void, + ): () => void; + + register(data: any, key?: KeyType, options?: RegisterOptions): void; +} export interface EditorConfig { skeleton?: SkeletonConfig; @@ -13,17 +46,8 @@ export interface EditorConfig { i18n?: I18nConfig; } -export interface NpmConfig { - version: string; - package: string; - main?: string; - exportName?: string; - subName?: string; - destructuring?: boolean; -} - export interface SkeletonConfig { - config: NpmConfig; + config: NpmInfo; props?: object; handler?: (config: EditorConfig) => EditorConfig; } @@ -59,7 +83,7 @@ export interface PluginConfig { panelProps?: object; linkProps?: object; }; - config?: NpmConfig; + config?: NpmInfo; pluginProps?: object; } @@ -68,14 +92,14 @@ export type HooksConfig = HookConfig[]; export interface HookConfig { message: string; type: 'on' | 'once'; - handler: (editor: Editor, ...args: any[]) => void; + handler: (editor: IEditor, ...args: any[]) => void; } export type ShortCutsConfig = ShortCutConfig[]; export interface ShortCutConfig { keyboard: string; - handler: (editor: Editor, ev: Event, keymaster: any) => void; + handler: (editor: IEditor, ev: Event, keymaster: any) => void; } export type UtilsConfig = UtilConfig[]; @@ -83,14 +107,14 @@ export type UtilsConfig = UtilConfig[]; export interface UtilConfig { name: string; type: 'npm' | 'function'; - content: NpmConfig | ((...args: []) => any); + content: NpmInfo | ((...args: []) => any); } export type ConstantsConfig = object; export interface LifeCyclesConfig { - init?: (editor: Editor) => any; - destroy?: (editor: Editor) => any; + init?: (editor: IEditor) => any; + destroy?: (editor: IEditor) => any; } export type LocaleType = 'zh-CN' | 'zh-TW' | 'en-US' | 'ja-JP'; @@ -113,19 +137,19 @@ export interface Utils { } export interface PluginProps { - editor: Editor; + editor: IEditor; config: PluginConfig; i18n?: I18nFunction; - ref?: React.RefObject<React.ReactElement>; + ref?: RefObject<ReactElement>; [key: string]: any; } -export type Plugin = React.ReactNode & { +export type Plugin = ReactNode & { open?: () => boolean | void | Promise<any>; close?: () => boolean | void | Promise<any>; }; -export type HOCPlugin = React.ReactNode & { +export type HOCPlugin = ReactNode & { open: () => Promise<any>; close: () => Promise<any>; }; @@ -134,8 +158,8 @@ export interface PluginSet { [key: string]: HOCPlugin; } -export type PluginClass = React.ComponentType<PluginProps> & { - init?: (editor: Editor) => void; +export type PluginClass = ComponentType<PluginProps> & { + init?: (editor: IEditor) => void; defaultProps?: { locale?: LocaleType; messages?: I18nMessages; diff --git a/packages/globals/src/types/field-config.ts b/packages/types/src/field-config.ts similarity index 99% rename from packages/globals/src/types/field-config.ts rename to packages/types/src/field-config.ts index 17a4cfd78..7e0ff6b38 100644 --- a/packages/globals/src/types/field-config.ts +++ b/packages/types/src/field-config.ts @@ -2,7 +2,6 @@ import { TitleContent } from './title'; import { SetterType, DynamicSetter } from './setter-config'; import { SettingTarget } from './setting-target'; - export interface FieldExtraProps { /** * 是否必填参数 diff --git a/packages/globals/src/types/i18n.ts b/packages/types/src/i18n.ts similarity index 100% rename from packages/globals/src/types/i18n.ts rename to packages/types/src/i18n.ts diff --git a/packages/globals/src/types/icon.ts b/packages/types/src/icon.ts similarity index 100% rename from packages/globals/src/types/icon.ts rename to packages/types/src/icon.ts diff --git a/packages/globals/src/types/index.ts b/packages/types/src/index.ts similarity index 93% rename from packages/globals/src/types/index.ts rename to packages/types/src/index.ts index 9ebb731ff..31aa669f3 100644 --- a/packages/globals/src/types/index.ts +++ b/packages/types/src/index.ts @@ -1,4 +1,5 @@ export * from './data-source'; +export * from './editor'; export * from './field-config'; export * from './i18n'; export * from './icon'; diff --git a/packages/globals/src/types/metadata.ts b/packages/types/src/metadata.ts similarity index 100% rename from packages/globals/src/types/metadata.ts rename to packages/types/src/metadata.ts diff --git a/packages/globals/src/types/npm.ts b/packages/types/src/npm.ts similarity index 100% rename from packages/globals/src/types/npm.ts rename to packages/types/src/npm.ts diff --git a/packages/globals/src/types/prop-config.ts b/packages/types/src/prop-config.ts similarity index 100% rename from packages/globals/src/types/prop-config.ts rename to packages/types/src/prop-config.ts diff --git a/packages/globals/src/types/schema.ts b/packages/types/src/schema.ts similarity index 100% rename from packages/globals/src/types/schema.ts rename to packages/types/src/schema.ts diff --git a/packages/globals/src/types/setter-config.ts b/packages/types/src/setter-config.ts similarity index 96% rename from packages/globals/src/types/setter-config.ts rename to packages/types/src/setter-config.ts index add5b59ca..7bac84279 100644 --- a/packages/globals/src/types/setter-config.ts +++ b/packages/types/src/setter-config.ts @@ -1,4 +1,4 @@ -import { isReactComponent } from '../utils'; +import { isReactComponent } from '@ali/lowcode-utils'; import { ComponentType, ReactElement, isValidElement } from 'react'; import { TitleContent } from './title'; import { SettingTarget } from './setting-target'; @@ -31,7 +31,6 @@ export interface SetterConfig { */ export type SetterType = SetterConfig | SetterConfig[] | string | CustomView; - export function isSetterConfig(obj: any): obj is SetterConfig { return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj); } diff --git a/packages/globals/src/types/setting-target.ts b/packages/types/src/setting-target.ts similarity index 96% rename from packages/globals/src/types/setting-target.ts rename to packages/types/src/setting-target.ts index 94a589561..3848fc154 100644 --- a/packages/globals/src/types/setting-target.ts +++ b/packages/types/src/setting-target.ts @@ -1,4 +1,4 @@ -import { IEditor } from '../di'; +import { IEditor } from './editor'; export interface SettingTarget { /** diff --git a/packages/globals/src/types/tip.ts b/packages/types/src/tip.ts similarity index 100% rename from packages/globals/src/types/tip.ts rename to packages/types/src/tip.ts diff --git a/packages/globals/src/types/title.ts b/packages/types/src/title.ts similarity index 99% rename from packages/globals/src/types/title.ts rename to packages/types/src/title.ts index e9a089b17..3be21d84e 100644 --- a/packages/globals/src/types/title.ts +++ b/packages/types/src/title.ts @@ -3,7 +3,6 @@ import { I18nData } from './i18n'; import { TipContent } from './tip'; import { IconType } from './icon'; - export interface TitleConfig { label?: I18nData | ReactNode; tip?: TipContent; diff --git a/packages/globals/src/types/utils.ts b/packages/types/src/utils.ts similarity index 100% rename from packages/globals/src/types/utils.ts rename to packages/types/src/utils.ts diff --git a/packages/globals/src/types/value-type.ts b/packages/types/src/value-type.ts similarity index 100% rename from packages/globals/src/types/value-type.ts rename to packages/types/src/value-type.ts diff --git a/packages/globals/tsconfig.json b/packages/types/tsconfig.json similarity index 73% rename from packages/globals/tsconfig.json rename to packages/types/tsconfig.json index 91c180bdd..c37b76ecc 100644 --- a/packages/globals/tsconfig.json +++ b/packages/types/tsconfig.json @@ -3,5 +3,7 @@ "compilerOptions": { "outDir": "lib" }, - "include": ["./src/"], + "include": [ + "./src/" + ] } diff --git a/packages/utils/package.json b/packages/utils/package.json new file mode 100644 index 000000000..e69de29bb diff --git a/packages/globals/src/utils/asset.ts b/packages/utils/src/asset.ts similarity index 100% rename from packages/globals/src/utils/asset.ts rename to packages/utils/src/asset.ts diff --git a/packages/globals/src/utils/clone-deep.ts b/packages/utils/src/clone-deep.ts similarity index 100% rename from packages/globals/src/utils/clone-deep.ts rename to packages/utils/src/clone-deep.ts diff --git a/packages/globals/src/utils/create-content.ts b/packages/utils/src/create-content.ts similarity index 100% rename from packages/globals/src/utils/create-content.ts rename to packages/utils/src/create-content.ts diff --git a/packages/globals/src/utils/create-icon.tsx b/packages/utils/src/create-icon.tsx similarity index 93% rename from packages/globals/src/utils/create-icon.tsx rename to packages/utils/src/create-icon.tsx index 0f9ec82c7..9a3a7c74d 100644 --- a/packages/globals/src/utils/create-icon.tsx +++ b/packages/utils/src/create-icon.tsx @@ -1,7 +1,7 @@ -import { Icon } from '@alifd/next'; import { isValidElement, ReactNode, createElement, cloneElement } from 'react'; +import { Icon } from '@alifd/next'; +import { IconType } from '@ali/lowcode-types'; import { isReactComponent } from './is-react'; -import { IconType } from '../types'; const URL_RE = /^(https?:)\/\//i; diff --git a/packages/globals/src/utils/cursor.less b/packages/utils/src/cursor.less similarity index 100% rename from packages/globals/src/utils/cursor.less rename to packages/utils/src/cursor.less diff --git a/packages/globals/src/utils/cursor.ts b/packages/utils/src/cursor.ts similarity index 100% rename from packages/globals/src/utils/cursor.ts rename to packages/utils/src/cursor.ts diff --git a/packages/globals/src/utils/get-prototype-of.ts b/packages/utils/src/get-prototype-of.ts similarity index 100% rename from packages/globals/src/utils/get-prototype-of.ts rename to packages/utils/src/get-prototype-of.ts diff --git a/packages/globals/src/utils/has-own-property.ts b/packages/utils/src/has-own-property.ts similarity index 100% rename from packages/globals/src/utils/has-own-property.ts rename to packages/utils/src/has-own-property.ts diff --git a/packages/globals/src/utils/index.ts b/packages/utils/src/index.ts similarity index 86% rename from packages/globals/src/utils/index.ts rename to packages/utils/src/index.ts index c61e07cd1..3df01d928 100644 --- a/packages/globals/src/utils/index.ts +++ b/packages/utils/src/index.ts @@ -1,22 +1,20 @@ -export * from './create-icon'; -export * from './is-react'; -export * from './unique-id'; -export * from './create-content'; export * from './asset'; export * from './clone-deep'; +export * from './create-content'; +export * from './create-icon'; export * from './cursor'; export * from './get-prototype-of'; export * from './has-own-property'; export * from './is-css-url'; export * from './is-element'; export * from './is-es-module'; +export * from './is-form-event'; export * from './is-function'; export * from './is-object'; export * from './is-plain-object'; +export * from './is-react'; export * from './navtive-selection'; export * from './set-prototype-of'; export * from './shallow-equal'; +export * from './svg-icon'; export * from './unique-id'; -export * from './get-public-path'; -export * from './is-form-event'; -export * from './hotkey'; diff --git a/packages/globals/src/utils/is-css-url.ts b/packages/utils/src/is-css-url.ts similarity index 100% rename from packages/globals/src/utils/is-css-url.ts rename to packages/utils/src/is-css-url.ts diff --git a/packages/globals/src/utils/is-element.ts b/packages/utils/src/is-element.ts similarity index 100% rename from packages/globals/src/utils/is-element.ts rename to packages/utils/src/is-element.ts diff --git a/packages/globals/src/utils/is-es-module.ts b/packages/utils/src/is-es-module.ts similarity index 100% rename from packages/globals/src/utils/is-es-module.ts rename to packages/utils/src/is-es-module.ts diff --git a/packages/globals/src/utils/is-form-event.ts b/packages/utils/src/is-form-event.ts similarity index 100% rename from packages/globals/src/utils/is-form-event.ts rename to packages/utils/src/is-form-event.ts diff --git a/packages/globals/src/utils/is-function.ts b/packages/utils/src/is-function.ts similarity index 100% rename from packages/globals/src/utils/is-function.ts rename to packages/utils/src/is-function.ts diff --git a/packages/globals/src/utils/is-object.ts b/packages/utils/src/is-object.ts similarity index 100% rename from packages/globals/src/utils/is-object.ts rename to packages/utils/src/is-object.ts diff --git a/packages/globals/src/utils/is-plain-object.ts b/packages/utils/src/is-plain-object.ts similarity index 100% rename from packages/globals/src/utils/is-plain-object.ts rename to packages/utils/src/is-plain-object.ts diff --git a/packages/globals/src/utils/is-react.ts b/packages/utils/src/is-react.ts similarity index 100% rename from packages/globals/src/utils/is-react.ts rename to packages/utils/src/is-react.ts diff --git a/packages/globals/src/utils/navtive-selection.ts b/packages/utils/src/navtive-selection.ts similarity index 100% rename from packages/globals/src/utils/navtive-selection.ts rename to packages/utils/src/navtive-selection.ts diff --git a/packages/globals/src/utils/set-prototype-of.ts b/packages/utils/src/set-prototype-of.ts similarity index 100% rename from packages/globals/src/utils/set-prototype-of.ts rename to packages/utils/src/set-prototype-of.ts diff --git a/packages/globals/src/utils/shallow-equal.ts b/packages/utils/src/shallow-equal.ts similarity index 100% rename from packages/globals/src/utils/shallow-equal.ts rename to packages/utils/src/shallow-equal.ts diff --git a/packages/globals/src/components/svg-icon.tsx b/packages/utils/src/svg-icon.tsx similarity index 100% rename from packages/globals/src/components/svg-icon.tsx rename to packages/utils/src/svg-icon.tsx diff --git a/packages/globals/src/utils/unique-id.ts b/packages/utils/src/unique-id.ts similarity index 100% rename from packages/globals/src/utils/unique-id.ts rename to packages/utils/src/unique-id.ts diff --git a/packages/vision-polyfill/src/skeleton/area.ts b/packages/vision-polyfill/src/skeleton/area.ts index 9c35e1289..3877e175d 100644 --- a/packages/vision-polyfill/src/skeleton/area.ts +++ b/packages/vision-polyfill/src/skeleton/area.ts @@ -1,7 +1,7 @@ import { obx, computed } from '@ali/lowcode-globals'; -import WidgetContainer from './widget-container'; +import WidgetContainer from './widget/widget-container'; import { Skeleton } from './skeleton'; -import { IWidget } from './widget'; +import { IWidget } from './widget/widget'; import { IWidgetBaseConfig } from './types'; export default class Area<C extends IWidgetBaseConfig = any, T extends IWidget = IWidget> { diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md b/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md new file mode 100644 index 000000000..8fe96cc16 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md @@ -0,0 +1,5 @@ +* 拖拽排序有问题 +* forceInline 有问题 +* 部分改变不响应 +* 样式还原 +* autofocus diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx new file mode 100644 index 000000000..344bd8a0f --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx @@ -0,0 +1,279 @@ +import { Component, Fragment } from 'react'; +import { Icon, Button, Message } from '@alifd/next'; +import { Title, SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-globals'; +import { createSettingFieldView } from '../../settings/settings-pane'; +import { PopupContext, PopupPipe } from '../../popup'; +import Sortable from './sortable'; +import './style.less'; +import { SettingField } from '@ali/lowcode-designer'; + +interface ArraySetterState { + items: SettingField[]; + itemsMap: Map<string | number, SettingField>; + prevLength: number; +} + +interface ArraySetterProps { + value: any[]; + field: SettingField; + itemSetter?: SetterType; + columns?: FieldConfig[]; + multiValue?: boolean; +} + +export class ListSetter extends Component<ArraySetterProps, ArraySetterState> { + static getDerivedStateFromProps(props: ArraySetterProps, state: ArraySetterState) { + const { value, field } = props; + const newLength = value && Array.isArray(value) ? value.length : 0; + if (state && state.prevLength === newLength) { + return null; + } + + // props value length change will go here + const originLength = state ? state.items.length : 0; + if (state && originLength === newLength) { + return { + prevLength: newLength, + }; + } + + const itemsMap = state ? state.itemsMap : new Map<string | number, SettingField>(); + let items = state ? state.items.slice() : []; + if (newLength > originLength) { + for (let i = originLength; i < newLength; i++) { + const item = field.createField({ + name: i, + setter: props.itemSetter, + // FIXME: + forceInline: 1, + }); + items[i] = item; + itemsMap.set(item.id, item); + } + } else if (newLength < originLength) { + const deletes = items.splice(newLength); + deletes.forEach((item) => { + itemsMap.delete(item.id); + }); + } + return { + items, + itemsMap, + prevLength: newLength, + }; + } + + state: ArraySetterState = { + items: [], + itemsMap: new Map<string | number, SettingField>(), + prevLength: 0, + }; + + onSort(sortedIds: Array<string | number>) { + const { itemsMap } = this.state; + const items = sortedIds.map((id, index) => { + const item = itemsMap.get(id)!; + item.setKey(index); + return item; + }); + this.setState({ + items, + }); + } + + private scrollToLast: boolean = false; + onAdd() { + const { items, itemsMap } = this.state; + const { itemSetter } = this.props; + const initialValue = typeof itemSetter === 'object' ? (itemSetter as any).initialValue : null; + const item = this.props.field.createField({ + name: items.length, + setter: itemSetter, + // FIXME: + forceInline: 1, + }); + items.push(item); + itemsMap.set(item.id, item); + item.setValue(typeof initialValue === 'function' ? initialValue(item) : initialValue); + this.scrollToLast = true; + this.setState({ + items: items.slice(), + }); + } + + onRemove(field: SettingField) { + const { items } = this.state; + let i = items.indexOf(field); + if (i < 0) { + return; + } + items.splice(i, 1); + const l = items.length; + while (i < l) { + items[i].setKey(i); + i++; + } + field.remove(); + this.setState({ items: items.slice() }); + } + + componentWillUnmount() { + this.state.items.forEach((field) => { + field.purge(); + }); + } + + shouldComponentUpdate(_: any, nextState: ArraySetterState) { + if (nextState.items !== this.state.items) { + return true; + } + return false; + } + + render() { + let columns: any = null; + if (this.props.columns) { + columns = this.props.columns.map((column) => <Title key={column.name} title={column.title || (column.name as string)} />); + } + + const { items } = this.state; + const scrollToLast = this.scrollToLast; + this.scrollToLast = false; + const lastIndex = items.length - 1; + + const content = + items.length > 0 ? ( + <div className="lc-setter-list-scroll-body"> + <Sortable itemClassName="lc-setter-list-card" onSort={this.onSort.bind(this)}> + {items.map((field, index) => ( + <ArrayItem + key={field.id} + scrollIntoView={scrollToLast && index === lastIndex} + field={field} + onRemove={this.onRemove.bind(this, field)} + /> + ))} + </Sortable> + </div> + ) : this.props.multiValue ? ( + <Message type="warning">当前选择了多个节点,且值不一致,修改会覆盖所有值</Message> + ) : ( + <Message type="notice">当前项目为空</Message> + ); + + return ( + <div className="lc-setter-list lc-block-setter"> + {/*<div className="lc-block-setter-actions"> + <Button size="medium" onClick={this.onAdd.bind(this)}> + <Icon type="add" /> + <span>添加</span> + </Button> + </div>*/} + {columns && <div className="lc-setter-list-columns">{columns}</div>} + {content} + <Button className="lc-setter-list-add" type="primary" onClick={this.onAdd.bind(this)}> + <Icon type="add" /> + <span>添加一项</span> + </Button> + </div> + ); + } +} + +class ArrayItem extends Component<{ + field: SettingField; + onRemove: () => void; + scrollIntoView: boolean; +}> { + shouldComponentUpdate() { + return false; + } + private shell?: HTMLDivElement | null; + componentDidMount() { + if (this.props.scrollIntoView && this.shell) { + this.shell.parentElement!.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); + } + } + render() { + const { onRemove, field } = this.props; + return ( + <div className="lc-listitem" ref={(ref) => (this.shell = ref)}> + <div draggable className="lc-listitem-handler"> + <Icon type="ellipsis" size="small" /> + </div> + <div className="lc-listitem-body">{createSettingFieldView(field, field.parent)}</div> + <div className="lc-listitem-actions"> + <div className="lc-listitem-action" onClick={onRemove}> + <Icon type="ashbin" size="small" /> + </div> + </div> + </div> + ); + } +} + +class TableSetter extends ListSetter { + // todo: + // forceInline = 1 + // has more actions +} + +export default class ArraySetter extends Component<{ + value: any[]; + field: SettingField; + itemSetter?: SetterType; + mode?: 'popup' | 'list'; + forceInline?: boolean; + multiValue?: boolean; +}> { + static contextType = PopupContext; + private pipe: any; + render() { + const { mode, forceInline, ...props } = this.props; + const { field, itemSetter } = props; + let columns: FieldConfig[] | undefined; + if ((itemSetter as SetterConfig)?.componentName === 'ObjectSetter') { + const items: FieldConfig[] = (itemSetter as any).props?.config?.items; + if (items && Array.isArray(items)) { + columns = items.filter((item) => item.isRequired || item.important || (item.setter as any)?.isRequired); + if (columns.length > 4) { + columns = columns.slice(0, 4); + } + } + } + + if (mode === 'popup' || forceInline) { + const title = ( + <Fragment> + 编辑: + <Title title={field.title} /> + </Fragment> + ); + if (!this.pipe) { + let width = 360; + if (columns) { + if (columns.length === 3) { + width = 480; + } else if (columns.length > 3) { + width = 600; + } + } + this.pipe = (this.context as PopupPipe).create({ width }); + } + this.pipe.send(<TableSetter key={field.id} {...props} columns={columns} />, title); + return ( + <Button + type={forceInline ? 'normal' : 'primary'} + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon type="edit" /> + {forceInline ? title : '编辑数组'} + </Button> + ); + } else { + return <ListSetter {...props} columns={columns?.slice(0, 2)} />; + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less new file mode 100644 index 000000000..12e9512cd --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less @@ -0,0 +1,29 @@ +.lc-sortable { + position: relative; + + .lc-sortable-card { + box-sizing: border-box; + &:after, &:before { + content: ""; + display: table; + } + &:after { + clear: both; + } + + &.lc-dragging { + outline: 2px dashed var(--color-brand); + outline-offset: -2px; + > * { + visibility: hidden; + } + border-color: transparent !important; + box-shadow: none !important; + background: transparent !important; + } + } + + [draggable] { + cursor: ns-resize; + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx new file mode 100644 index 000000000..3329470f1 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx @@ -0,0 +1,220 @@ +import { Component, Children, ReactElement } from 'react'; +import classNames from 'classnames'; +import './sortable.less'; + +class Sortable extends Component<{ + className?: string; + itemClassName?: string; + onSort?: (sortedIds: Array<string | number>) => void; + dragImageSourceHandler?: (elem: Element) => Element; + children: ReactElement[]; +}> { + private shell?: HTMLDivElement | null; + private items?: Array<string | number>; + private willDetach?: () => void; + componentDidMount() { + const box = this.shell!; + + let isDragEnd: boolean = false; + + /** + * target node to be dragged + */ + let source: Element | null; + + /** + * node to be placed + */ + let ref: Element | null; + + /** + * next sibling of the source node + */ + let origRef: Element | null; + + /** + * accurately locate the node from event + */ + const locate = (e: DragEvent) => { + let y = e.clientY; + if (e.view !== window && e.view!.frameElement) { + y += e.view!.frameElement.getBoundingClientRect().top; + } + let node = box.firstElementChild as HTMLDivElement; + while (node) { + if (node !== source && node.dataset.id) { + const rect = node.getBoundingClientRect(); + + if (rect.height <= 0) continue; + if (y < rect.top + rect.height / 2) { + break; + } + } + node = node.nextElementSibling as HTMLDivElement; + } + return node; + }; + + /** + * find the source node + */ + const getSource = (e: DragEvent) => { + const target = e.target as Element; + if (!target || !box.contains(target) || target === box) { + return null; + } + + let node = box.firstElementChild; + while (node) { + if (node.contains(target)) { + return node; + } + node = node.nextElementSibling; + } + + return null; + }; + + const sort = (beforeId: string | number | null | undefined) => { + if (!source) return; + + const sourceId = (source as HTMLDivElement).dataset.id; + const items = this.items!; + const origIndex = items.findIndex(id => id == sourceId); + + let newIndex = beforeId ? items.findIndex(id => id == beforeId) : items.length; + + if (origIndex < 0 || newIndex < 0) return; + if (this.props.onSort) { + if (newIndex > origIndex) { + newIndex -= 1; + } + if (origIndex === newIndex) return; + const item = items.splice(origIndex, 1); + items.splice(newIndex, 0, item[0]); + + this.props.onSort(items); + } + }; + + const dragstart = (e: DragEvent) => { + isDragEnd = false; + source = getSource(e); + if (!source) { + return false; + } + origRef = source.nextElementSibling; + const rect = source.getBoundingClientRect(); + let dragSource = source; + if (this.props.dragImageSourceHandler) { + dragSource = this.props.dragImageSourceHandler(source); + } + if (e.dataTransfer) { + e.dataTransfer.setDragImage(dragSource, e.clientX - rect.left, e.clientY - rect.top); + e.dataTransfer.effectAllowed = 'move'; + e.dataTransfer.dropEffect = 'move'; + try { + e.dataTransfer.setData('application/json', {} as any); + } catch (ex) { + // eslint-disable-line + } + } + + setTimeout(() => { + source!.classList.add('lc-dragging'); + }, 0); + return true; + }; + + const placeAt = (beforeRef: Element | null) => { + if (beforeRef) { + if (beforeRef !== source) { + box.insertBefore(source!, beforeRef); + } + } else { + box.appendChild(source!); + } + }; + + const adjust = (e: DragEvent) => { + if (isDragEnd) return; + ref = locate(e); + placeAt(ref); + }; + + let lastDragEvent: DragEvent | null; + const drag = (e: DragEvent) => { + if (!source) return; + e.preventDefault(); + if (lastDragEvent) { + if (lastDragEvent.clientX === e.clientX && lastDragEvent.clientY === e.clientY) { + return; + } + } + lastDragEvent = e; + if (e.dataTransfer) { + e.dataTransfer.effectAllowed = 'move'; + } + adjust(e); + }; + + const dragend = (e: DragEvent) => { + isDragEnd = true; + if (!source) return; + e.preventDefault(); + source.classList.remove('lc-dragging'); + placeAt(origRef); + sort(ref ? (ref as HTMLDivElement).dataset.id : null); + source = null; + ref = null; + origRef = null; + lastDragEvent = null; + }; + + box.addEventListener('dragstart', dragstart); + document.addEventListener('dragover', drag); + document.addEventListener('drag', drag); + document.addEventListener('dragend', dragend); + + this.willDetach = () => { + box.removeEventListener('dragstart', dragstart); + document.removeEventListener('dragover', drag); + document.removeEventListener('drag', drag); + document.removeEventListener('dragend', dragend); + }; + } + + componentWillUnmount() { + if (this.willDetach) { + this.willDetach(); + } + } + + render() { + const { className, itemClassName, children } = this.props; + const items: Array<string | number> = []; + const cards = Children.map(children, child => { + const id = child.key!; + items.push(id); + return ( + <div key={id} data-id={id} className={classNames('lc-sortable-card', itemClassName)}> + {child} + </div> + ); + }); + this.items = items; + + return ( + <div + className={classNames('lc-sortable', className)} + ref={ref => { + this.shell = ref; + }} + > + {cards} + </div> + ); + } +} + +export default Sortable; diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/style.less b/packages/vision-polyfill/src/skeleton/components/array-setter/style.less new file mode 100644 index 000000000..8e0da024b --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/array-setter/style.less @@ -0,0 +1,103 @@ +.lc-setter-list { + [draggable] { + cursor: move; + } + color: var(--color-text); + + .next-btn { + display: inline-flex; + align-items: center; + line-height: 1 !important; + max-width: 100%; + text-overflow: ellipsis; + } + + .lc-setter-list-add { + display: block; + width: 100%; + margin-top: 8px;; + } + + + .lc-setter-list-columns { + display: flex; + > .lc-title { + flex: 1; + justify-content: center; + } + margin-left: 47px; + margin-right: 28px; + margin-bottom: 5px; + } + + .lc-setter-list-scroll-body { + margin: -8px -5px; + padding: 8px 10px; + overflow-y: auto; + max-height: 300px; + } + + .lc-setter-list-card { + border: 1px solid rgba(31,56,88,.2); + background-color: var(--color-block-background-light); + border-radius: 3px; + &:not(:last-child) { + margin-bottom: 5px; + } + + .lc-listitem { + position: relative; + outline: none; + display: flex; + align-items: stretch; + height: 34px; + + .lc-listitem-actions { + margin: 0 3px; + display: inline-flex; + align-items: center; + justify-content: flex-end; + .lc-listitem-action { + text-align: center; + cursor: pointer; + opacity: 0.6; + &:hover { + opacity: 1; + } + } + } + .lc-listitem-body { + flex: 1; + display: flex; + align-items: stretch; + overflow: hidden; + min-width: 0; + text-overflow: ellipsis; + .lc-field { + padding: 0 !important; + display: flex; + align-items: center; + >.lc-field-body { + justify-content: center; + } + } + > * { + width: 100%; + } + .next-btn { + display: block; + width: 100%; + } + } + .lc-listitem-handler { + margin-left: 2px; + display: inline-flex; + align-items: center; + .next-icon-ellipsis { + transform: rotate(90deg); + } + opacity: 0.6; + } + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/field/fields.tsx b/packages/vision-polyfill/src/skeleton/components/field/fields.tsx new file mode 100644 index 000000000..d36928604 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/field/fields.tsx @@ -0,0 +1,184 @@ +import { Component } from 'react'; +import classNames from 'classnames'; +import { Icon } from '@alifd/next'; +import { Title, TitleContent } from '@ali/lowcode-globals'; +import { PopupPipe, PopupContext } from '../popup'; +import './index.less'; + +export interface FieldProps { + className?: string; + title?: TitleContent | null; + defaultDisplay?: 'accordion' | 'inline' | 'block'; + collapsed?: boolean; + onExpandChange?: (expandState: boolean) => void; +} + +export class Field extends Component<FieldProps> { + state = { + collapsed: this.props.collapsed, + display: this.props.defaultDisplay || 'inline', + }; + + private toggleExpand = () => { + const { onExpandChange } = this.props; + const collapsed = !this.state.collapsed; + this.setState({ + collapsed, + }); + onExpandChange && onExpandChange(!collapsed); + }; + private body: HTMLDivElement | null = null; + private dispose?: () => void; + private deployBlockTesting() { + if (this.dispose) { + this.dispose(); + } + const body = this.body; + if (!body) { + return; + } + const check = () => { + const setter = body.firstElementChild; + if (setter && setter.classList.contains('lc-block-setter')) { + this.setState({ + display: 'block', + }); + } else { + this.setState({ + display: 'inline', + }); + } + }; + const observer = new MutationObserver(check); + check(); + observer.observe(body, { + childList: true, + subtree: true, + attributes: true, + attributeFilter: ['class'], + }); + this.dispose = () => observer.disconnect(); + } + componentDidMount() { + const { defaultDisplay } = this.props; + if (!defaultDisplay || defaultDisplay === 'inline') { + this.deployBlockTesting(); + } + } + componentWillUnmount() { + if (this.dispose) { + this.dispose(); + } + } + + render() { + const { className, children, title } = this.props; + const { display, collapsed } = this.state; + const isAccordion = display === 'accordion'; + return ( + <div + className={classNames(`lc-field lc-${display}-field`, className, { + 'lc-field-is-collapsed': isAccordion && collapsed, + })} + > + <div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}> + <div className="lc-field-title"> + <Title title={title || ''} /> + </div> + {isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />} + </div> + <div key="body" ref={(shell) => (this.body = shell)} className="lc-field-body"> + {children} + </div> + </div> + ); + } +} + +export interface PopupFieldProps extends FieldProps { + width?: number; +} + +export class PopupField extends Component<PopupFieldProps> { + static contextType = PopupContext; + private pipe: any; + + static defaultProps: PopupFieldProps = { + width: 300, + }; + + render() { + const { className, children, title, width } = this.props; + if (!this.pipe) { + this.pipe = (this.context as PopupPipe).create({ width }); + } + + const titleElement = title && ( + <div className="lc-field-title"> + <Title title={title} /> + </div> + ); + + this.pipe.send(<div className="lc-field-body">{children}</div>, titleElement); + + return ( + <div className={classNames('lc-field lc-popup-field', className)}> + {title && ( + <div + className="lc-field-head" + onClick={(e) => { + this.pipe.show((e as any).target); + }} + > + <div className="lc-field-title"> + <Title title={title} /> + </div> + <Icon className="lc-field-icon" type="arrow-left" size="xs" /> + </div> + )} + </div> + ); + } +} + +export interface EntryFieldProps extends FieldProps { + stageName?: string; +} + +export class EntryField extends Component<EntryFieldProps> { + render() { + const { stageName, title, className } = this.props; + const classNameList = classNames('engine-setting-field', 'engine-entry-field', className); + const fieldProps: any = {}; + + if (stageName) { + // 为 stage 切换奠定基础 + fieldProps['data-stage-target'] = stageName; + } + + const innerElements = [ + <span className="engine-field-title" key="field-title"> + {title} + </span>, + // renderTip(tip, { propName }), + // <Icons name="arrow" className="engine-field-arrow" size="12px" key="engine-field-arrow-icon" />, + ]; + + return ( + <div className={classNameList} {...fieldProps}> + {innerElements} + </div> + ); + } +} + +export class PlainField extends Component<FieldProps> { + render() { + const { className, children } = this.props; + return ( + <div className={classNames(`lc-field lc-plain-field`, className)}> + <div className="lc-field-body">{children}</div> + </div> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/field/index.less b/packages/vision-polyfill/src/skeleton/components/field/index.less new file mode 100644 index 000000000..5fecb74d9 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/field/index.less @@ -0,0 +1,154 @@ +@import '../variables.less'; + +@x-gap: 10px; +@y-gap: 8px; + +.lc-field { + // head + .lc-field-head { + display: flex; + align-items: center; + justify-content: space-between; + + .lc-field-title { + display: flex; + align-items: center; + } + .lc-field-icon { + margin-right: @x-gap; + transform-origin: center; + transition: transform 0.1s; + } + } + + &.lc-plain-field { + // for top-level style + padding: 8px 10px; + > .lc-field-body { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + } + } + + &.lc-inline-field { + display: flex; + align-items: center; + // for top-level style + padding: 8px 10px; + + > .lc-field-head { + width: 70px; + margin-right: 1px; + .lc-title-label { + width: 70px; + word-break: break-all; + } + } + > .lc-field-body { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + } + } + + &.lc-block-field, &.lc-accordion-field { + display: block; + &:not(:first-child) { + border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + } + > .lc-field-head { + padding-left: @x-gap; + height: 32px; + display: flex; + align-items: center; + font-weight: 500; + background: var(--color-block-background-shallow, rgba(31,56,88,.06)); + border-bottom: 1px solid var(--color-line-normal, @dark-alpha-2); + color: var(--color-title, @white-alpha-2); + user-select: none; + } + + > .lc-field-body { + padding: @y-gap @x-gap/2; + } + + + .lc-inline-field { + border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + } + } + + .lc-setter-actions { + display: flex; + align-items: center; + } + + &.lc-block-field { + position: relative; + >.lc-field-body>.lc-block-setter>.lc-setter-actions { + position: absolute; + right: 10px; + top: 0; + height: 32px; + display: flex; + align-items: center; + } + } + + &.lc-accordion-field { + // collapsed + &.lc-field-is-collapsed { + > .lc-field-head .lc-field-icon { + transform: rotate(180deg); + } + > .lc-field-body { + display: none; + } + } + + // 邻近的保持上下距离 + + .lc-field { + margin-top: @y-gap; + } + } + + // 2rd level reset + .lc-field-body { + .lc-inline-field { + padding: @y-gap @x-gap/2 0 @x-gap/2; + &:first-child { + padding-top: 0; + } + + .lc-accordion-field, +.lc-block-field { + margin-top: @y-gap; + } + } + + .lc-field { + border-top: none !important; + } + + .lc-accordion-field, .lc-block-field { + > .lc-field-head { + padding-left: @x-gap/2; + background: var(--color-block-background-light); + border-bottom-color: var(--color-line-light); + > .lc-field-icon { + margin-right: @x-gap/2; + } + } + } + + // 3rd level field title width should short + .lc-field-body .lc-inline-field { + > .lc-field-head { + width: 50px; + .lc-title-label { + width: 50px; + } + } + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/field/index.ts b/packages/vision-polyfill/src/skeleton/components/field/index.ts new file mode 100644 index 000000000..2f50d53ff --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/field/index.ts @@ -0,0 +1,28 @@ +import { ReactNode, createElement } from 'react'; +import { TitleContent } from '@ali/lowcode-globals'; +import './index.less'; +import { Field, PopupField, EntryField, PlainField } from './fields'; + +export interface FieldProps { + className?: string; + title?: TitleContent | null; + display?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry'; + collapsed?: boolean; + onExpandChange?: (collapsed: boolean) => void; + [extra: string]: any; +} + +export function createField(props: FieldProps, children: ReactNode, type?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry') { + if (type === 'popup') { + return createElement(PopupField, props, children); + } + if (type === 'entry') { + return createElement(EntryField, props, children); + } + if (type === 'plain' || !props.title) { + return createElement(PlainField, props, children); + } + return createElement(Field, { ...props, defaultDisplay: type }, children); +} + +export { Field, PopupField, EntryField, PlainField }; diff --git a/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx new file mode 100644 index 000000000..5217322c2 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx @@ -0,0 +1,257 @@ +import React, { Component, isValidElement } from 'react'; +import classNames from 'classnames'; +import { Dropdown, Button, Menu } from '@alifd/next'; +import { + getSetter, + getSettersMap, + SetterConfig, + computed, + obx, + CustomView, + DynamicProps, + DynamicSetter, + TitleContent, + isSetterConfig, + Title, + createSetterContent, + observer, + isDynamicSetter, + shallowIntl, + EmbedTip, + isI18nData, +} from '@ali/lowcode-globals'; +import { IconConvert } from '../../icons/convert'; + +import './style.less'; +import { SettingField } from '@ali/lowcode-designer'; + +export interface SetterItem { + name: string; + title: TitleContent; + setter: string | DynamicSetter | CustomView; + props?: object | DynamicProps; + condition?: (field: SettingField) => boolean; + initialValue?: any | ((field: SettingField) => any); + list: boolean; +} + +function nomalizeSetters(setters?: Array<string | SetterConfig | CustomView | DynamicSetter>): SetterItem[] { + if (!setters) { + const normalized: SetterItem[] = []; + getSettersMap().forEach((setter, name) => { + if (name === 'MixedSetter') { + return; + } + normalized.push({ + name, + title: setter.title || name, + setter: name, + condition: setter.condition, + initialValue: setter.initialValue, + list: setter.recommend || false, + }); + }); + return normalized; + } + const names: string[] = []; + function generateName(n: string) { + let idx = 1; + let got = n; + while (names.indexOf(got) > -1) { + got = `${n}:${idx++}`; + } + names.push(got); + return got; + } + return setters.map((setter) => { + const config: any = { + setter, + list: true, + }; + if (isSetterConfig(setter)) { + config.setter = setter.componentName; + config.props = setter.props; + config.condition = setter.condition; + config.initialValue = setter.initialValue; + config.title = setter.title; + } + if (typeof config.setter === 'string') { + config.name = config.setter; + names.push(config.name); + const info = getSetter(config.setter); + if (!config.title) { + config.title = info?.title || config.setter; + } + if (!config.condition) { + config.condition = info?.condition; + } + if (!config.initialValue) { + config.initialValue = info?.initialValue; + } + } else { + config.name = generateName((config.setter as any).displayName || (config.setter as any).name || 'CustomSetter'); + if (!config.title) { + config.title = config.name; + } + } + return config; + }); +} + +@observer +export default class MixedSetter extends Component<{ + field: SettingField; + setters?: Array<string | SetterConfig | CustomView | DynamicSetter>; + onSetterChange?: (field: SettingField, name: string) => void; + onChange?: (val: any) => void; + value?: any; + className?: string; +}> { + private setters = nomalizeSetters(this.props.setters); + @obx.ref private used?: string; + @computed private getCurrentSetter() { + const { field } = this.props; + let firstMatched: SetterItem | undefined; + for (const setter of this.setters) { + const matched = !setter.condition || setter.condition(field); + if (matched) { + if (setter.name === this.used) { + return setter; + } + if (!firstMatched) { + firstMatched = setter; + } + } + } + return firstMatched; + } + + private useSetter = (name: string) => { + if (name === this.used) { + return; + } + const { field, onChange } = this.props; + const setter = this.setters.find((item) => item.name === name); + this.used = name; + if (setter) { + let newValue: any = setter.initialValue; + if (newValue && typeof newValue === 'function') { + newValue = newValue(field); + } + onChange && onChange(newValue); + } + }; + + private shell: HTMLDivElement | null = null; + private checkIsBlockField() { + if (this.shell) { + const setter = this.shell.firstElementChild; + if (setter && setter.classList.contains('lc-block-setter')) { + this.shell.classList.add('lc-block-setter'); + } else { + this.shell.classList.remove('lc-block-setter'); + } + } + } + componentDidUpdate() { + this.checkIsBlockField(); + } + componentDidMount() { + this.checkIsBlockField(); + } + + render() { + const { className, field, setters, onSetterChange, ...restProps } = this.props; + + const currentSetter = this.getCurrentSetter(); + const isTwoType = this.setters.length < 3; + + let setterContent: any; + const triggerTitle: any = { + tip: { + type: 'i18n', + 'zh-CN': '切换格式', + 'en-US': 'Switch Format', + }, + icon: <IconConvert size={24} />, + }; + if (currentSetter) { + const { setter, title, props } = currentSetter; + let setterProps: any = {}; + let setterType: any; + if (isDynamicSetter(setter)) { + setterType = setter.call(field, field); + } else { + setterType = setter; + } + if (props) { + setterProps = props; + if (typeof setterProps === 'function') { + setterProps = setterProps(field); + } + } + + setterContent = createSetterContent(setterType, { + ...shallowIntl(setterProps), + field, + ...restProps, + }); + if (title) { + if (typeof title !== 'object' || isI18nData(title) || isValidElement(title)) { + triggerTitle.tip = title; + } else { + triggerTitle.tip = title.tip || title.label; + } + } + } else { + // 未匹配的 null 值,显示 NullValue 空值 + // 未匹配的 其它 值,显示 InvalidValue 非法值 + if (restProps.value == null) { + setterContent = <span>NullValue</span>; + } else { + setterContent = <span>InvalidValue</span>; + } + } + const usedName = currentSetter?.name || this.used; + let moreBtnNode = ( + <Title + title={triggerTitle} + className="lc-switch-trigger" + onClick={ + isTwoType + ? () => { + if (this.setters[0]?.name === usedName) { + this.useSetter(this.setters[1]?.name); + } else { + this.useSetter(this.setters[0]?.name); + } + } + : undefined + } + /> + ); + if (!isTwoType) { + moreBtnNode = ( + <Dropdown trigger={moreBtnNode} triggerType="click" align="tr br"> + <Menu selectMode="single" hasSelectedIcon={true} selectedKeys={usedName} onItemClick={this.useSetter}> + {this.setters.filter(setter => setter.list || setter.name === usedName).map((setter) => { + return ( + <Menu.Item key={setter.name}> + <Title title={setter.title} /> + </Menu.Item> + ); + })} + </Menu> + </Dropdown> + ); + } + + return ( + <div ref={(shell) => (this.shell = shell)} className={classNames('lc-setter-mixed', className)}> + {setterContent} + + <div className="lc-setter-actions">{moreBtnNode}</div> + </div> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less b/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less new file mode 100644 index 000000000..6efebb28c --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less @@ -0,0 +1,30 @@ +.lc-setter-mixed { + flex: 1; + min-width: 0; + margin-right: 26px; + display: block; + position: relative; + >.lc-setter-actions { + position: absolute; + right: -2px; + top: 50%; + transform: translate(100%, -50%); + .lc-switch-trigger { + cursor: pointer; + opacity: 0.6; + &:hover { + opacity: 1; + } + } + } + .next-input,.next-date-picker { + width: 100%; + } + &.lc-block-setter { + position: static; + margin-right: 0; + >.lc-setter-actions { + transform: none; + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx new file mode 100644 index 000000000..2f84c8adb --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx @@ -0,0 +1,180 @@ +import { Component, Fragment } from 'react'; +import { Icon, Button } from '@alifd/next'; +import { Title, SetterType, FieldConfig } from '@ali/lowcode-globals'; +import { createSettingFieldView } from '../../settings/settings-pane'; +import { PopupContext, PopupPipe } from '../../popup'; +import { SettingField } from '@ali/lowcode-designer'; +import './style.less'; + +export default class ObjectSetter extends Component<{ + field: SettingField; + descriptor?: string | ((rowField: SettingField) => string); + config: ObjectSetterConfig; + mode?: 'popup' | 'form'; + // 1: in tablerow 2: in listrow 3: in column-cell + forceInline?: number; +}> { + render() { + const { mode, forceInline = 0, ...props } = this.props; + if (forceInline || mode === 'popup') { + if (forceInline > 2 || mode === 'popup') { + // popup + return <RowSetter {...props} primaryButton={forceInline ? false : true} />; + } else { + return <RowSetter columns={forceInline > 1 ? 2 : 4} {...props} />; + } + } else { + // form + return <FormSetter {...props} />; + } + } +} + +interface ObjectSetterConfig { + items?: FieldConfig[]; + extraSetter?: SetterType; +} + +interface RowSetterProps { + field: SettingField; + descriptor?: string | ((rowField: SettingField) => string); + config: ObjectSetterConfig; + columns?: number; + primaryButton?: boolean; +} + +class RowSetter extends Component<RowSetterProps> { + static contextType = PopupContext; + + state: any = { + descriptor: '', + }; + + private items?: SettingField[]; + constructor(props: RowSetterProps) { + super(props); + const { config, descriptor, field, columns } = props; + const items: SettingField[] = []; + if (columns && config.items) { + const l = Math.min(config.items.length, columns); + for (let i = 0; i < l; i++) { + const conf = config.items[i]; + if (conf.isRequired || conf.important || (conf.setter as any)?.isRequired) { + const item = field.createField({ + ...conf, + // in column-cell + forceInline: 3, + }); + items.push(item); + } + } + } + + if (items.length > 0) { + this.items = items; + } + + let firstRun: boolean = true; + field.onEffect(() => { + let state: any = {}; + if (descriptor) { + if (typeof descriptor === 'function') { + state.descriptor = descriptor(field); + } else { + state.descriptor = field.getPropValue(descriptor); + } + } else { + state.descriptor = field.title; + } + + if (firstRun) { + firstRun = false; + this.state = state; + } else { + this.setState(state); + } + }); + } + + shouldComponentUpdate(_: any, nextState: any) { + if (this.state.decriptor !== nextState.decriptor) { + return true; + } + return false; + } + + private pipe: any; + render() { + const items = this.items; + const { field, primaryButton, config } = this.props; + + if (!this.pipe) { + this.pipe = (this.context as PopupPipe).create({ width: 320 }); + } + + const title = ( + <Fragment> + 编辑: + <Title title={this.state.descriptor} /> + </Fragment> + ); + + this.pipe.send(<FormSetter key={field.id} field={field} config={config} />, title); + + if (items) { + return ( + <div className="lc-setter-object-row"> + <div + className="lc-setter-object-row-edit" + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon size="small" type="edit" /> + </div> + <div className="lc-setter-object-row-body">{items.map((item) => createSettingFieldView(item, field))}</div> + </div> + ); + } + + return ( + <Button + type={primaryButton === false ? 'normal' : 'primary'} + onClick={(e) => { + this.pipe.show((e as any).target, field.id); + }} + > + <Icon type="edit" /> + {title} + </Button> + ); + } +} + +interface FormSetterProps { + field: SettingField; + config: ObjectSetterConfig; +} +class FormSetter extends Component<FormSetterProps> { + private items: SettingField[]; + constructor(props: RowSetterProps) { + super(props); + const { config, field } = props; + this.items = (config.items || []).map((conf) => field.createField(conf)); + + // TODO: extraConfig for custom fields + } + + shouldComponentUpdate() { + return false; + } + + render() { + const { field } = this.props; + return ( + <div className="lc-setter-object lc-block-setter"> + {this.items.map((item, index) => createSettingFieldView(item, field, index))} + </div> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/object-setter/style.less b/packages/vision-polyfill/src/skeleton/components/object-setter/style.less new file mode 100644 index 000000000..6d6064df1 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/object-setter/style.less @@ -0,0 +1,31 @@ +.lc-setter-object-row { + display: flex; + align-items: stretch; + width: 100%; + .lc-setter-object-row-edit { + width: 20px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + } + .lc-setter-object-row-body { + display: flex; + flex: 1; + min-width: 0; + align-items: center; + .lc-field { + padding: 0 !important; + .lc-field-body { + padding: 0 !important; margin: 0 !important; + } + } + > * { + flex: 1; + flex-shrink: 1; + margin-left: 2px; + min-width: 0; + overflow: hidden; + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/popup/index.tsx b/packages/vision-polyfill/src/skeleton/components/popup/index.tsx new file mode 100644 index 000000000..503e986f9 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/popup/index.tsx @@ -0,0 +1,150 @@ +import { createContext, ReactNode, Component, PureComponent } from 'react'; +import { EventEmitter } from 'events'; +import { Balloon } from '@alifd/next'; +import { uniqueId } from '@ali/lowcode-globals'; +import './style.less'; + +export const PopupContext = createContext<PopupPipe>({} as any); + +export class PopupPipe { + private emitter = new EventEmitter(); + private currentId?: string; + + create(props?: object): { send: (content: ReactNode, title: ReactNode) => void; show: (target: Element) => void } { + let sendContent: ReactNode = null; + let sendTitle: ReactNode = null; + const id = uniqueId('popup'); + return { + send: (content: ReactNode, title: ReactNode) => { + sendContent = content; + sendTitle = title; + if (this.currentId === id) { + this.popup({ + ...props, + content, + title, + }); + } + }, + show: (target: Element, actionKey?: string) => { + this.currentId = id; + this.popup( + { + ...props, + actionKey, + content: sendContent, + title: sendTitle, + }, + target, + ); + }, + }; + } + + private popup(props: object, target?: Element) { + Promise.resolve().then(() => { + this.emitter.emit('popupchange', props, target); + }); + } + + onPopupChange(fn: (props: object, target?: Element) => void): () => void { + this.emitter.on('popupchange', fn); + return () => { + this.emitter.removeListener('popupchange', fn); + }; + } + + purge() { + this.emitter.removeAllListeners(); + } +} + +export default class PopupService extends Component<{ actionKey?: string; safeId?: string }> { + private popupPipe = new PopupPipe(); + + componentWillUnmount() { + this.popupPipe.purge(); + } + + render() { + const { children, actionKey, safeId } = this.props; + return ( + <PopupContext.Provider value={this.popupPipe}> + {children} + <PopupContent key={'pop' + actionKey} safeId={safeId} /> + </PopupContext.Provider> + ); + } +} + +export class PopupContent extends PureComponent<{ safeId?: string }> { + static contextType = PopupContext; + state: any = { + visible: false, + pos: {}, + }; + + private dispose = (this.context as PopupPipe).onPopupChange((props, target) => { + const state: any = { + ...props, + visible: true, + }; + if (target) { + const rect = target.getBoundingClientRect(); + state.pos = { + top: rect.top, + height: rect.height, + }; + // todo: compute the align method + } + this.setState(state); + }); + + componentWillUnmount() { + this.dispose(); + } + + render() { + const { content, visible, width, title, pos, actionKey } = this.state; + if (!visible) { + return null; + } + let avoidLaterHidden = true; + setTimeout(() => { + avoidLaterHidden = false; + }, 10); + + const id = uniqueId('ball'); + + return ( + <Balloon + className="lc-ballon" + align="l" + id={this.props.safeId} + safeNode={id} + visible={visible} + style={{ width }} + onVisibleChange={(visible) => { + if (avoidLaterHidden) { + return; + } + if (!visible) { + this.setState({ visible: false }); + } + }} + trigger={<div className="lc-popup-placeholder" style={pos} />} + triggerType="click" + animation={false} + // needAdjust + shouldUpdatePosition + > + <div className="lc-ballon-title">{title}</div> + <div className="lc-ballon-content"> + <PopupService actionKey={actionKey} safeId={id}> + {content} + </PopupService> + </div> + </Balloon> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/popup/style.less b/packages/vision-polyfill/src/skeleton/components/popup/style.less new file mode 100644 index 000000000..b115fd371 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/popup/style.less @@ -0,0 +1,22 @@ +.lc-popup-placeholder { + position: fixed; + width: 100%; + pointer-events: none; +} + +.lc-ballon { + padding: 10px; + max-width: 640px; + width: 640px; + .lc-ballon-title { + font-size: 14px; + } + .lc-ballon-content { + margin-top: 10px; + // width: 300px; + } + .next-balloon-close { + top: 4px; + right: 4px; + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/register.ts b/packages/vision-polyfill/src/skeleton/components/register.ts new file mode 100644 index 000000000..3c096aa82 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/register.ts @@ -0,0 +1,29 @@ +import { registerSetter, isPlainObject } from '@ali/lowcode-globals'; +import ArraySetter from './array-setter'; +import ObjectSetter from './settings-pane/src/setters/object-setter'; +import MixedSetter from './mixed-setter'; + +registerSetter('ArraySetter', { + component: ArraySetter, + defaultProps: {}, + title: 'ArraySetter', // TODO + condition: (field: any) => { + const v = field.getValue(); + return v == null || Array.isArray(v); + }, + initialValue: [], + recommend: true, +}); +registerSetter('ObjectSetter', { + component: ObjectSetter, + // todo: defaultProps + defaultProps: {}, + title: 'ObjectSetter', // TODO + condition: (field: any) => { + const v = field.getValue(); + return v == null || isPlainObject(v); + }, + initialValue: {}, + recommend: true, +}); +registerSetter('MixedSetter', MixedSetter); diff --git a/packages/vision-polyfill/src/skeleton/components/settings/index.ts b/packages/vision-polyfill/src/skeleton/components/settings/index.ts new file mode 100644 index 000000000..f51b7b704 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/index.ts @@ -0,0 +1,9 @@ +import { createSettingFieldView } from './settings-pane'; +import './transducers/register'; +import '../../register'; +import './style.less'; +import SettingsMainView from './settings-primary-view'; + +export default SettingsMainView; + +export { createSettingFieldView }; diff --git a/packages/vision-polyfill/src/skeleton/components/settings/main.ts b/packages/vision-polyfill/src/skeleton/components/settings/main.ts new file mode 100644 index 000000000..f752add28 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/main.ts @@ -0,0 +1,89 @@ +import { EventEmitter } from 'events'; +import { obx, computed } from '@ali/lowcode-globals'; +import { Node, Designer, Selection, SettingTopEntry } from '@ali/lowcode-designer'; +import { getTreeMaster } from '@ali/lowcode-plugin-outline-pane'; +import Editor from '@ali/lowcode-editor-core'; + +function generateSessionId(nodes: Node[]) { + return nodes + .map((node) => node.id) + .sort() + .join(','); +} + +export class SettingsMain { + private emitter = new EventEmitter(); + private _sessionId = ''; + @obx.ref private _settings?: SettingTopEntry; + + @computed get length(): number | undefined { + return this._settings?.nodes.length; + } + + @computed get componentMeta() { + return this._settings?.componentMeta; + } + + get settings() { + return this._settings; + } + + private disposeListener: () => void; + + private designer?: Designer; + + constructor(readonly editor: Editor) { + this.init(); + } + + private async init() { + const setupSelection = (selection?: Selection) => { + if (selection) { + this.setup(selection.getNodes()); + } else { + this.setup([]); + } + }; + this.editor.on('designer.selection.change', setupSelection); + this.disposeListener = () => { + this.editor.removeListener('designer.selection.change', setupSelection); + }; + const designer = await this.editor.onceGot(Designer); + this.designer = designer; + getTreeMaster(designer).onceEnableBuiltin(() => { + this.emitter.emit('outline-visible'); + }); + setupSelection(designer.currentSelection); + } + + private setup(nodes: Node[]) { + // check nodes change + const sessionId = generateSessionId(nodes); + if (sessionId === this._sessionId) { + return; + } + this._sessionId = sessionId; + if (nodes.length < 1) { + this._settings = undefined; + return; + } + + if (!this.designer) { + this.designer = nodes[0].document.designer; + } + + this._settings = this.designer.createSettingEntry(this.editor, nodes); + } + + onceOutlineVisible(fn: () => void): () => void { + this.emitter.on('outline-visible', fn); + return () => { + this.emitter.removeListener('outline-visible', fn); + }; + } + + purge() { + this.disposeListener(); + this.emitter.removeAllListeners(); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/package.json b/packages/vision-polyfill/src/skeleton/components/settings/package.json new file mode 100644 index 000000000..2a0fab24e --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/package.json @@ -0,0 +1,49 @@ +{ + "name": "@ali/lowcode-plugin-settings-pane", + "version": "0.8.10", + "description": "Settings pane for Ali lowCode engine", + "files": [ + "es", + "lib" + ], + "main": "lib/index.js", + "module": "es/index.js", + "scripts": { + "build": "build-scripts build --skip-demo", + "test": "ava", + "test:snapshot": "ava --update-snapshots" + }, + "dependencies": { + "@ali/lowcode-designer": "^0.9.2", + "@ali/lowcode-editor-core": "^0.8.5", + "@ali/lowcode-globals": "^0.9.2", + "@ali/lowcode-plugin-outline-pane": "^0.8.8", + "@ali/ve-stage-box": "^4.0.0", + "@alifd/next": "^1.19.16", + "classnames": "^2.2.6", + "react": "^16" + }, + "devDependencies": { + "@alib/build-scripts": "^0.1.18", + "@types/classnames": "^2.2.7", + "@types/node": "^13.7.1", + "@types/react": "^16", + "build-plugin-component": "^0.2.10", + "build-plugin-fusion": "^0.1.1", + "build-plugin-moment-locales": "^0.1.0" + }, + "ava": { + "compileEnhancements": false, + "snapshotDir": "test/fixtures/__snapshots__", + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + }, + "license": "MIT", + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx b/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx new file mode 100644 index 000000000..11edc8a4c --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx @@ -0,0 +1,149 @@ +import { Component } from 'react'; +import { + createContent, + CustomView, + intl, + shallowIntl, + isSetterConfig, + createSetterContent, + observer, +} from '@ali/lowcode-globals'; +import { Field, createField } from '../field'; +import PopupService from '../popup'; +import { SettingField, isSettingField, SettingTopEntry, SettingEntry } from '@ali/lowcode-designer'; + +@observer +class SettingFieldView extends Component<{ field: SettingField }> { + render() { + const { field } = this.props; + const { extraProps } = field; + const { condition, defaultValue } = extraProps; + const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; + if (!visible) { + return null; + } + const { setter } = field; + + let setterProps: any = {}; + let setterType: any; + if (Array.isArray(setter)) { + setterType = 'MixedSetter'; + setterProps = { + setters: setter, + }; + } else if (isSetterConfig(setter)) { + setterType = setter.componentName; + if (setter.props) { + setterProps = setter.props; + if (typeof setterProps === 'function') { + setterProps = setterProps(field); + } + } + } else if (setter) { + setterType = setter; + } + let value = null; + if (field.type === 'field') { + if (defaultValue != null && !('defaultValue' in setterProps)) { + setterProps.defaultValue = defaultValue; + } + if (field.valueState > 0) { + value = field.getValue(); + } else { + setterProps.multiValue = true; + if (!('placeholder' in setterProps)) { + // FIXME! move to locale file + setterProps.placeholder = intl({ + type: 'i18n', + 'zh-CN': '多种值', + 'en-US': 'Multiple Value', + }); + } + } + } + + // todo: error handling + + return createField({ + title: field.title, + collapsed: !field.expanded, + onExpandChange: (expandState) => field.setExpanded(expandState), + }, createSetterContent(setterType, { + ...shallowIntl(setterProps), + forceInline: extraProps.forceInline, + key: field.id, + // === injection + prop: field, // for compatible vision + field, + // === IO + value, // reaction point + onChange: (value: any) => { + this.setState({ + value, + }); + field.setValue(value); + }, + }), extraProps.forceInline ? 'plain' : extraProps.display); + } +} + +@observer +class SettingGroupView extends Component<{ field: SettingField }> { + shouldComponentUpdate() { + return false; + } + + render() { + const { field } = this.props; + const { extraProps } = field; + const { condition } = extraProps; + const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; + + if (!visible) { + return null; + } + + // todo: split collapsed state | field.items for optimize + return ( + <Field defaultDisplay="accordion" title={field.title} collapsed={!field.expanded} onExpandChange={(expandState) => { + field.setExpanded(expandState); + }}> + {field.items.map((item, index) => createSettingFieldView(item, field, index))} + </Field> + ); + } +} + +export function createSettingFieldView(item: SettingField | CustomView, field: SettingEntry, index?: number) { + if (isSettingField(item)) { + if (item.isGroup) { + return <SettingGroupView field={item} key={item.id} />; + } else { + return <SettingFieldView field={item} key={item.id} />; + } + } else { + return createContent(item, { key: index, field }); + } +} + +@observer +export default class SettingsPane extends Component<{ target: SettingTopEntry | SettingField }> { + shouldComponentUpdate() { + return false; + } + + render() { + const { target } = this.props; + const items = target.items + return ( + <div className="lc-settings-pane"> + {/* todo: add head for single use */} + <PopupService> + <div className="lc-settings-content"> + {items.map((item, index) => createSettingFieldView(item, target, index))} + </div> + </PopupService> + </div> + ); + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx b/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx new file mode 100644 index 000000000..caf45bc22 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx @@ -0,0 +1,121 @@ +import React, { Component, PureComponent } from 'react'; +import { Tab, Breadcrumb } from '@alifd/next'; +import { Title, createIcon, observer } from '@ali/lowcode-globals'; +import { Node, isSettingField, SettingField } from '@ali/lowcode-designer'; +import Editor from '@ali/lowcode-editor-core'; +import { SettingsMain } from './main'; +import SettingsPane from './settings-pane'; + +@observer +export default class SettingsMainView extends Component<{ editor: Editor }> { + private main = new SettingsMain(this.props.editor); + + shouldComponentUpdate() { + return false; + } + + componentWillUnmount() { + this.main.purge(); + } + + renderBreadcrumb() { + const { settings } = this.main; + if (!settings) { + return null; + } + if (settings.isMultiple) { + return ( + <div className="lc-settings-navigator"> + {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} + <Title title={settings.componentMeta!.title} /> + <span>x {settings.nodes.length}</span> + </div> + ); + } + + let node: Node | null = settings.first; + const items = []; + let l = 3; + while (l-- > 0 && node) { + const props = + l === 2 + ? {} + : { + onMouseOver: hoverNode.bind(null, node, true), + onMouseOut: hoverNode.bind(null, node, false), + onClick: selectNode.bind(null, node), + }; + items.unshift(<Breadcrumb.Item {...props} key={node.id}><Title title={node.title} /></Breadcrumb.Item>); + node = node.parent; + } + + return ( + <div className="lc-settings-navigator"> + {createIcon(this.main.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} + <Breadcrumb className="lc-settings-node-breadcrumb">{items}</Breadcrumb> + </div> + ); + } + + render() { + const { settings } = this.main; + if (!settings) { + // 未选中节点,提示选中 或者 显示根节点设置 + return ( + <div className="lc-settings-main"> + <div className="lc-settings-notice"> + <p>请在左侧画布选中节点</p> + </div> + </div> + ); + } + + if (!settings.isSameComponent) { + // todo: future support 获取设置项交集编辑 + return ( + <div className="lc-settings-main"> + <div className="lc-settings-notice"> + <p>请选中同一类型节点编辑</p> + </div> + </div> + ); + } + + const { items } = settings; + if (items.length > 5 || items.some(item => !isSettingField(item) || !item.isGroup)) { + return ( + <div className="lc-settings-main"> + {this.renderBreadcrumb()} + <div className="lc-settings-body"> + <SettingsPane target={settings} /> + </div> + </div> + ); + } + + return ( + <div className="lc-settings-main"> + <Tab + navClassName="lc-settings-tabs" + animation={false} + excessMode="dropdown" + contentClassName="lc-settings-tabs-content" + extra={this.renderBreadcrumb()} + > + {(items as SettingField[]).map(field => ( + <Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}> + <SettingsPane target={field} key={field.id} /> + </Tab.Item> + ))} + </Tab> + </div> + ); + } +} + +function hoverNode(node: Node, flag: boolean) { + node.hover(flag); +} +function selectNode(node: Node) { + node.select(); +} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/style.less b/packages/vision-polyfill/src/skeleton/components/settings/style.less new file mode 100644 index 000000000..9b2c2b403 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/style.less @@ -0,0 +1,124 @@ +.lc-settings-main { + position: relative; + height: 100%; + overflow: hidden; + + .lc-settings-notice { + text-align: center; + font-size: 12px; + font-family: PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica,Arial,sans-serif; + color: var(--color-text ,rgba(0,0,0,.6)); + padding: 50px 15px 0; + } + + .lc-settings-navigator { + height: 30px; + display: flex; + align-items: center; + padding-left: 5px; + border-bottom: 1px solid var(--color-line-normal); + .lc-settings-navigator-icon { + width: 16px; + height: 16px; + * { + fill: var(--color-icon-normal, rgba(31, 56, 88, 0.4)); + } + } + .lc-settings-node-breadcrumb { + margin-left: 5px; + .next-breadcrumb { + display: inline-flex; + align-items: stretch; + height: 24px; + } + .next-breadcrumb-item { + display: inline-flex; + align-items: center; + cursor: default; + &:not(:last-child):hover { + cursor: pointer; + } + .next-breadcrumb-text { + font-size: 12px; + } + } + } + } + + .lc-settings-body { + position: absolute; + top: 30px; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + } + + // ====== reset fusion-tabs ===== + .lc-settings-tabs { + position: relative; + overflow: visible; + > .next-tabs-nav-extra { + position: absolute !important; + top: 40px !important; + left: 0 !important; + height: 30px; + right: 0; + transform: none !important; + + } + .next-tabs-nav-container { + .next-tabs-nav { + display: flex; + .next-tabs-tab.lc-settings-tab-item { + flex: 1; + min-width: 0; + outline: none; + .next-tabs-tab-inner { + text-align: center; + padding: 12px 0; + } + } + } + } + } + + .lc-settings-tabs-content { + position: absolute; + top: 70px; + left:0; + right: 0; + bottom: 0; + .next-tabs-tabpane { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; + overflow-y: auto; + outline: none !important; + box-shadow: none !important; + } + } + .lc-outline-pane { + position: absolute; + z-index: 100; + background-color: white; + top: 0; + bottom: 0; + display: none; + } +} + +.lc-settings-pane { + padding-bottom: 50px; + .next-btn { + line-height: 1 !important; + } +} + +html.lc-cursor-dragging:not(.lowcode-has-fixed-tree) { + .lc-settings-main .lc-outline-pane { + display: block; + } +} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/utils.js b/packages/vision-polyfill/src/skeleton/components/settings/utils.js new file mode 100644 index 000000000..b8f5bbdcc --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/components/settings/utils.js @@ -0,0 +1,41 @@ +function getHotterFromSetter(setter) { + return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line +} + +function getTransducerFromSetter(setter) { + return setter && ( + setter.transducer || setter.Transducer + || (setter.type && (setter.type.transducer || setter.type.Transducer)) + ) || null; // eslint-disable-line +} + +function combineTransducer(transducer, arr, context) { + if (!transducer && Array.isArray(arr)) { + const [toHot, toNative] = arr; + transducer = { toHot, toNative }; + } + + return { + toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line + toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line + }; +} + +export class Transducer { + constructor(context, config) { + this.setterTransducer = combineTransducer( + getTransducerFromSetter(config.setter), + getHotterFromSetter(config.setter), + context, + ); + this.context = context; + } + + toHot(data) { + return this.setterTransducer.toHot(data); + } + + toNative(data) { + return this.setterTransducer.toNative(data); + } +} diff --git a/packages/vision-polyfill/src/skeleton/widget-views.tsx b/packages/vision-polyfill/src/skeleton/components/widget-views.tsx similarity index 94% rename from packages/vision-polyfill/src/skeleton/widget-views.tsx rename to packages/vision-polyfill/src/skeleton/components/widget-views.tsx index 6f8037aa3..6d32600b1 100644 --- a/packages/vision-polyfill/src/skeleton/widget-views.tsx +++ b/packages/vision-polyfill/src/skeleton/components/widget-views.tsx @@ -1,13 +1,13 @@ import { Component, ReactElement } from 'react'; import classNames from 'classnames'; import { Title, observer } from '@ali/lowcode-globals'; -import { DockProps } from './types'; -import PanelDock from './panel-dock'; -import { composeTitle } from './utils'; -import WidgetContainer from './widget-container'; -import Panel from './panel'; -import { IWidget } from './widget'; -import { SkeletonEvents } from './skeleton'; +import { DockProps } from '../types'; +import PanelDock from '../widget/panel-dock'; +import { composeTitle } from '../widget/utils'; +import WidgetContainer from '../widget/widget-container'; +import Panel from '../widget/panel'; +import { IWidget } from '../widget/widget'; +import { SkeletonEvents } from '../skeleton'; export function DockView({ title, icon, description, size, className, onClick }: DockProps) { return ( diff --git a/packages/vision-polyfill/src/skeleton/dock.ts b/packages/vision-polyfill/src/skeleton/dock.ts index 5fd726e41..721c6b9c6 100644 --- a/packages/vision-polyfill/src/skeleton/dock.ts +++ b/packages/vision-polyfill/src/skeleton/dock.ts @@ -2,8 +2,8 @@ import { ReactNode, createElement } from 'react'; import { uniqueId, createContent, obx } from '@ali/lowcode-globals'; import { DockConfig } from "./types"; import { Skeleton } from './skeleton'; -import { DockView, WidgetView } from './widget-views'; -import { IWidget } from './widget'; +import { DockView, WidgetView } from './components/widget-views'; +import { IWidget } from './widget/widget'; /** * 带图标(主要)/标题(次要)的扩展 diff --git a/packages/vision-polyfill/src/skeleton/icons/convert.tsx b/packages/vision-polyfill/src/skeleton/icons/convert.tsx new file mode 100644 index 000000000..71ab8630e --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/icons/convert.tsx @@ -0,0 +1,16 @@ +import { SVGIcon, IconProps } from "@ali/lowcode-globals"; + +export function IconConvert(props: IconProps) { + return ( + <SVGIcon viewBox="0 0 1024 1024" {...props}> + <path d="M508.16 889.6C291.84 889.6 115.2 714.24 115.2 497.92 115.2 281.6 291.84 106.24 509.44 106.24c43.52 0 85.76 6.4 124.16 20.48l-10.24 30.72c-35.84-11.52-72.96-17.92-113.92-17.92-199.68 0-362.24 161.28-362.24 359.68s162.56 358.4 360.96 358.4 359.68-161.28 359.68-359.68c0-66.56-17.92-131.84-51.2-185.6L844.8 294.4c37.12 60.16 56.32 130.56 56.32 203.52-1.28 216.32-176.64 391.68-392.96 391.68z" /> + <path d="M627.2 140.8m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> + <path d="M832 304.64m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> + <path d="M348.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + <path d="M508.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + <path d="M668.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> + </SVGIcon> + ); +} + +IconConvert.displayName = 'Convert'; diff --git a/packages/vision-polyfill/src/skeleton/index.ts b/packages/vision-polyfill/src/skeleton/index.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/vision-polyfill/src/skeleton/bottom-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx similarity index 92% rename from packages/vision-polyfill/src/skeleton/bottom-area.tsx rename to packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx index 89834b0c2..ae251cd2e 100644 --- a/packages/vision-polyfill/src/skeleton/bottom-area.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx @@ -1,8 +1,8 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; -import Panel from './panel'; +import Area from '../area'; +import Panel from '../widget/panel'; @observer export default class BottomArea extends Component<{ area: Area<any, Panel> }> { diff --git a/packages/vision-polyfill/src/skeleton/left-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-area.tsx similarity index 97% rename from packages/vision-polyfill/src/skeleton/left-area.tsx rename to packages/vision-polyfill/src/skeleton/layouts/left-area.tsx index 87df6170c..8fe785055 100644 --- a/packages/vision-polyfill/src/skeleton/left-area.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/left-area.tsx @@ -1,7 +1,7 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; +import Area from '../area'; @observer export default class LeftArea extends Component<{ area: Area }> { diff --git a/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx similarity index 91% rename from packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx rename to packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx index 89ccc37a7..bae3a9eae 100644 --- a/packages/vision-polyfill/src/skeleton/left-fixed-pane.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx @@ -2,9 +2,9 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; import { Button, Icon } from '@alifd/next'; -import Area from './area'; -import { PanelConfig } from './types'; -import Panel from './panel'; +import Area from '../area'; +import { PanelConfig } from '../types'; +import Panel from '../widget/panel'; @observer export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { diff --git a/packages/vision-polyfill/src/skeleton/left-float-pane.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx similarity index 96% rename from packages/vision-polyfill/src/skeleton/left-float-pane.tsx rename to packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx index a38433a0e..fefe6d525 100644 --- a/packages/vision-polyfill/src/skeleton/left-float-pane.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx @@ -2,8 +2,8 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; import { Button, Icon } from '@alifd/next'; -import Area from './area'; -import Panel from './panel'; +import Area from '../area'; +import Panel from '../widget/panel'; @observer export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { diff --git a/packages/vision-polyfill/src/skeleton/main-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/main-area.tsx similarity index 81% rename from packages/vision-polyfill/src/skeleton/main-area.tsx rename to packages/vision-polyfill/src/skeleton/layouts/main-area.tsx index 45242805e..a531398b0 100644 --- a/packages/vision-polyfill/src/skeleton/main-area.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/main-area.tsx @@ -1,9 +1,9 @@ import { Component } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; -import Panel from './panel'; -import Widget from './widget'; +import Area from '../area'; +import Panel from '../widget/panel'; +import Widget from '../widget/widget'; @observer export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> { diff --git a/packages/vision-polyfill/src/skeleton/right-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/right-area.tsx similarity index 91% rename from packages/vision-polyfill/src/skeleton/right-area.tsx rename to packages/vision-polyfill/src/skeleton/layouts/right-area.tsx index 89daa1ea2..b27223f1f 100644 --- a/packages/vision-polyfill/src/skeleton/right-area.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/right-area.tsx @@ -1,8 +1,8 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; -import Panel from './panel'; +import Area from '../area'; +import Panel from '../widget/panel'; @observer export default class RightArea extends Component<{ area: Area<any, Panel> }> { diff --git a/packages/vision-polyfill/src/skeleton/layouts/theme.less b/packages/vision-polyfill/src/skeleton/layouts/theme.less new file mode 100644 index 000000000..5171884c0 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/layouts/theme.less @@ -0,0 +1,60 @@ +@import '~@ali/ve-less-variables/index.less'; + +/* + * Theme Colors + * + * 乐高设计器的主要主题色变量 + */ +:root { + --color-brand: @brand-color-1; + --color-brand-light: @brand-color-2; + --color-brand-dark: @brand-color-3; + + --color-canvas-background: @normal-alpha-8; + + --color-icon-normal: @normal-alpha-4; + --color-icon-hover: @normal-alpha-3; + --color-icon-active: @brand-color-1; + --color-icon-reverse: @white-alpha-1; + + --color-line-normal: @normal-alpha-7; + --color-line-darken: darken(@normal-alpha-7, 10%); + + --color-title: @dark-alpha-2; + --color-text: @dark-alpha-3; + --color-text-dark: darken(@dark-alpha-3, 10%); + --color-text-light: lighten(@dark-alpha-3, 10%); + --color-text-reverse: @white-alpha-2; + --color-text-regular: @normal-alpha-2; + + --color-field-label: @dark-alpha-4; + --color-field-text: @dark-alpha-3; + --color-field-placeholder: @normal-alpha-5; + --color-field-border: @normal-alpha-5; + --color-field-border-hover: @normal-alpha-4; + --color-field-border-active: @normal-alpha-3; + --color-field-background: @white-alpha-1; + + --color-function-success: @brand-success; + --color-function-success-dark: darken(@brand-success, 10%); + --color-function-success-light: lighten(@brand-success, 10%); + --color-function-warning: @brand-warning; + --color-function-warning-dark: darken(@brand-warning, 10%); + --color-function-warning-light: lighten(@brand-warning, 10%); + --color-function-information: @brand-link-hover; + --color-function-information-dark: darken(@brand-link-hover, 10%); + --color-function-information-light: lighten(@brand-link-hover, 10%); + --color-function-error: @brand-danger; + --color-function-error-dark: darken(@brand-danger, 10%); + --color-function-error-light: lighten(@brand-danger, 10%); + + --color-pane-background: @white-alpha-1; + --color-block-background-normal: @white-alpha-1; + --color-block-background-light: @normal-alpha-9; + --color-block-background-shallow: @normal-alpha-8; + --color-block-background-dark: @normal-alpha-7; + --color-block-background-disabled: @normal-alpha-6; + --color-block-background-deep-dark: @normal-5; + --color-layer-mask-background: @dark-alpha-7; + --color-layer-tooltip-background: rgba(44,47,51,0.8); +} diff --git a/packages/vision-polyfill/src/skeleton/toolbar.tsx b/packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx similarity index 97% rename from packages/vision-polyfill/src/skeleton/toolbar.tsx rename to packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx index 7a0c7561a..ea9c02ef0 100644 --- a/packages/vision-polyfill/src/skeleton/toolbar.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx @@ -1,7 +1,7 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; +import Area from '../area'; @observer export default class Toolbar extends Component<{ area: Area }> { diff --git a/packages/vision-polyfill/src/skeleton/top-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/top-area.tsx similarity index 97% rename from packages/vision-polyfill/src/skeleton/top-area.tsx rename to packages/vision-polyfill/src/skeleton/layouts/top-area.tsx index d1c3812d2..13da4d17e 100644 --- a/packages/vision-polyfill/src/skeleton/top-area.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/top-area.tsx @@ -1,7 +1,7 @@ import { Component, Fragment } from 'react'; import classNames from 'classnames'; import { observer } from '@ali/lowcode-globals'; -import Area from './area'; +import Area from '../area'; @observer export default class TopArea extends Component<{ area: Area }> { diff --git a/packages/vision-polyfill/src/skeleton/layouts/workbench.less b/packages/vision-polyfill/src/skeleton/layouts/workbench.less new file mode 100644 index 000000000..92deeeacd --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/layouts/workbench.less @@ -0,0 +1,375 @@ +@import "./theme.less"; + +:root { + --font-family: @font-family; + --font-size-label: @fontSize-4; + --font-size-text: @fontSize-5; + --font-size-btn-large: @fontSize-3; + --font-size-btn-medium: @fontSize-4; + --font-size-btn-small: @fontSize-5; + + --global-border-radius: @global-border-radius; + --input-border-radius: @input-border-radius; + --popup-border-radius: @popup-border-radius; + + --left-area-width: 48px; + --right-area-width: 280px; + --top-area-height: 48px; + --toolbar-height: 36px; + --dock-pane-width: 280px; + --dock-fixed-pane-width: 280px; +} + +@media (min-width: 1860px) { + :root { + --right-area-width: 400px; + --dock-pane-width: 452px; + --dock-fixed-pane-width: 350px; + } +} + +html, +body { + height: 100%; + overflow: hidden; + padding: 0; + margin: 0; + position: relative; + font-family: var(--font-family); + font-size: var(--font-size-text); + color: var(--color-text); + background-color:#EDEFF3; +} + +* { + box-sizing: border-box; +} + + +.lc-titled-panel { + width: 100%; + height: 100%; + position: relative; + .pane-title { + // height: var(--pane-title-height); + background-color: var(--pane-title-bg-color); + display: flex; + align-items: center; + padding: 0 15px; + .my-help-tip { + margin-left: 4px; + } + } + + .pane-body { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + overflow: auto; + .my-tabs { + width: 100%; + height: 100%; + position: relative; + .tabs-title { + display: flex; + height: var(--pane-title-height); + > .tab-title { + cursor: pointer; + padding: 0; + flex: 1; + min-width: 0; + justify-content: center; + border-bottom: 2px solid transparent; + &.actived { + cursor: default; + color: var(--color-text-avtived); + border-bottom-color: #3896ee; + } + } + } + .tabs-content { + position: absolute; + top: var(--pane-title-height); + bottom: 0; + left: 0; + right: 0; + height: calc(100% - var(--pane-title-height)); + overflow: hidden; + } + } + } + + &.titled > .pane-body { + top: var(--pane-title-height); + } +} +.lc-panel { + height: 100%; + width: 100%; + overflow: auto; + &.hidden { + display: none; + } + .pane-title { + height: var(--pane-title-height); + background-color: var(--pane-title-bg-color); + display: flex; + align-items: center; + padding: 0 15px; + .my-help-tip { + margin-left: 4px; + } + } + .my-tabs { + width: 100%; + height: 100%; + position: relative; + .tabs-title { + display: flex; + height: var(--pane-title-height); + margin-right: 30px; + > .tab-title { + cursor: pointer; + padding: 0; + flex: 1; + min-width: 0; + justify-content: center; + border-bottom: 2px solid transparent; + &.actived { + cursor: default; + color: var(--color-text-avtived); + border-bottom-color: #3896ee; + } + } + } + .tabs-content { + position: absolute; + top: var(--pane-title-height); + bottom: 0; + left: 0; + right: 0; + height: calc(100% - var(--pane-title-height)); + overflow: hidden; + } + } +} + +.my-dock { + padding: 0px 10px; + cursor: pointer; + align-self: stretch; + display: flex; + align-items: center; + .my-title-label { + user-select: none; + } + &.actived, &:hover { + background-color: var(--pane-title-bg-color); + .my-title { + color: var(--color-actived); + } + } +} + + +.lc-workbench { + height: 100%; + display: flex; + flex-direction: column; + background-color: #EDEFF3; + .lc-top-area { + height: var(--top-area-height); + background-color: var(--color-pane-background); + width: 100%; + display: flex; + margin-bottom: 2px; + padding: 8px; + .lc-top-area-left{} + .lc-top-area-center{ + flex: 1; + display: flex; + justify-content: flex-end; + margin-right: 8px; + } + .lc-top-area-right{ + display: flex; + align-items: center; + >* { + margin-left: 4px; + margin-right: 4px; + } + } + } + .lc-workbench-body { + flex: 1; + display: flex; + min-height: 0; + position: relative; + .lc-left-float-pane { + position: absolute; + top: 0; + bottom: 0; + width: var(--dock-pane-width); + left: calc(var(--left-area-width) + 1px); + background-color: var(--color-pane-background); + box-shadow: 4px 0 16px 0 rgba(31,50,88,0.08); + z-index: 820; + display: none; + // padding-top: 36px; + &.lc-area-visible { + display: block; + } + .lc-pane-close{ + position: absolute; + right: 10px; + top: 6px; + z-index: 2; + .next-icon{ + line-height: 1; + } + } + .lc-tabs-title { + width: 100%; + height: 36px; + position: relative; + display: center; + display: flex; + justify-content: center; + align-items: center; + background: rgba(31,56,88,0.04); + } + .lc-tabs-content { + position: absolute; + top: 36px; + bottom: 0; + left: 0; + right: 0; + } + } + .lc-left-area { + height: 100%; + width: var(--left-area-width); + background-color: var(--color-pane-background); + display: none; + flex-shrink: 0; + flex-direction: column; + justify-content: space-between; + &.lc-area-visible { + display: flex; + } + .lc-left-area-top, + .lc-left-area-bottom{ + width: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + .lc-title{ + padding: 12px; + flex-direction: column; + &.has-tip{ + cursor: pointer; + } + &.actived{ + color: #0079F2; + } + .lc-title-icon{ + margin: 0; + .next-icon:before { + line-height: 1 !important; + } + } + } + } + .lc-left-area-top{ + padding-top: 12px; + } + .lc-left-area-bottom{ + padding-bottom: 12px; + } + } + .lc-left-fixed-pane { + width: var(--dock-fixed-pane-width); + background-color: var(--color-pane-background); + height: 100%; + display: none; + flex-shrink: 0; + position: relative; + &.lc-area-visible { + display: block; + } + .lc-pane-close { + position: absolute; + right: 10px; + top: 6px; + z-index: 2; + .next-icon { + line-height: 1; + } + } + } + .lc-left-area.lc-area-visible ~ .lc-left-fixed-pane { + margin-left: 1px; + } + .lc-left-area.lc-area-visible ~ .lc-workbench-center { + margin-left: 2px; + } + .lc-outline-pane{ + .lc-outline-tree .tree-node .tree-node-title{ + border-bottom: none; + } + } + .lc-workbench-center { + flex: 1; + display: flex; + flex-direction: column; + .lc-toolbar { + height: var(--toolbar-height); + background-color: var(--color-pane-background); + padding: 8px 16px; + } + .lc-main-area { + flex: 1; + } + .lc-bottom-area { + height: var(--bottom-area-height); + background-color: var(--color-pane-background); + display: none; + &.lc-area-visible { + display: block; + } + } + } + .lc-right-area { + height: 100%; + width: var(--right-area-width); + background-color: var(--color-pane-background); + display: none; + flex-shrink: 0; + margin-left: 2px; + &.lc-area-visible { + display: block; + } + .lc-settings-tabs{ + > .next-tabs-nav-extra{ + top: 36px !important; + } + .lc-settings-tab-item{ + .next-tabs-tab-inner{ + font-size: 12px; + line-height: 12px; + } + } + .lc-title{ + color: inherit; + line-height: inherit !important; + } + } + .lc-settings-tabs-content{ + top: 66px; + } + } + } +} diff --git a/packages/vision-polyfill/src/skeleton/workbench.tsx b/packages/vision-polyfill/src/skeleton/layouts/workbench.tsx similarity index 96% rename from packages/vision-polyfill/src/skeleton/workbench.tsx rename to packages/vision-polyfill/src/skeleton/layouts/workbench.tsx index aa92a2ae6..c55633f39 100644 --- a/packages/vision-polyfill/src/skeleton/workbench.tsx +++ b/packages/vision-polyfill/src/skeleton/layouts/workbench.tsx @@ -1,6 +1,6 @@ import { Component } from 'react'; import { TipContainer, observer } from '@ali/lowcode-globals'; -import { Skeleton } from './skeleton'; +import { Skeleton } from '../skeleton'; import TopArea from './top-area'; import LeftArea from './left-area'; import LeftFixedPane from './left-fixed-pane'; diff --git a/packages/vision-polyfill/src/skeleton/panel.ts b/packages/vision-polyfill/src/skeleton/panel.ts index 3a2da4def..c9e2e890d 100644 --- a/packages/vision-polyfill/src/skeleton/panel.ts +++ b/packages/vision-polyfill/src/skeleton/panel.ts @@ -2,9 +2,9 @@ import { createElement, ReactNode } from 'react'; import { obx, uniqueId, createContent, TitleContent } from '@ali/lowcode-globals'; import WidgetContainer from './widget-container'; import { PanelConfig, HelpTipConfig } from './types'; -import { TitledPanelView, TabsPanelView, PanelView } from './widget-views'; +import { TitledPanelView, TabsPanelView, PanelView } from './components/widget-views'; import { Skeleton } from './skeleton'; -import { composeTitle } from './utils'; +import { composeTitle } from './widget/utils'; import { IWidget } from './widget'; export default class Panel implements IWidget { diff --git a/packages/vision-polyfill/src/skeleton/skeleton.ts b/packages/vision-polyfill/src/skeleton/skeleton.ts index a5627157c..2ed0c7b39 100644 --- a/packages/vision-polyfill/src/skeleton/skeleton.ts +++ b/packages/vision-polyfill/src/skeleton/skeleton.ts @@ -9,16 +9,19 @@ import { isDockConfig, isPanelDockConfig, isPanelConfig, + DividerConfig, + isDividerConfig } from './types'; -import Panel, { isPanel } from './panel'; -import WidgetContainer from './widget-container'; +import Panel, { isPanel } from './widget/panel'; +import WidgetContainer from './widget/widget-container'; import Area from './area'; -import Widget, { isWidget, IWidget } from './widget'; -import PanelDock from './panel-dock'; -import Dock from './dock'; -import { Stage, StageConfig } from './stage'; +import Widget, { isWidget, IWidget } from './widget/widget'; +import PanelDock from './widget/panel-dock'; +import Dock from './widget/dock'; +import { Stage, StageConfig } from './widget/stage'; import { isValidElement } from 'react'; import { isPlainObject } from 'globals/src/utils'; +import { Divider } from '@alifd/next'; export enum SkeletonEvents { PANEL_DOCK_ACTIVE = 'skeleton.panel-dock.active', @@ -33,8 +36,8 @@ export class Skeleton { private panels = new Map<string, Panel>(); private containers = new Map<string, WidgetContainer<any>>(); readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; - readonly topArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; - readonly toolbar: Area<DockConfig | PanelDockConfig | DialogDockConfig>; + readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; + readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; readonly leftFixedArea: Area<PanelConfig, Panel>; readonly leftFloatArea: Area<PanelConfig, Panel>; readonly rightArea: Area<PanelConfig, Panel>; @@ -144,7 +147,7 @@ export class Skeleton { } private setupPlugins() { - const { config, componentsMap } = this.editor; + const { config, components: componentsMap } = this.editor; const { plugins } = config; if (!plugins) { return; @@ -200,18 +203,23 @@ export class Skeleton { if (isPanelDockConfig(config)) { widget = new PanelDock(this, config); } else if (false) { + // DialogDock // others... } else { widget = new Dock(this, config); } + } else if (isDividerConfig(config)) { + widget = new Widget(this, { + ...config, + type: 'Widget', + content: Divider, + }); } else if (isPanelConfig(config)) { widget = this.createPanel(config); } else { widget = new Widget(this, config as WidgetConfig); } - // ? - // this.editor.set(`skeleton.${widget.name}`, widget); return widget; } @@ -219,8 +227,6 @@ export class Skeleton { config = this.parseConfig(config); const panel = new Panel(this, config); this.panels.set(panel.name, panel); - // ? - // this.editor.set(`skeleton.${panel.name}`, panel); return panel; } diff --git a/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts b/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts new file mode 100644 index 000000000..80ad16cc1 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts @@ -0,0 +1,255 @@ +import { TransformedComponentMetadata, FieldConfig } from '@ali/lowcode-globals'; + +export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { + const { componentName, configure = {} } = metadata; + if (componentName === 'Leaf') { + return { + ...metadata, + configure: { + ...configure, + combined: [ + { + name: 'children', + title: { type: 'i18n', 'zh-CN': '内容设置', 'en-US': 'Content' }, + setter: { + componentName: 'MixinSetter', + props: { + // TODO: + setters: [ + { + componentName: 'StringSetter', + props: { + // TODO: textarea mode + multiline: true, + }, + initialValue: '', + }, + { + componentName: 'ExpressionSetter', + initialValue: { + type: 'JSExpression', + value: '', + }, + }, + ], + }, + }, + }, + ], + }, + }; + } + + const { props, events = {}, styles } = configure as any; + const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; + const eventsDefinition: any[] = []; + const supportedLifecycles = + events.supportedLifecycles || + (isRoot + ? [ + { + description: '初始化时', + name: 'constructor', + }, + { + description: '装载后', + name: 'componentDidMount', + }, + { + description: '更新时', + name: 'componentDidMount', + }, + { + description: '卸载时', + name: 'componentWillUnmount', + }, + ] + : null); + if (supportedLifecycles) { + eventsDefinition.push({ + type: 'lifeCycleEvent', + title: '生命周期', + list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); + } + if (events.supportedEvents) { + eventsDefinition.push({ + type: 'events', + title: '事件', + list: (events.supportedEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), + }); + } + // 通用设置 + const propsGroup = props || []; + propsGroup.push({ + name: '#generals', + title: { type: 'i18n', 'zh-CN': '通用', 'en-US': 'General' }, + items: [ + { + name: 'id', + title: 'ID', + setter: 'StringSetter', + }, + { + name: 'key', + title: 'Key', + // todo: use Mixin + setter: 'StringSetter', + }, + { + name: 'ref', + title: 'Ref', + setter: 'StringSetter', + }, + /* + { + name: '!more', + title: '更多', + setter: 'PropertiesSetter', + },*/ + ], + }); + const combined: FieldConfig[] = [ + { + title: { type: 'i18n', 'zh-CN': '属性', 'en-US': 'Props' }, + name: '#props', + items: propsGroup, + }, + ]; + const stylesGroup: FieldConfig[] = []; + if (styles?.supportClassName) { + stylesGroup.push({ + name: 'className', + title: { type: 'i18n', 'zh-CN': '类名绑定', 'en-US': 'ClassName' }, + setter: 'ClassNameSetter', + }); + } + if (styles?.supportInlineStyle) { + stylesGroup.push({ + name: 'style', + title: { type: 'i18n', 'zh-CN': '行内样式', 'en-US': 'Style' }, + setter: 'StyleSetter', + }); + } + if (stylesGroup.length > 0) { + combined.push({ + name: '#styles', + title: { type: 'i18n', 'zh-CN': '样式', 'en-US': 'Styles' }, + items: stylesGroup, + }); + } + + if (eventsDefinition.length > 0) { + combined.push({ + name: '#events', + title: { type: 'i18n', 'zh-CN': '事件', 'en-US': 'Events' }, + items: [ + { + name: '!events', + title: { type: 'i18n', 'zh-CN': '事件设置', 'en-US': 'Events' }, + setter: { + componentName: 'EventsSetter', + props: { + definition: eventsDefinition, + }, + }, + getValue(field: SettingField, val?: any[]) { + // todo: + return val; + }, + + setValue(field: SettingField, eventDataList: any[]) { + // todo: + return; + }, + }, + ], + }); + } + + if (isRoot) { + /* + combined.push({ + name: '#advanced', + title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, + items: [], + }); + */ + } else { + combined.push({ + name: '#advanced', + title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, + items: [ + { + name: '__condition', + title: { type: 'i18n', 'zh-CN': '条件显示', 'en-US': 'Condition' }, + setter: 'ExpressionSetter', + }, + { + name: '#loop', + title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' }, + items: [ + { + name: '__loop', + title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, + setter: { + componentName: 'MixinSetter', + props: { + // TODO: + setters: [ + { + componentName: 'JSONSetter', + props: { + mode: 'popup', + placeholder: { type: 'i18n', 'zh-CN': '编辑数据', 'en-US': 'Edit Data' }, + }, + }, + { + componentName: 'ExpressionSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '绑定数据', 'en-US': 'Bind Data' }, + }, + }, + ], + }, + }, + }, + { + name: '__loopArgs.0', + title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' }, + setter: { + componentName: 'StringSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '默认为: item', 'en-US': 'Defaults: item' }, + } + }, + }, + { + name: '__loopArgs.1', + title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' }, + setter: { + componentName: 'StringSetter', + props: { + placeholder: { type: 'i18n', 'zh-CN': '默认为: index', 'en-US': 'Defaults: index' }, + } + }, + }, + { + name: 'key', + title: 'Key', + setter: 'ExpressionSetter', + }, + ], + }, + ], + }); + } + + return { + ...metadata, + configure: { + ...configure, + combined, + }, + }; +} diff --git a/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts b/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts new file mode 100644 index 000000000..43bd44221 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts @@ -0,0 +1,232 @@ +import { + FieldConfig, + PropConfig, + PropType, + SetterType, + OneOf, + Shape, + ObjectOf, + ArrayOf, + TransformedComponentMetadata, +} from '@ali/lowcode-globals'; + +function propConfigToFieldConfig(propConfig: PropConfig): FieldConfig { + const { name, description } = propConfig; + const title = { + label: { + type: 'i18n', + 'en-US': name, + 'zh-CN': description?.slice(0, 10) || name, + }, + tip: description ? `${name} | ${description}` : undefined, + }; + return { + title, + ...propConfig, + setter: propTypeToSetter(propConfig.propType), + }; +} + +function propTypeToSetter(propType: PropType): SetterType { + let typeName: string; + let isRequired: boolean | undefined = false; + if (typeof propType === 'string') { + typeName = propType; + } else { + typeName = propType.type; + isRequired = propType.isRequired; + } + // TODO: use mixinSetter wrapper + switch (typeName) { + case 'string': + return { + componentName: 'StringSetter', + isRequired, + initialValue: '', + }; + + case 'number': + return { + componentName: 'NumberSetter', + isRequired, + initialValue: 0, + }; + case 'bool': + return { + componentName: 'NumberSetter', + isRequired, + initialValue: false, + }; + case 'oneOf': + const dataSource = ((propType as OneOf).value || []).map((value, index) => { + const t = typeof value; + return { + label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`, + value, + }; + }); + const componentName = dataSource.length > 4 ? 'SelectSetter' : 'RadioGroupSetter'; + return { + componentName, + props: { dataSource }, + isRequired, + initialValue: dataSource[0] ? dataSource[0].value : null, + }; + + case 'element': + case 'node': // TODO: use Mixin + return { + // slotSetter + componentName: 'NodeSetter', + props: { + mode: typeName, + }, + isRequired, + initialValue: { + type: 'JSSlot', + value: '', + }, + }; + case 'shape': + case 'exact': + const items = (propType as Shape).value.map((item) => propConfigToFieldConfig(item)); + return { + componentName: 'ObjectSetter', + props: { + config: { + items, + extraSetter: typeName === 'shape' ? propTypeToSetter('any') : null, + }, + }, + isRequired, + initialValue: (field: any) => { + const data: any = {}; + items.forEach((item) => { + let initial = item.defaultValue; + if (initial == null && item.setter && typeof item.setter === 'object') { + initial = (item.setter as any).initialValue; + } + data[item.name] = initial ? (typeof initial === 'function' ? initial(field) : initial) : null; + }); + return data; + }, + }; + case 'object': + case 'objectOf': + return { + componentName: 'ObjectSetter', + props: { + config: { + extraSetter: propTypeToSetter(typeName === 'objectOf' ? (propType as ObjectOf).value : 'any'), + }, + }, + isRequired, + }; + case 'array': + case 'arrayOf': + return { + componentName: 'ArraySetter', + props: { + itemSetter: propTypeToSetter(typeName === 'arrayOf' ? (propType as ArrayOf).value : 'any'), + }, + isRequired, + initialValue: [], + }; + case 'func': + return { + componentName: 'FunctionSetter', + isRequired, + initialValue: { + type: 'JSFunction', + value: 'function(){}', + }, + }; + case 'oneOfType': + return { + componentName: 'MixinSetter', + props: { + // TODO: + // setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), + }, + isRequired, + }; + } + + return { + componentName: 'MixinSetter', + isRequired, + }; +} + +const EVENT_RE = /^on[A-Z][\w]*$/; + +export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { + const { configure } = metadata; + if (configure.props) { + return metadata; + } + + if (!metadata.props) { + return { + ...metadata, + configure: { + ...configure, + props: [], + }, + }; + } + const { component = {}, events = {}, styles = {} } = configure; + const supportedEvents: any[] | null = (events as any).supportedEvents ? null : []; + const props: FieldConfig[] = []; + + metadata.props.forEach((prop) => { + const { name, propType, description } = prop; + if ( + name === 'children' && + (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') + ) { + if (component.isContainer !== false) { + component.isContainer = true; + return; + } + } + + if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) { + if (supportedEvents) { + supportedEvents.push({ + name, + description, + }); + (events as any).supportedEvents = supportedEvents; + } + return; + } + + if (name === 'className' && (propType === 'string' || propType === 'any')) { + if ((styles as any).supportClassName == null) { + (styles as any).supportClassName = true; + } + return; + } + + if (name === 'style' && (propType === 'object' || propType === 'any')) { + if ((styles as any).supportInlineStyle == null) { + (styles as any).supportInlineStyle = true; + } + return; + } + + props.push(propConfigToFieldConfig(prop)); + }); + + return { + ...metadata, + configure: { + ...configure, + props, + events, + styles, + component, + }, + }; +} diff --git a/packages/vision-polyfill/src/skeleton/transducers/register.ts b/packages/vision-polyfill/src/skeleton/transducers/register.ts new file mode 100644 index 000000000..a09e685ed --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/transducers/register.ts @@ -0,0 +1,9 @@ +import { registerMetadataTransducer } from '@ali/lowcode-globals'; +import parseProps from './parse-props'; +import addonCombine from './addon-combine'; + +// parseProps +registerMetadataTransducer(parseProps, 10, 'parse-props'); + +// addon/platform custom +registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/vision-polyfill/src/skeleton/types.ts b/packages/vision-polyfill/src/skeleton/types.ts index 2ae7df543..b44b7b165 100644 --- a/packages/vision-polyfill/src/skeleton/types.ts +++ b/packages/vision-polyfill/src/skeleton/types.ts @@ -14,7 +14,6 @@ export interface IWidgetBaseConfig { export interface WidgetConfig extends IWidgetBaseConfig { type: "Widget"; - name: string; // as pluginKey props?: { align?: "left" | "right" | "bottom" | "center" | "top"; }; @@ -22,7 +21,7 @@ export interface WidgetConfig extends IWidgetBaseConfig { } export function isWidgetConfig(obj: any): obj is WidgetConfig { - return obj && obj.type === "Custom"; + return obj && obj.type === "Widget"; } export interface DockProps { @@ -34,6 +33,17 @@ export interface DockProps { onClick?: () => void; } +export interface DividerConfig extends IWidgetBaseConfig { + type: "Divider"; + props?: { + align?: "left" | "right" | "center"; + }; +} + +export function isDividerConfig(obj: any): obj is DividerConfig { + return obj && obj.type === "Divider"; +} + export interface IDockBaseConfig extends IWidgetBaseConfig { props?: DockProps & { align?: "left" | "right" | "bottom" | "center" | "top"; diff --git a/packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts b/packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts new file mode 100644 index 000000000..e69de29bb diff --git a/packages/vision-polyfill/src/skeleton/widget/dock.ts b/packages/vision-polyfill/src/skeleton/widget/dock.ts new file mode 100644 index 000000000..019b2e321 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/widget/dock.ts @@ -0,0 +1,86 @@ +import { ReactNode, createElement } from 'react'; +import { uniqueId, createContent, obx } from '@ali/lowcode-globals'; +import { DockConfig } from "../types"; +import { Skeleton } from '../skeleton'; +import { DockView, WidgetView } from '../components/widget-views'; +import { IWidget } from './widget'; + +/** + * 带图标(主要)/标题(次要)的扩展 + */ +export default class Dock implements IWidget { + readonly isWidget = true; + readonly id = uniqueId('dock'); + readonly name: string; + readonly align?: string; + + @obx.ref private _visible: boolean = true; + get visible(): boolean { + return this._visible; + } + + get content(): ReactNode { + return createElement(WidgetView, { + widget: this, + key: this.id, + }); + } + + private inited: boolean = false; + private _body: ReactNode; + get body() { + if (this.inited) { + return this._body; + } + + const { props, content, contentProps } = this.config; + + if (content) { + this._body = createContent(content, { + ...contentProps, + config: this.config, + editor: this.skeleton.editor, + }); + } else { + this._body = createElement(DockView, props); + } + return this._body; + } + + constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { + const { props = {}, name } = config; + this.name = name; + this.align = props.align; + } + + setVisible(flag: boolean) { + if (flag === this._visible) { + return; + } + if (flag) { + this._visible = true; + } else if (this.inited) { + this._visible = false; + } + } + + getContent() { + return this.content; + } + + getName() { + return this.name; + } + + hide() { + this.setVisible(false); + } + + show() { + this.setVisible(true); + } + + toggle() { + this.setVisible(!this._visible); + } +} diff --git a/packages/vision-polyfill/src/skeleton/panel-dock.ts b/packages/vision-polyfill/src/skeleton/widget/panel-dock.ts similarity index 92% rename from packages/vision-polyfill/src/skeleton/panel-dock.ts rename to packages/vision-polyfill/src/skeleton/widget/panel-dock.ts index 7deca60c9..c47d3290a 100644 --- a/packages/vision-polyfill/src/skeleton/panel-dock.ts +++ b/packages/vision-polyfill/src/skeleton/widget/panel-dock.ts @@ -1,11 +1,10 @@ import { uniqueId, obx, computed } from '@ali/lowcode-globals'; import { createElement, ReactNode } from 'react'; -import { Skeleton } from './skeleton'; -import { PanelDockConfig } from './types'; +import { Skeleton } from '../skeleton'; +import { PanelDockConfig } from '../types'; import Panel from './panel'; -import { PanelDockView, WidgetView } from './widget-views'; +import { PanelDockView, WidgetView } from '../components/widget-views'; import { IWidget } from './widget'; -import { composeTitle } from './utils'; export default class PanelDock implements IWidget { readonly isWidget = true; diff --git a/packages/vision-polyfill/src/skeleton/widget/panel.ts b/packages/vision-polyfill/src/skeleton/widget/panel.ts new file mode 100644 index 000000000..9a33c3e44 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/widget/panel.ts @@ -0,0 +1,164 @@ +import { createElement, ReactNode } from 'react'; +import { obx, uniqueId, createContent, TitleContent } from '@ali/lowcode-globals'; +import WidgetContainer from './widget-container'; +import { PanelConfig, HelpTipConfig } from '../types'; +import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views'; +import { Skeleton } from '../skeleton'; +import { composeTitle } from './utils'; +import { IWidget } from './widget'; + +export default class Panel implements IWidget { + readonly isWidget = true; + readonly name: string; + readonly id: string; + @obx.ref inited: boolean = false; + @obx.ref private _actived: boolean = false; + get actived(): boolean { + return this._actived; + } + + get visible(): boolean { + if (this.parent?.visible) { + return this._actived; + } + return false; + } + + readonly isPanel = true; + + private _body?: ReactNode; + get body() { + this.initBody(); + return this._body; + } + + get content(): ReactNode { + if (this.plain) { + return createElement(PanelView, { + panel: this, + key: this.id, + }); + } + return createElement(TitledPanelView, { panel: this, key: this.id }); + } + + readonly title: TitleContent; + readonly help?: HelpTipConfig; + private plain: boolean = false; + + private container?: WidgetContainer<Panel, PanelConfig>; + private parent?: WidgetContainer; + + constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { + const { name, content, props = {} } = config; + const { hideTitleBar, title, icon, description, help, shortcut } = props; + this.name = name; + this.id = uniqueId(`pane:${name}$`); + this.title = composeTitle(title || name, icon, description); + this.plain = hideTitleBar || !title; + this.help = help; + if (Array.isArray(content)) { + this.container = this.skeleton.createContainer( + name, + (item) => { + if (isPanel(item)) { + return item; + } + return this.skeleton.createPanel(item); + }, + true, + () => this.visible, + true, + ); + content.forEach((item) => this.add(item)); + } + // todo: process shortcut + } + + private initBody() { + if (this.inited) { + return; + } + this.inited = true; + if (this.container) { + this._body = createElement(TabsPanelView, { + container: this.container, + }); + } else { + const { content, contentProps } = this.config; + this._body = createContent(content, { + ...contentProps, + editor: this.skeleton.editor, + config: this.config, + panel: this, + }); + } + } + + setParent(parent: WidgetContainer) { + if (parent === this.parent) { + return; + } + if (this.parent) { + this.parent.remove(this); + } + this.parent = parent; + } + + add(item: Panel | PanelConfig) { + return this.container?.add(item); + } + + getPane(name: string): Panel | null { + return this.container?.get(name) || null; + } + + remove(item: Panel | string) { + return this.container?.remove(item); + } + + active(item?: Panel | string | null) { + this.container?.active(item); + } + + getName() { + return this.name; + } + + getContent() { + return this.content; + } + + setActive(flag: boolean) { + if (flag === this._actived) { + // TODO: 如果移动到另外一个 container,会有问题 + return; + } + if (flag) { + if (!this.inited) { + this.initBody(); + } + this._actived = true; + this.parent?.active(this); + } else if (this.inited) { + this._actived = false; + this.parent?.unactive(this); + } + } + + toggle() { + this.setActive(!this._actived); + } + + hide() { + this.setActive(false); + } + + show() { + this.setActive(true); + } +} + +export function isPanel(obj: any): obj is Panel { + return obj && obj.isPanel; +} diff --git a/packages/vision-polyfill/src/skeleton/widget/stage.ts b/packages/vision-polyfill/src/skeleton/widget/stage.ts new file mode 100644 index 000000000..a4bf483f2 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/widget/stage.ts @@ -0,0 +1,51 @@ +import Widget from './widget'; +import { Skeleton } from '../skeleton'; +import { WidgetConfig } from '../types'; + +export interface StageConfig extends WidgetConfig { + isRoot?: boolean; +} + +export class Stage extends Widget { + readonly isRoot: boolean; + private previous?: Stage; + private refer?: { + stage?: Stage; + direction?: 'right' | 'left'; + }; + + constructor(skeleton: Skeleton, config: StageConfig) { + super(skeleton, config); + this.isRoot = config.isRoot || false; + } + + setPrevious(stage: Stage) { + this.previous = stage; + } + + getPrevious() { + return this.previous; + } + + hasBack(): boolean { + return this.previous && !this.isRoot ? true : false; + } + + setRefer(stage: Stage, direction: 'right' | 'left') { + this.refer = { stage, direction }; + } + + setReferRight(stage: Stage) { + this.setRefer(stage, 'right'); + } + + setReferLeft(stage: Stage) { + this.setRefer(stage, 'left'); + } + + getRefer() { + const refer = this.refer; + this.refer = undefined; + return refer; + } +} diff --git a/packages/vision-polyfill/src/skeleton/widget/utils.ts b/packages/vision-polyfill/src/skeleton/widget/utils.ts new file mode 100644 index 000000000..301426a87 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/widget/utils.ts @@ -0,0 +1,28 @@ +import { IconType, TitleContent, isI18nData, TipContent } from '@ali/lowcode-globals'; +import { isValidElement } from 'react'; + +export function composeTitle(title?: TitleContent, icon?: IconType, tip?: TipContent, tipAsTitle?: boolean) { + if (!title) { + title = {}; + if (!icon || tipAsTitle) { + title.label = tip; + tip = undefined; + } + } + if (icon || tip) { + if (typeof title !== 'object' || isValidElement(title) || isI18nData(title)) { + title = { + label: title, + icon, + tip, + }; + } else { + title = { + ...title, + icon, + tip + }; + } + } + return title; +} diff --git a/packages/vision-polyfill/src/skeleton/widget/widget-container.ts b/packages/vision-polyfill/src/skeleton/widget/widget-container.ts new file mode 100644 index 000000000..b34827ae7 --- /dev/null +++ b/packages/vision-polyfill/src/skeleton/widget/widget-container.ts @@ -0,0 +1,134 @@ +import { obx, hasOwnProperty, computed } from '@ali/lowcode-globals'; +import { isPanel } from './panel'; +export interface WidgetItem { + name: string; +} + +export interface Activeable { + setActive(flag: boolean): void; +} + +function isActiveable(obj: any): obj is Activeable { + return obj && obj.setActive; +} + +export default class WidgetContainer<T extends WidgetItem = any, G extends WidgetItem = any> { + @obx.val items: T[] = []; + private maps: { [name: string]: T } = {}; + @obx.ref private _current: T & Activeable | null = null; + + get current() { + return this._current; + } + + constructor( + readonly name: string, + private handle: (item: T | G) => T, + private exclusive: boolean = false, + private checkVisible: () => boolean = () => true, + private defaultSetCurrent: boolean = false, + ) {} + + @computed get visible() { + return this.checkVisible(); + } + + active(nameOrItem?: T | string | null) { + let item: any = nameOrItem; + if (nameOrItem && typeof nameOrItem === 'string') { + item = this.get(nameOrItem); + } + if (!isActiveable(nameOrItem)) { + item = null; + } + + if (this.exclusive) { + if (this._current === item) { + return; + } + if (this._current) { + this._current.setActive(false); + } + this._current = item; + } + + if (item) { + item.setActive(true); + } + } + + unactive(nameOrItem?: T | string | null) { + let item: any = nameOrItem; + if (nameOrItem && typeof nameOrItem === 'string') { + item = this.get(nameOrItem); + } + if (!isActiveable(nameOrItem)) { + item = null; + } + if (this._current === item) { + this._current = null; + } + if (item) { + item.setActive(false); + } + } + + add(item: T | G): T { + item = this.handle(item); + const origin = this.get(item.name); + if (origin === item) { + return origin; + } + const i = origin ? this.items.indexOf(origin) : -1; + if (i > -1) { + this.items[i] = item; + } else { + this.items.push(item); + } + this.maps[item.name] = item; + if (isPanel(item)) { + item.setParent(this); + } + if (this.defaultSetCurrent) { + if (!this._current) { + this.active(item); + } + } + return item; + } + + get(name: string): T | null { + return this.maps[name] || null; + } + + getAt(index: number): T | null { + return this.items[index] || null; + } + + has(name: string): boolean { + return hasOwnProperty(this.maps, name); + } + + indexOf(item: T): number { + return this.items.indexOf(item); + } + + /** + * return indexOf the deletion + */ + remove(item: string | T): number { + const thing = typeof item === 'string' ? this.get(item) : item; + if (!thing) { + return -1; + } + const i = this.items.indexOf(thing); + if (i > -1) { + this.items.splice(i, 1); + } + delete this.maps[thing.name]; + if (thing === this.current) { + this._current = null; + } + return i; + } +} diff --git a/packages/vision-polyfill/src/skeleton/widget.ts b/packages/vision-polyfill/src/skeleton/widget/widget.ts similarity index 92% rename from packages/vision-polyfill/src/skeleton/widget.ts rename to packages/vision-polyfill/src/skeleton/widget/widget.ts index 3b04672b8..1f7a7d84a 100644 --- a/packages/vision-polyfill/src/skeleton/widget.ts +++ b/packages/vision-polyfill/src/skeleton/widget/widget.ts @@ -1,8 +1,8 @@ import { ReactNode, createElement } from 'react'; import { createContent, uniqueId, obx } from '@ali/lowcode-globals'; -import { WidgetConfig, IWidgetBaseConfig } from './types'; -import { Skeleton } from './skeleton'; -import { WidgetView } from './widget-views'; +import { WidgetConfig, IWidgetBaseConfig } from '../types'; +import { Skeleton } from '../skeleton'; +import { WidgetView } from '../components/widget-views'; export interface IWidget { readonly name: string; diff --git a/packages/vision-polyfill/src/vision.ts b/packages/vision-polyfill/src/vision.ts index c8c079467..7bca93882 100644 --- a/packages/vision-polyfill/src/vision.ts +++ b/packages/vision-polyfill/src/vision.ts @@ -9,7 +9,7 @@ import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS } from './const'; import Bus from './bus'; import Symbols from './symbols'; import { skeleton, editor } from './editor'; -import { VisionWorkbench } from './skeleton/workbench'; +import { VisionWorkbench } from './skeleton/layouts/workbench'; import Panes from './panes'; import Exchange from './exchange'; import VisualEngineContext from './context'; From e801a4c47a63abb5bff95553f39705c1418afcb4 Mon Sep 17 00:00:00 2001 From: kangwei <bingbing.yb@alibaba-inc.com> Date: Mon, 27 Apr 2020 02:12:43 +0800 Subject: [PATCH 02/12] big change --- packages/designer/package.json | 4 +- packages/designer/src/component-meta.ts | 68 ++-- packages/designer/src/locale/index.ts | 4 +- packages/editor-core/cloud-build.json | 4 +- packages/editor-core/package.json | 7 +- packages/editor-core/src/di/index.ts | 2 +- packages/editor-core/src/editor.ts | 4 + .../editor-core/src/widgets/tip/tip-item.tsx | 2 +- packages/editor-skeleton/package.json | 11 +- .../src/components/field/index.less | 10 +- .../src/components/settings/index.ts | 8 +- .../src/components/settings/package.json | 49 --- ...ary-view.tsx => settings-primary-pane.tsx} | 2 +- .../settings/transducers/register.ts | 9 - packages/editor-skeleton/src/dock.ts | 87 ---- packages/editor-skeleton/src/index.ts | 6 + packages/editor-skeleton/src/panel.ts | 166 -------- .../register.ts => register-defaults.ts} | 15 +- .../transducers/addon-combine.ts | 0 .../settings => }/transducers/parse-props.ts | 0 packages/editor-skeleton/src/widget/utils.ts | 2 +- .../src/widget/widget-container.ts | 3 +- packages/editor/src/editor.ts | 30 ++ packages/plugin-components-pane/package.json | 1 + packages/plugin-components-pane/src/index.tsx | 35 +- .../plugin-components-pane/src/module.d.ts | 1 + .../plugin-event-bind-dialog/package.json | 3 +- .../plugin-event-bind-dialog/src/index.tsx | 56 +-- packages/plugin-outline-pane/package.json | 3 +- .../src/views/backup-pane.tsx | 30 ++ .../plugin-outline-pane/src/views/pane.tsx | 1 - packages/plugin-settings-pane/CHANGELOG.md | 87 ---- packages/plugin-settings-pane/README.md | 15 - packages/plugin-settings-pane/build.json | 9 - packages/plugin-settings-pane/package.json | 49 --- .../plugin-settings-pane/src/field/fields.tsx | 184 --------- .../plugin-settings-pane/src/field/index.less | 154 ------- .../plugin-settings-pane/src/field/index.ts | 28 -- .../src/icons/convert.tsx | 16 - packages/plugin-settings-pane/src/index.tsx | 9 - .../plugin-settings-pane/src/popup/index.tsx | 150 ------- .../plugin-settings-pane/src/popup/style.less | 22 - .../src/setters/array-setter/bugs.md | 5 - .../src/setters/array-setter/index.tsx | 279 ------------- .../src/setters/array-setter/sortable.less | 29 -- .../src/setters/array-setter/sortable.tsx | 220 ---------- .../src/setters/array-setter/style.less | 103 ----- .../src/setters/mixed-setter/index.tsx | 257 ------------ .../src/setters/mixed-setter/style.less | 30 -- .../src/setters/object-setter/index.tsx | 180 --------- .../src/setters/object-setter/style.less | 31 -- .../src/setters/register.ts | 29 -- .../src/settings/main-view.tsx | 148 ------- .../plugin-settings-pane/src/settings/main.ts | 89 ----- .../src/settings/settings-pane.tsx | 149 ------- packages/plugin-settings-pane/src/style.less | 124 ------ .../src/transducers/addon-combine.ts | 256 ------------ .../src/transducers/parse-props.ts | 232 ----------- .../src/transducers/register.ts | 9 - packages/plugin-settings-pane/src/utils.js | 41 -- .../plugin-settings-pane/src/variables.less | 170 -------- packages/plugin-source-editor/src/index.tsx | 34 +- packages/plugin-source-editor/src/module.d.ts | 1 + packages/plugin-undo-redo/package.json | 2 + packages/plugin-undo-redo/src/index.tsx | 24 +- packages/plugin-zh-en/package.json | 3 +- packages/plugin-zh-en/src/icons/en.tsx | 2 +- packages/plugin-zh-en/src/icons/zh.tsx | 2 +- packages/plugin-zh-en/src/locale/index.ts | 2 +- .../react-simulator-renderer/package.json | 3 +- packages/setters/src/index.tsx | 2 +- packages/types/package.json | 11 +- packages/types/src/setter-config.ts | 11 +- packages/utils/README.md | 1 + packages/utils/build.json | 5 + packages/utils/package.json | 40 ++ .../tsconfig.json | 0 .../vision-polyfill/src/bundle/prototype.ts | 12 +- packages/vision-polyfill/src/bundle/trunk.ts | 2 +- .../src/bundle/upgrade-metadata.ts | 108 ++--- packages/vision-polyfill/src/demo/index.ts | 2 +- packages/vision-polyfill/src/drag-engine.ts | 2 +- packages/vision-polyfill/src/editor.ts | 10 +- packages/vision-polyfill/src/module.d.ts | 3 + packages/vision-polyfill/src/pages.ts | 2 +- packages/vision-polyfill/src/panes.ts | 2 +- packages/vision-polyfill/src/prop.ts | 18 +- packages/vision-polyfill/src/skeleton/area.ts | 59 --- .../skeleton/components/array-setter/bugs.md | 5 - .../components/array-setter/index.tsx | 279 ------------- .../components/array-setter/sortable.less | 29 -- .../components/array-setter/sortable.tsx | 220 ---------- .../components/array-setter/style.less | 103 ----- .../src/skeleton/components/field/fields.tsx | 184 --------- .../src/skeleton/components/field/index.less | 154 ------- .../src/skeleton/components/field/index.ts | 28 -- .../components/mixed-setter/index.tsx | 257 ------------ .../components/mixed-setter/style.less | 30 -- .../components/object-setter/index.tsx | 180 --------- .../components/object-setter/style.less | 31 -- .../src/skeleton/components/popup/index.tsx | 150 ------- .../src/skeleton/components/popup/style.less | 22 - .../src/skeleton/components/register.ts | 29 -- .../src/skeleton/components/settings/index.ts | 9 - .../src/skeleton/components/settings/main.ts | 89 ----- .../skeleton/components/settings/package.json | 49 --- .../components/settings/settings-pane.tsx | 149 ------- .../settings/settings-primary-view.tsx | 121 ------ .../skeleton/components/settings/style.less | 124 ------ .../src/skeleton/components/settings/utils.js | 41 -- .../src/skeleton/components/widget-views.tsx | 236 ----------- packages/vision-polyfill/src/skeleton/dock.ts | 86 ---- .../src/skeleton/icons/convert.tsx | 16 - .../vision-polyfill/src/skeleton/index.ts | 0 .../src/skeleton/layouts/bottom-area.tsx | 37 -- .../src/skeleton/layouts/left-area.tsx | 41 -- .../src/skeleton/layouts/left-fixed-pane.tsx | 50 --- .../src/skeleton/layouts/left-float-pane.tsx | 73 ---- .../src/skeleton/layouts/main-area.tsx | 21 - .../src/skeleton/layouts/right-area.tsx | 35 -- .../src/skeleton/layouts/theme.less | 60 --- .../src/skeleton/layouts/toolbar.tsx | 49 --- .../src/skeleton/layouts/top-area.tsx | 44 -- .../src/skeleton/layouts/workbench.less | 375 ------------------ .../src/skeleton/layouts/workbench.tsx | 40 -- .../vision-polyfill/src/skeleton/panel.ts | 164 -------- .../vision-polyfill/src/skeleton/skeleton.ts | 318 --------------- .../src/skeleton/transducers/addon-combine.ts | 255 ------------ .../src/skeleton/transducers/parse-props.ts | 232 ----------- .../src/skeleton/transducers/register.ts | 9 - .../vision-polyfill/src/skeleton/types.ts | 114 ------ .../src/skeleton/widget/dialog-dock.ts | 0 .../src/skeleton/widget/dock.ts | 86 ---- .../src/skeleton/widget/panel-dock.ts | 117 ------ .../src/skeleton/widget/panel.ts | 164 -------- .../src/skeleton/widget/stage.ts | 51 --- .../src/skeleton/widget/utils.ts | 28 -- .../src/skeleton/widget/widget-container.ts | 134 ------- .../src/skeleton/widget/widget.ts | 100 ----- packages/vision-polyfill/src/symbols.ts | 17 - packages/vision-polyfill/src/vision.ts | 14 +- 141 files changed, 380 insertions(+), 8959 deletions(-) delete mode 100644 packages/editor-skeleton/src/components/settings/package.json rename packages/editor-skeleton/src/components/settings/{settings-primary-view.tsx => settings-primary-pane.tsx} (97%) delete mode 100644 packages/editor-skeleton/src/components/settings/transducers/register.ts delete mode 100644 packages/editor-skeleton/src/dock.ts delete mode 100644 packages/editor-skeleton/src/panel.ts rename packages/editor-skeleton/src/{components/settings/register.ts => register-defaults.ts} (58%) rename packages/editor-skeleton/src/{components/settings => }/transducers/addon-combine.ts (100%) rename packages/editor-skeleton/src/{components/settings => }/transducers/parse-props.ts (100%) create mode 100644 packages/editor/src/editor.ts create mode 100644 packages/plugin-components-pane/src/module.d.ts create mode 100644 packages/plugin-outline-pane/src/views/backup-pane.tsx delete mode 100644 packages/plugin-settings-pane/CHANGELOG.md delete mode 100644 packages/plugin-settings-pane/README.md delete mode 100644 packages/plugin-settings-pane/build.json delete mode 100644 packages/plugin-settings-pane/package.json delete mode 100644 packages/plugin-settings-pane/src/field/fields.tsx delete mode 100644 packages/plugin-settings-pane/src/field/index.less delete mode 100644 packages/plugin-settings-pane/src/field/index.ts delete mode 100644 packages/plugin-settings-pane/src/icons/convert.tsx delete mode 100644 packages/plugin-settings-pane/src/index.tsx delete mode 100644 packages/plugin-settings-pane/src/popup/index.tsx delete mode 100644 packages/plugin-settings-pane/src/popup/style.less delete mode 100644 packages/plugin-settings-pane/src/setters/array-setter/bugs.md delete mode 100644 packages/plugin-settings-pane/src/setters/array-setter/index.tsx delete mode 100644 packages/plugin-settings-pane/src/setters/array-setter/sortable.less delete mode 100644 packages/plugin-settings-pane/src/setters/array-setter/sortable.tsx delete mode 100644 packages/plugin-settings-pane/src/setters/array-setter/style.less delete mode 100644 packages/plugin-settings-pane/src/setters/mixed-setter/index.tsx delete mode 100644 packages/plugin-settings-pane/src/setters/mixed-setter/style.less delete mode 100644 packages/plugin-settings-pane/src/setters/object-setter/index.tsx delete mode 100644 packages/plugin-settings-pane/src/setters/object-setter/style.less delete mode 100644 packages/plugin-settings-pane/src/setters/register.ts delete mode 100644 packages/plugin-settings-pane/src/settings/main-view.tsx delete mode 100644 packages/plugin-settings-pane/src/settings/main.ts delete mode 100644 packages/plugin-settings-pane/src/settings/settings-pane.tsx delete mode 100644 packages/plugin-settings-pane/src/style.less delete mode 100644 packages/plugin-settings-pane/src/transducers/addon-combine.ts delete mode 100644 packages/plugin-settings-pane/src/transducers/parse-props.ts delete mode 100644 packages/plugin-settings-pane/src/transducers/register.ts delete mode 100644 packages/plugin-settings-pane/src/utils.js delete mode 100644 packages/plugin-settings-pane/src/variables.less create mode 100644 packages/plugin-source-editor/src/module.d.ts create mode 100644 packages/utils/README.md create mode 100644 packages/utils/build.json rename packages/{plugin-settings-pane => utils}/tsconfig.json (100%) create mode 100644 packages/vision-polyfill/src/module.d.ts delete mode 100644 packages/vision-polyfill/src/skeleton/area.ts delete mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md delete mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/array-setter/style.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/field/fields.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/field/index.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/field/index.ts delete mode 100644 packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/object-setter/style.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/popup/index.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/popup/style.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/register.ts delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/index.ts delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/main.ts delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/package.json delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/style.less delete mode 100644 packages/vision-polyfill/src/skeleton/components/settings/utils.js delete mode 100644 packages/vision-polyfill/src/skeleton/components/widget-views.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/dock.ts delete mode 100644 packages/vision-polyfill/src/skeleton/icons/convert.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/index.ts delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/left-area.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/main-area.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/right-area.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/theme.less delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/top-area.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/workbench.less delete mode 100644 packages/vision-polyfill/src/skeleton/layouts/workbench.tsx delete mode 100644 packages/vision-polyfill/src/skeleton/panel.ts delete mode 100644 packages/vision-polyfill/src/skeleton/skeleton.ts delete mode 100644 packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts delete mode 100644 packages/vision-polyfill/src/skeleton/transducers/parse-props.ts delete mode 100644 packages/vision-polyfill/src/skeleton/transducers/register.ts delete mode 100644 packages/vision-polyfill/src/skeleton/types.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/dock.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/panel-dock.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/panel.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/stage.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/utils.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/widget-container.ts delete mode 100644 packages/vision-polyfill/src/skeleton/widget/widget.ts delete mode 100644 packages/vision-polyfill/src/symbols.ts diff --git a/packages/designer/package.json b/packages/designer/package.json index 1b1f34703..e271381bf 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -15,7 +15,9 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-globals": "^0.9.3", + "@ali/lowcode-editor-core": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", + "@ali/lowcode-types": "^0.8.0", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 5509d13a5..1954f6091 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -11,7 +11,7 @@ import { import { computed } from '@ali/lowcode-editor-core'; import { Node, ParentalNode } from './document'; import { Designer } from './designer'; -import { intl } from './locale'; +import { intlNode } from './locale'; import { IconContainer } from './icons/container'; import { IconPage } from './icons/page'; import { IconComponent } from './icons/component'; @@ -235,6 +235,38 @@ function preprocessMetadata(metadata: ComponentMetadata): TransformedComponentMe }; } + +export interface MetadataTransducer { + (prev: TransformedComponentMetadata): TransformedComponentMetadata; + /** + * 0 - 9 system + * 10 - 99 builtin-plugin + * 100 - app & plugin + */ + level?: number; + /** + * use to replace TODO + */ + id?: string; +} +const metadataTransducers: MetadataTransducer[] = []; + +export function registerMetadataTransducer(transducer: MetadataTransducer, level: number = 100, id?: string) { + transducer.level = level; + transducer.id = id; + const i = metadataTransducers.findIndex((item) => item.level != null && item.level > level); + if (i < 0) { + metadataTransducers.push(transducer); + } else { + metadataTransducers.splice(i, 0, transducer); + } +} + +export function getRegisteredMetadataTransducers(): MetadataTransducer[] { + return metadataTransducers; +} + + registerMetadataTransducer((metadata) => { const { configure, componentName } = metadata; const { component = {} } = configure; @@ -280,7 +312,7 @@ const builtinComponentActions: ComponentAction[] = [ name: 'remove', content: { icon: IconRemove, - title: intl('remove'), + title: intlNode('remove'), action(node: Node) { node.remove(); }, @@ -291,7 +323,7 @@ const builtinComponentActions: ComponentAction[] = [ name: 'copy', content: { icon: IconClone, - title: intl('copy'), + title: intlNode('copy'), action(node: Node) { // node.remove(); }, @@ -309,33 +341,3 @@ export function removeBuiltinComponentAction(name: string) { export function addBuiltinComponentAction(action: ComponentAction) { builtinComponentActions.push(action); } - -export interface MetadataTransducer { - (prev: TransformedComponentMetadata): TransformedComponentMetadata; - /** - * 0 - 9 system - * 10 - 99 builtin-plugin - * 100 - app & plugin - */ - level?: number; - /** - * use to replace TODO - */ - id?: string; -} -const metadataTransducers: MetadataTransducer[] = []; - -export function registerMetadataTransducer(transducer: MetadataTransducer, level: number = 100, id?: string) { - transducer.level = level; - transducer.id = id; - const i = metadataTransducers.findIndex((item) => item.level != null && item.level > level); - if (i < 0) { - metadataTransducers.push(transducer); - } else { - metadataTransducers.splice(i, 0, transducer); - } -} - -export function getRegisteredMetadataTransducers(): MetadataTransducer[] { - return metadataTransducers; -} diff --git a/packages/designer/src/locale/index.ts b/packages/designer/src/locale/index.ts index dfd17521f..26507f0ef 100644 --- a/packages/designer/src/locale/index.ts +++ b/packages/designer/src/locale/index.ts @@ -2,9 +2,9 @@ import { createIntl } from '@ali/lowcode-editor-core'; import en_US from './en-US.json'; import zh_CN from './zh-CN.json'; -const { intl, getLocale, setLocale } = createIntl({ +const { intl, intlNode, getLocale, setLocale } = createIntl({ 'en-US': en_US, 'zh-CN': zh_CN, }); -export { intl, getLocale, setLocale }; +export { intl, intlNode, getLocale, setLocale }; diff --git a/packages/editor-core/cloud-build.json b/packages/editor-core/cloud-build.json index 2cfca99dd..15de75b91 100644 --- a/packages/editor-core/cloud-build.json +++ b/packages/editor-core/cloud-build.json @@ -3,8 +3,8 @@ [ "build-plugin-component", { - "filename": "globals", - "library": "LCEGlobals", + "filename": "core", + "library": "LCECore", "libraryTarget": "umd" } ], diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index c8fcce18c..0e9ac0349 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-globals", - "version": "0.9.3", + "version": "0.8.6", "description": "Globals api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -27,13 +27,14 @@ }, "dependencies": { "@alifd/next": "^1.19.16", + "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", "classnames": "^2.2.6", "power-di": "^2.2.4", "debug": "^4.1.1", "intl-messageformat": "^8.3.1", - "lodash": "^4.17.15", "store": "^2.0.12", "react": "^16", "react-dom": "^16.7.0" @@ -44,8 +45,6 @@ "@types/node": "^13.7.1", "@types/react": "^16", "@types/react-dom": "^16", - - "@types/lodash": "^4.14.149", "@types/store": "^2.0.2", "build-plugin-component": "^0.2.11", "build-plugin-fusion": "^0.1.0", diff --git a/packages/editor-core/src/di/index.ts b/packages/editor-core/src/di/index.ts index d60f74e53..75a4e84f1 100644 --- a/packages/editor-core/src/di/index.ts +++ b/packages/editor-core/src/di/index.ts @@ -1,3 +1,3 @@ export * from './setter'; export * from './ioc-context'; -export * from './tip'; +export * from '../widgets/tip/tip'; diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index aa7fe1083..8fd69d46c 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -20,6 +20,8 @@ export type GetReturnType<T, ClsType> = T extends undefined const NOT_FOUND = Symbol.for('not_found'); +import * as utils from './utils'; + export class Editor extends EventEmitter implements IEditor { /** * Ioc Container @@ -32,6 +34,8 @@ export class Editor extends EventEmitter implements IEditor { return globalLocale.getLocale(); } + readonly utils = utils; + constructor(readonly config: EditorConfig = {}, readonly components: PluginClassSet = {}) { super(); } diff --git a/packages/editor-core/src/widgets/tip/tip-item.tsx b/packages/editor-core/src/widgets/tip/tip-item.tsx index 558d13768..20ec87bea 100644 --- a/packages/editor-core/src/widgets/tip/tip-item.tsx +++ b/packages/editor-core/src/widgets/tip/tip-item.tsx @@ -1,7 +1,7 @@ import { Component } from 'react'; import classNames from 'classnames'; -import { intl } from '@ali/lowcode-editor-core'; import { TipConfig } from '@ali/lowcode-types'; +import { intl } from '../../intl'; import { resolvePosition } from './utils'; import { tipHandler } from './tip-handler'; diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 3b66a00b7..7bc4a6f41 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -20,13 +20,14 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", "@alifd/next": "^1.x", - "prop-types": "^15.5.8", + "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-designer": "^0.9.2", + "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", + "classnames": "^2.2.6", "react": "^16.8.1", - "react-dom": "^16.8.1", - "react-router-dom": "^5.1.2", - "store": "^2.0.12" + "react-dom": "^16.8.1" }, "devDependencies": { "@alib/build-scripts": "^0.1.3", diff --git a/packages/editor-skeleton/src/components/field/index.less b/packages/editor-skeleton/src/components/field/index.less index 5fecb74d9..2a47edf15 100644 --- a/packages/editor-skeleton/src/components/field/index.less +++ b/packages/editor-skeleton/src/components/field/index.less @@ -1,5 +1,3 @@ -@import '../variables.less'; - @x-gap: 10px; @y-gap: 8px; @@ -57,7 +55,7 @@ &.lc-block-field, &.lc-accordion-field { display: block; &:not(:first-child) { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + border-top: 1px solid var(--color-line-normal); } > .lc-field-head { padding-left: @x-gap; @@ -66,8 +64,8 @@ align-items: center; font-weight: 500; background: var(--color-block-background-shallow, rgba(31,56,88,.06)); - border-bottom: 1px solid var(--color-line-normal, @dark-alpha-2); - color: var(--color-title, @white-alpha-2); + border-bottom: 1px solid var(--color-line-normal); + color: var(--color-title); user-select: none; } @@ -76,7 +74,7 @@ } + .lc-inline-field { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); + border-top: 1px solid var(--color-line-normal); } } diff --git a/packages/editor-skeleton/src/components/settings/index.ts b/packages/editor-skeleton/src/components/settings/index.ts index be0ed6e8d..4738b3e54 100644 --- a/packages/editor-skeleton/src/components/settings/index.ts +++ b/packages/editor-skeleton/src/components/settings/index.ts @@ -1,7 +1,3 @@ -export * from './settings-pane'; -import './transducers/register'; -import './register'; import './style.less'; -import SettingsMainView from './settings-primary-view'; - -export default SettingsMainView; +export * from './settings-primary-pane'; +export * from './settings-pane'; diff --git a/packages/editor-skeleton/src/components/settings/package.json b/packages/editor-skeleton/src/components/settings/package.json deleted file mode 100644 index 2a0fab24e..000000000 --- a/packages/editor-skeleton/src/components/settings/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@ali/lowcode-plugin-settings-pane", - "version": "0.8.10", - "description": "Settings pane for Ali lowCode engine", - "files": [ - "es", - "lib" - ], - "main": "lib/index.js", - "module": "es/index.js", - "scripts": { - "build": "build-scripts build --skip-demo", - "test": "ava", - "test:snapshot": "ava --update-snapshots" - }, - "dependencies": { - "@ali/lowcode-designer": "^0.9.2", - "@ali/lowcode-editor-core": "^0.8.5", - "@ali/lowcode-globals": "^0.9.2", - "@ali/lowcode-plugin-outline-pane": "^0.8.8", - "@ali/ve-stage-box": "^4.0.0", - "@alifd/next": "^1.19.16", - "classnames": "^2.2.6", - "react": "^16" - }, - "devDependencies": { - "@alib/build-scripts": "^0.1.18", - "@types/classnames": "^2.2.7", - "@types/node": "^13.7.1", - "@types/react": "^16", - "build-plugin-component": "^0.2.10", - "build-plugin-fusion": "^0.1.1", - "build-plugin-moment-locales": "^0.1.0" - }, - "ava": { - "compileEnhancements": false, - "snapshotDir": "test/fixtures/__snapshots__", - "extensions": [ - "ts" - ], - "require": [ - "ts-node/register" - ] - }, - "license": "MIT", - "publishConfig": { - "registry": "https://registry.npm.alibaba-inc.com" - } -} diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-view.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx similarity index 97% rename from packages/editor-skeleton/src/components/settings/settings-primary-view.tsx rename to packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 7a4c49815..77c9eda0f 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-view.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -7,7 +7,7 @@ import { SettingsPane } from './settings-pane'; import { createIcon } from '@ali/lowcode-utils'; @observer -export default class SettingsMainView extends Component<{ editor: Editor }> { +export class SettingsPrimaryPane extends Component<{ editor: Editor }> { private main = new SettingsMain(this.props.editor); shouldComponentUpdate() { diff --git a/packages/editor-skeleton/src/components/settings/transducers/register.ts b/packages/editor-skeleton/src/components/settings/transducers/register.ts deleted file mode 100644 index 0ac451c52..000000000 --- a/packages/editor-skeleton/src/components/settings/transducers/register.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { registerMetadataTransducer } from '@ali/lowcode-designer'; -import parseProps from './parse-props'; -import addonCombine from './addon-combine'; - -// parseProps -registerMetadataTransducer(parseProps, 10, 'parse-props'); - -// addon/platform custom -registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/editor-skeleton/src/dock.ts b/packages/editor-skeleton/src/dock.ts deleted file mode 100644 index affa84d98..000000000 --- a/packages/editor-skeleton/src/dock.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { obx } from '@ali/lowcode-editor-core'; -import { uniqueId, createContent } from '@ali/lowcode-utils'; -import { DockConfig } from "./types"; -import { Skeleton } from './skeleton'; -import { DockView, WidgetView } from './components/widget-views'; -import { IWidget } from './widget/widget'; - -/** - * 带图标(主要)/标题(次要)的扩展 - */ -export default class Dock implements IWidget { - readonly isWidget = true; - readonly id = uniqueId('dock'); - readonly name: string; - readonly align?: string; - - @obx.ref private _visible: boolean = true; - get visible(): boolean { - return this._visible; - } - - get content(): ReactNode { - return createElement(WidgetView, { - widget: this, - key: this.id, - }); - } - - private inited: boolean = false; - private _body: ReactNode; - get body() { - if (this.inited) { - return this._body; - } - - const { props, content, contentProps } = this.config; - - if (content) { - this._body = createContent(content, { - ...contentProps, - config: this.config, - editor: this.skeleton.editor, - }); - } else { - this._body = createElement(DockView, props); - } - return this._body; - } - - constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { - const { props = {}, name } = config; - this.name = name; - this.align = props.align; - } - - setVisible(flag: boolean) { - if (flag === this._visible) { - return; - } - if (flag) { - this._visible = true; - } else if (this.inited) { - this._visible = false; - } - } - - getContent() { - return this.content; - } - - getName() { - return this.name; - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } - - toggle() { - this.setVisible(!this._visible); - } -} diff --git a/packages/editor-skeleton/src/index.ts b/packages/editor-skeleton/src/index.ts index 923bd59cb..2a8dcdbf8 100644 --- a/packages/editor-skeleton/src/index.ts +++ b/packages/editor-skeleton/src/index.ts @@ -1 +1,7 @@ export { Workbench } from './layouts/workbench'; +export * from './skeleton'; +export * from './types'; +export * from './components/settings'; +export * from './components/field'; + +import './register-defaults'; diff --git a/packages/editor-skeleton/src/panel.ts b/packages/editor-skeleton/src/panel.ts deleted file mode 100644 index fd8a5de46..000000000 --- a/packages/editor-skeleton/src/panel.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { createElement, ReactNode } from 'react'; -import { TitleContent } from '@ali/lowcode-types'; -import { uniqueId, createContent } from '@ali/lowcode-utils'; -import { obx } from '@ali/lowcode-editor-core'; -import WidgetContainer from './widget/widget-container'; -import { PanelConfig, HelpTipConfig } from './types'; -import { TitledPanelView, TabsPanelView, PanelView } from './components/widget-views'; -import { Skeleton } from './skeleton'; -import { composeTitle } from './widget/utils'; -import { IWidget } from './widget/widget'; - -export default class Panel implements IWidget { - readonly isWidget = true; - readonly name: string; - readonly id: string; - @obx.ref inited: boolean = false; - @obx.ref private _actived: boolean = false; - get actived(): boolean { - return this._actived; - } - - get visible(): boolean { - if (this.parent?.visible) { - return this._actived; - } - return false; - } - - readonly isPanel = true; - - private _body?: ReactNode; - get body() { - this.initBody(); - return this._body; - } - - get content(): ReactNode { - if (this.plain) { - return createElement(PanelView, { - panel: this, - key: this.id, - }); - } - return createElement(TitledPanelView, { panel: this, key: this.id }); - } - - readonly title: TitleContent; - readonly help?: HelpTipConfig; - private plain: boolean = false; - - private container?: WidgetContainer<Panel, PanelConfig>; - private parent?: WidgetContainer; - - constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { - const { name, content, props = {} } = config; - const { hideTitleBar, title, icon, description, help, shortcut } = props; - this.name = name; - this.id = uniqueId(`pane:${name}$`); - this.title = composeTitle(title || name, icon, description); - this.plain = hideTitleBar || !title; - this.help = help; - if (Array.isArray(content)) { - this.container = this.skeleton.createContainer( - name, - (item) => { - if (isPanel(item)) { - return item; - } - return this.skeleton.createPanel(item); - }, - true, - () => this.visible, - true, - ); - content.forEach((item) => this.add(item)); - } - // todo: process shortcut - } - - private initBody() { - if (this.inited) { - return; - } - this.inited = true; - if (this.container) { - this._body = createElement(TabsPanelView, { - container: this.container, - }); - } else { - const { content, contentProps } = this.config; - this._body = createContent(content, { - ...contentProps, - editor: this.skeleton.editor, - config: this.config, - panel: this, - }); - } - } - - setParent(parent: WidgetContainer) { - if (parent === this.parent) { - return; - } - if (this.parent) { - this.parent.remove(this); - } - this.parent = parent; - } - - add(item: Panel | PanelConfig) { - return this.container?.add(item); - } - - getPane(name: string): Panel | null { - return this.container?.get(name) || null; - } - - remove(item: Panel | string) { - return this.container?.remove(item); - } - - active(item?: Panel | string | null) { - this.container?.active(item); - } - - getName() { - return this.name; - } - - getContent() { - return this.content; - } - - setActive(flag: boolean) { - if (flag === this._actived) { - // TODO: 如果移动到另外一个 container,会有问题 - return; - } - if (flag) { - if (!this.inited) { - this.initBody(); - } - this._actived = true; - this.parent?.active(this); - } else if (this.inited) { - this._actived = false; - this.parent?.unactive(this); - } - } - - toggle() { - this.setActive(!this._actived); - } - - hide() { - this.setActive(false); - } - - show() { - this.setActive(true); - } -} - -export function isPanel(obj: any): obj is Panel { - return obj && obj.isPanel; -} diff --git a/packages/editor-skeleton/src/components/settings/register.ts b/packages/editor-skeleton/src/register-defaults.ts similarity index 58% rename from packages/editor-skeleton/src/components/settings/register.ts rename to packages/editor-skeleton/src/register-defaults.ts index 1ff61b101..63bf0dd90 100644 --- a/packages/editor-skeleton/src/components/settings/register.ts +++ b/packages/editor-skeleton/src/register-defaults.ts @@ -1,8 +1,11 @@ import { registerSetter } from '@ali/lowcode-editor-core'; -import ArraySetter from '../array-setter'; -import ObjectSetter from '../object-setter'; -import MixedSetter from '../mixed-setter'; +import { registerMetadataTransducer } from '@ali/lowcode-designer'; +import ArraySetter from './components/array-setter'; +import ObjectSetter from './components/object-setter'; +import MixedSetter from './components/mixed-setter'; import { isPlainObject } from '@ali/lowcode-utils'; +import parseProps from './transducers/parse-props'; +import addonCombine from './transducers/addon-combine'; registerSetter('ArraySetter', { component: ArraySetter, @@ -28,3 +31,9 @@ registerSetter('ObjectSetter', { recommend: true, }); registerSetter('MixedSetter', MixedSetter); + +// parseProps +registerMetadataTransducer(parseProps, 10, 'parse-props'); + +// addon/platform custom +registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts similarity index 100% rename from packages/editor-skeleton/src/components/settings/transducers/addon-combine.ts rename to packages/editor-skeleton/src/transducers/addon-combine.ts diff --git a/packages/editor-skeleton/src/components/settings/transducers/parse-props.ts b/packages/editor-skeleton/src/transducers/parse-props.ts similarity index 100% rename from packages/editor-skeleton/src/components/settings/transducers/parse-props.ts rename to packages/editor-skeleton/src/transducers/parse-props.ts diff --git a/packages/editor-skeleton/src/widget/utils.ts b/packages/editor-skeleton/src/widget/utils.ts index 301426a87..b635fbbe0 100644 --- a/packages/editor-skeleton/src/widget/utils.ts +++ b/packages/editor-skeleton/src/widget/utils.ts @@ -1,4 +1,4 @@ -import { IconType, TitleContent, isI18nData, TipContent } from '@ali/lowcode-globals'; +import { IconType, TitleContent, isI18nData, TipContent } from '@ali/lowcode-types'; import { isValidElement } from 'react'; export function composeTitle(title?: TitleContent, icon?: IconType, tip?: TipContent, tipAsTitle?: boolean) { diff --git a/packages/editor-skeleton/src/widget/widget-container.ts b/packages/editor-skeleton/src/widget/widget-container.ts index b34827ae7..268f5fcfb 100644 --- a/packages/editor-skeleton/src/widget/widget-container.ts +++ b/packages/editor-skeleton/src/widget/widget-container.ts @@ -1,5 +1,6 @@ -import { obx, hasOwnProperty, computed } from '@ali/lowcode-globals'; +import { obx, computed } from '@ali/lowcode-editor-core'; import { isPanel } from './panel'; +import { hasOwnProperty } from '@ali/lowcode-utils'; export interface WidgetItem { name: string; } diff --git a/packages/editor/src/editor.ts b/packages/editor/src/editor.ts new file mode 100644 index 000000000..1cc9a8040 --- /dev/null +++ b/packages/editor/src/editor.ts @@ -0,0 +1,30 @@ +import { globalContext, Editor } from '@ali/lowcode-editor-core'; +import { Designer } from '@ali/lowcode-designer'; +import DesignerPlugin from '@ali/lowcode-plugin-designer'; +import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton'; + +export const editor = new Editor(); +globalContext.register(editor, Editor); + +export const skeleton = new Skeleton(editor); +editor.set(Skeleton, skeleton); + +export const designer = new Designer({ editor: editor }); +editor.set(Designer, designer); + +skeleton.add({ + area: 'mainArea', + name: 'designer', + type: 'Widget', + content: DesignerPlugin, +}); +skeleton.add({ + area: 'rightArea', + name: 'settingsPane', + type: 'Panel', + content: SettingsPrimaryPane, +}); + +export * from '@ali/lowcode-types'; +export * from '@ali/lowcode-designer'; +export * from '@ali/lowcode-editor-skeleton' diff --git a/packages/plugin-components-pane/package.json b/packages/plugin-components-pane/package.json index b51bed16c..a00043109 100644 --- a/packages/plugin-components-pane/package.json +++ b/packages/plugin-components-pane/package.json @@ -25,6 +25,7 @@ "@ali/iceluna-sdk": "^1.0.6-beta.6", "@ali/lowcode-designer": "^0.9.3", "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-types": "^0.8.0", "@alifd/next": "^1.19.19", "react": "^16.8.1" }, diff --git a/packages/plugin-components-pane/src/index.tsx b/packages/plugin-components-pane/src/index.tsx index 3dc8ccd5a..7c5540f79 100644 --- a/packages/plugin-components-pane/src/index.tsx +++ b/packages/plugin-components-pane/src/index.tsx @@ -19,13 +19,10 @@ export interface IState { componentList: object[]; } -export default class ComponentListPlugin extends PureComponent< - PluginProps, - IState -> { +export default class ComponentListPlugin extends PureComponent<PluginProps, IState> { static displayName = 'LowcodeComponentListPlugin'; - constructor(props) { + constructor(props: any) { super(props); this.state = { loading: false, @@ -50,15 +47,15 @@ export default class ComponentListPlugin extends PureComponent< } } - transformMaterial = (componentList): any => { - return componentList.map(category => { + transformMaterial = (componentList: any): any => { + return componentList.map((category: any) => { return { name: category.title, - items: category.children.map(comp => { + items: category.children.map((comp: any) => { return { ...comp, name: comp.componentName, - snippets: comp.snippets.map(snippet => { + snippets: comp.snippets.map((snippet: any) => { return { name: snippet.title, screenshot: snippet.screenshot, @@ -76,7 +73,7 @@ export default class ComponentListPlugin extends PureComponent< const assets = editor.get('assets') || {}; const list: string[] = []; const libs: LibrayInfo[] = []; - Object.values(assets.packages).forEach((item): void => { + Object.values(assets.packages).forEach((item: any): void => { list.push(item.library); libs.push({ label: item.title, @@ -100,7 +97,7 @@ export default class ComponentListPlugin extends PureComponent< }); editor.set('dndHelper', { - handleResourceDragStart: function(ev, tagName, schema) { + handleResourceDragStart: function(ev: any, tagName: any, schema: any) { const designer = editor.get(Designer); if (designer) { designer.dragon.boost( @@ -125,18 +122,16 @@ export default class ComponentListPlugin extends PureComponent< const { searchKey, currentLib, componentList } = this.state; const libs = currentLib.split(','); return (componentList || []) - .map(cate => { + .map((cate: any) => { return { ...cate, - items: (cate.items || []).filter(item => { - let libFlag = libs.some(lib => lib == item.library); + items: (cate.items || []).filter((item: any) => { + let libFlag = libs.some((lib) => lib == item.library); let keyFlag = true; if (searchKey) { keyFlag = - `${item.name || ''} ${item.title || ''}` - .toLowerCase() - .indexOf(searchKey.trim().toLowerCase()) >= 0; + `${item.name || ''} ${item.title || ''}`.toLowerCase().indexOf(searchKey.trim().toLowerCase()) >= 0; } else { keyFlag = item.is_show === undefined || !!(item.is_show == 1); } @@ -144,7 +139,7 @@ export default class ComponentListPlugin extends PureComponent< }), }; }) - .filter(cate => { + .filter((cate) => { return cate.items && cate.items.length > 0; }); }; @@ -159,10 +154,10 @@ export default class ComponentListPlugin extends PureComponent< </div> <Search shape="simple" - size="small" + size="medium" className="search" placeholder="请输入关键词" - onChange={this.searchAction} + onChange={this.searchAction as any} onSearch={this.searchAction} hasClear /> diff --git a/packages/plugin-components-pane/src/module.d.ts b/packages/plugin-components-pane/src/module.d.ts new file mode 100644 index 000000000..df9f49df3 --- /dev/null +++ b/packages/plugin-components-pane/src/module.d.ts @@ -0,0 +1 @@ +declare module "@ali/iceluna-comp-material-show"; diff --git a/packages/plugin-event-bind-dialog/package.json b/packages/plugin-event-bind-dialog/package.json index cc9d51e9b..9a37ec2f7 100644 --- a/packages/plugin-event-bind-dialog/package.json +++ b/packages/plugin-event-bind-dialog/package.json @@ -19,7 +19,8 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.0", "@alifd/next": "^1.19.16", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-event-bind-dialog/src/index.tsx b/packages/plugin-event-bind-dialog/src/index.tsx index 4aedba085..819f2dd4b 100644 --- a/packages/plugin-event-bind-dialog/src/index.tsx +++ b/packages/plugin-event-bind-dialog/src/index.tsx @@ -1,11 +1,9 @@ import { Component, isValidElement, ReactElement, ReactNode } from 'react'; import { Dialog, Search, Input } from '@alifd/next'; -import { Editor } from '@ali/lowcode-editor-core'; +import { PluginProps } from '@ali/lowcode-types'; import './index.scss'; -export default class EventBindDialog extends Component<{ - editor:Editor, -}> { +export default class EventBindDialog extends Component<PluginProps> { private eventList: any[] = [ { name: 'getData', @@ -24,29 +22,29 @@ export default class EventBindDialog extends Component<{ }, ]; - state = { - visiable:false, + state: any = { + visiable: false, selectedEventName: '', eventName: '', }; - openDialog = (bindEventName:String) => { + openDialog = (bindEventName: String) => { this.setState({ - visiable:true, - eventName:bindEventName - }) - } + visiable: true, + eventName: bindEventName, + }); + }; closeDialog = () => { this.setState({ - visiable:false - }) - } + visiable: false, + }); + }; - componentDidMount (){ - const {editor,config} = this.props; - editor.on(`${config.pluginKey}.openDialog`,(bindEventName:String)=>{ - this.openDialog(bindEventName) + componentDidMount() { + const { editor, config } = this.props; + editor.on(`${config.pluginKey}.openDialog`, (bindEventName: String) => { + this.openDialog(bindEventName); }); } @@ -89,22 +87,28 @@ export default class EventBindDialog extends Component<{ onSearchEvent = (searchEventName: String) => {}; onOk = () => { - const {editor} = this.props; - editor.emit('event-setter.bindEvent',this.state.eventName); + const { editor } = this.props; + editor.emit('event-setter.bindEvent', this.state.eventName); // 选中的是新建事件 - if (this.state.selectedEventName == ''){ - editor.emit('sourceEditor.addFunction',{ - functionName:this.state.eventName - }) + if (this.state.selectedEventName == '') { + editor.emit('sourceEditor.addFunction', { + functionName: this.state.eventName, + }); } this.closeDialog(); }; render() { - const { selectedEventName, eventName,visiable} = this.state; + const { selectedEventName, eventName, visiable } = this.state; return ( - <Dialog visible={visiable} title="事件绑定" onClose={this.closeDialog} onCancel={this.closeDialog} onOk={this.onOk}> + <Dialog + visible={visiable} + title="事件绑定" + onClose={this.closeDialog} + onCancel={this.closeDialog} + onOk={this.onOk} + > <div className="event-dialog-body"> <div className="dialog-left-container"> <div className="dialog-small-title">事件选择</div> diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 5e3e4821b..315048104 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -16,7 +16,8 @@ "dependencies": { "@ali/lowcode-designer": "^0.9.3", "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-globals": "^0.9.3", + "@ali/lowcode-utils": "^0.8.0", + "@ali/lowcode-types": "^0.8.0", "@alifd/next": "^1.19.16", "classnames": "^2.2.6", "react": "^16", diff --git a/packages/plugin-outline-pane/src/views/backup-pane.tsx b/packages/plugin-outline-pane/src/views/backup-pane.tsx new file mode 100644 index 000000000..f74eceaff --- /dev/null +++ b/packages/plugin-outline-pane/src/views/backup-pane.tsx @@ -0,0 +1,30 @@ +import { PureComponent } from 'react'; +import { PluginProps } from '@ali/lowcode-types'; +import OutlinePane from './pane'; + +export class OutlineBackupPane extends PureComponent<PluginProps> { + state = { + outlineInited: false, + }; + private dispose = this.props.main.onceOutlineVisible(() => { + this.setState({ + outlineInited: true, + }); + }); + componentWillUnmount() { + this.dispose(); + } + render() { + if (!this.state.outlineInited) { + return null; + } + return ( + <OutlinePane + editor={this.props.main.editor} + config={{ + name: '__IN_SETTINGS__', + }} + /> + ); + } +} diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index f539b51be..b11c5e4c1 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -21,7 +21,6 @@ export default class OutlinePane extends Component<{ config: any; editor: any; i } render() { - console.info(this.props); const tree = this.main.currentTree; if (!tree) { diff --git a/packages/plugin-settings-pane/CHANGELOG.md b/packages/plugin-settings-pane/CHANGELOG.md deleted file mode 100644 index c2f41be85..000000000 --- a/packages/plugin-settings-pane/CHANGELOG.md +++ /dev/null @@ -1,87 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -<a name="0.8.10"></a> -## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.9...@ali/lowcode-plugin-settings-pane@0.8.10) (2020-04-16) - - - - -**Note:** Version bump only for package @ali/lowcode-plugin-settings-pane - -<a name="0.8.9"></a> -## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.8...@ali/lowcode-plugin-settings-pane@0.8.9) (2020-04-15) - - -### Bug Fixes - -* plugin-designer ([2dfbcd4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/2dfbcd4)) - - - - -<a name="0.8.8"></a> -## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.7...@ali/lowcode-plugin-settings-pane@0.8.8) (2020-03-31) - - - - -**Note:** Version bump only for package @ali/lowcode-plugin-settings-pane - -<a name="0.8.7"></a> -## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.6...@ali/lowcode-plugin-settings-pane@0.8.7) (2020-03-30) - - -### Bug Fixes - -* **settings-pane:** overflow problem ([d2d8556](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/d2d8556)) - - - - -<a name="0.8.6"></a> -## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.5...@ali/lowcode-plugin-settings-pane@0.8.6) (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-plugin-settings-pane - -<a name="0.8.5"></a> -## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-settings-pane@0.8.4...@ali/lowcode-plugin-settings-pane@0.8.5) (2020-03-30) - - - - -**Note:** Version bump only for package @ali/lowcode-plugin-settings-pane - -<a name="0.8.4"></a> -## 0.8.4 (2020-03-30) - - -### Features - -* add color-setter ([a149921](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a149921)) -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7)) -* 增加color-setter,json-setter ([93e76ce](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/93e76ce)) - - - - -<a name="0.8.3"></a> -## 0.8.3 (2020-03-30) - - -### Features - -<<<<<<< HEAD -* add color-setter ([a149921](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a149921)) -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7)) -* 增加color-setter,json-setter ([93e76ce](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/93e76ce)) -======= -* add color-setter ([a149921](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/a14992174b65b1241e7bb82561c7efdfd6589606)) -* double outline & ZH_EN support ([b379bd7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b379bd7c0c488ef24f825760750a13d3fa083c96)) -* 增加color-setter,json-setter ([93e76ce](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/93e76ce3606603ee926ad83b21b29ffe28dc0682)) ->>>>>>> df955e1db90ff104cd11160def80113cfd6faccc diff --git a/packages/plugin-settings-pane/README.md b/packages/plugin-settings-pane/README.md deleted file mode 100644 index 9b40bf02b..000000000 --- a/packages/plugin-settings-pane/README.md +++ /dev/null @@ -1,15 +0,0 @@ -属性面板 - -其中 field 可独立出去一个包 - -提供: - 1. 快捷设置面板服务 - 2. 对应节点的设置面板服务 - 3. 右侧设置面板 - 4. 提供 setters 服务,setters 注册、获取机制 - -依赖: - -tip 处理 -field -popup diff --git a/packages/plugin-settings-pane/build.json b/packages/plugin-settings-pane/build.json deleted file mode 100644 index e791d5b6b..000000000 --- a/packages/plugin-settings-pane/build.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "plugins": [ - "build-plugin-component", - "build-plugin-fusion", - ["build-plugin-moment-locales", { - "locales": ["zh-cn"] - }] - ] -} diff --git a/packages/plugin-settings-pane/package.json b/packages/plugin-settings-pane/package.json deleted file mode 100644 index 2a0fab24e..000000000 --- a/packages/plugin-settings-pane/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@ali/lowcode-plugin-settings-pane", - "version": "0.8.10", - "description": "Settings pane for Ali lowCode engine", - "files": [ - "es", - "lib" - ], - "main": "lib/index.js", - "module": "es/index.js", - "scripts": { - "build": "build-scripts build --skip-demo", - "test": "ava", - "test:snapshot": "ava --update-snapshots" - }, - "dependencies": { - "@ali/lowcode-designer": "^0.9.2", - "@ali/lowcode-editor-core": "^0.8.5", - "@ali/lowcode-globals": "^0.9.2", - "@ali/lowcode-plugin-outline-pane": "^0.8.8", - "@ali/ve-stage-box": "^4.0.0", - "@alifd/next": "^1.19.16", - "classnames": "^2.2.6", - "react": "^16" - }, - "devDependencies": { - "@alib/build-scripts": "^0.1.18", - "@types/classnames": "^2.2.7", - "@types/node": "^13.7.1", - "@types/react": "^16", - "build-plugin-component": "^0.2.10", - "build-plugin-fusion": "^0.1.1", - "build-plugin-moment-locales": "^0.1.0" - }, - "ava": { - "compileEnhancements": false, - "snapshotDir": "test/fixtures/__snapshots__", - "extensions": [ - "ts" - ], - "require": [ - "ts-node/register" - ] - }, - "license": "MIT", - "publishConfig": { - "registry": "https://registry.npm.alibaba-inc.com" - } -} diff --git a/packages/plugin-settings-pane/src/field/fields.tsx b/packages/plugin-settings-pane/src/field/fields.tsx deleted file mode 100644 index d36928604..000000000 --- a/packages/plugin-settings-pane/src/field/fields.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { Component } from 'react'; -import classNames from 'classnames'; -import { Icon } from '@alifd/next'; -import { Title, TitleContent } from '@ali/lowcode-globals'; -import { PopupPipe, PopupContext } from '../popup'; -import './index.less'; - -export interface FieldProps { - className?: string; - title?: TitleContent | null; - defaultDisplay?: 'accordion' | 'inline' | 'block'; - collapsed?: boolean; - onExpandChange?: (expandState: boolean) => void; -} - -export class Field extends Component<FieldProps> { - state = { - collapsed: this.props.collapsed, - display: this.props.defaultDisplay || 'inline', - }; - - private toggleExpand = () => { - const { onExpandChange } = this.props; - const collapsed = !this.state.collapsed; - this.setState({ - collapsed, - }); - onExpandChange && onExpandChange(!collapsed); - }; - private body: HTMLDivElement | null = null; - private dispose?: () => void; - private deployBlockTesting() { - if (this.dispose) { - this.dispose(); - } - const body = this.body; - if (!body) { - return; - } - const check = () => { - const setter = body.firstElementChild; - if (setter && setter.classList.contains('lc-block-setter')) { - this.setState({ - display: 'block', - }); - } else { - this.setState({ - display: 'inline', - }); - } - }; - const observer = new MutationObserver(check); - check(); - observer.observe(body, { - childList: true, - subtree: true, - attributes: true, - attributeFilter: ['class'], - }); - this.dispose = () => observer.disconnect(); - } - componentDidMount() { - const { defaultDisplay } = this.props; - if (!defaultDisplay || defaultDisplay === 'inline') { - this.deployBlockTesting(); - } - } - componentWillUnmount() { - if (this.dispose) { - this.dispose(); - } - } - - render() { - const { className, children, title } = this.props; - const { display, collapsed } = this.state; - const isAccordion = display === 'accordion'; - return ( - <div - className={classNames(`lc-field lc-${display}-field`, className, { - 'lc-field-is-collapsed': isAccordion && collapsed, - })} - > - <div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}> - <div className="lc-field-title"> - <Title title={title || ''} /> - </div> - {isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />} - </div> - <div key="body" ref={(shell) => (this.body = shell)} className="lc-field-body"> - {children} - </div> - </div> - ); - } -} - -export interface PopupFieldProps extends FieldProps { - width?: number; -} - -export class PopupField extends Component<PopupFieldProps> { - static contextType = PopupContext; - private pipe: any; - - static defaultProps: PopupFieldProps = { - width: 300, - }; - - render() { - const { className, children, title, width } = this.props; - if (!this.pipe) { - this.pipe = (this.context as PopupPipe).create({ width }); - } - - const titleElement = title && ( - <div className="lc-field-title"> - <Title title={title} /> - </div> - ); - - this.pipe.send(<div className="lc-field-body">{children}</div>, titleElement); - - return ( - <div className={classNames('lc-field lc-popup-field', className)}> - {title && ( - <div - className="lc-field-head" - onClick={(e) => { - this.pipe.show((e as any).target); - }} - > - <div className="lc-field-title"> - <Title title={title} /> - </div> - <Icon className="lc-field-icon" type="arrow-left" size="xs" /> - </div> - )} - </div> - ); - } -} - -export interface EntryFieldProps extends FieldProps { - stageName?: string; -} - -export class EntryField extends Component<EntryFieldProps> { - render() { - const { stageName, title, className } = this.props; - const classNameList = classNames('engine-setting-field', 'engine-entry-field', className); - const fieldProps: any = {}; - - if (stageName) { - // 为 stage 切换奠定基础 - fieldProps['data-stage-target'] = stageName; - } - - const innerElements = [ - <span className="engine-field-title" key="field-title"> - {title} - </span>, - // renderTip(tip, { propName }), - // <Icons name="arrow" className="engine-field-arrow" size="12px" key="engine-field-arrow-icon" />, - ]; - - return ( - <div className={classNameList} {...fieldProps}> - {innerElements} - </div> - ); - } -} - -export class PlainField extends Component<FieldProps> { - render() { - const { className, children } = this.props; - return ( - <div className={classNames(`lc-field lc-plain-field`, className)}> - <div className="lc-field-body">{children}</div> - </div> - ); - } -} diff --git a/packages/plugin-settings-pane/src/field/index.less b/packages/plugin-settings-pane/src/field/index.less deleted file mode 100644 index 5fecb74d9..000000000 --- a/packages/plugin-settings-pane/src/field/index.less +++ /dev/null @@ -1,154 +0,0 @@ -@import '../variables.less'; - -@x-gap: 10px; -@y-gap: 8px; - -.lc-field { - // head - .lc-field-head { - display: flex; - align-items: center; - justify-content: space-between; - - .lc-field-title { - display: flex; - align-items: center; - } - .lc-field-icon { - margin-right: @x-gap; - transform-origin: center; - transition: transform 0.1s; - } - } - - &.lc-plain-field { - // for top-level style - padding: 8px 10px; - > .lc-field-body { - flex: 1; - min-width: 0; - display: flex; - align-items: center; - } - } - - &.lc-inline-field { - display: flex; - align-items: center; - // for top-level style - padding: 8px 10px; - - > .lc-field-head { - width: 70px; - margin-right: 1px; - .lc-title-label { - width: 70px; - word-break: break-all; - } - } - > .lc-field-body { - flex: 1; - min-width: 0; - display: flex; - align-items: center; - } - } - - &.lc-block-field, &.lc-accordion-field { - display: block; - &:not(:first-child) { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); - } - > .lc-field-head { - padding-left: @x-gap; - height: 32px; - display: flex; - align-items: center; - font-weight: 500; - background: var(--color-block-background-shallow, rgba(31,56,88,.06)); - border-bottom: 1px solid var(--color-line-normal, @dark-alpha-2); - color: var(--color-title, @white-alpha-2); - user-select: none; - } - - > .lc-field-body { - padding: @y-gap @x-gap/2; - } - - + .lc-inline-field { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); - } - } - - .lc-setter-actions { - display: flex; - align-items: center; - } - - &.lc-block-field { - position: relative; - >.lc-field-body>.lc-block-setter>.lc-setter-actions { - position: absolute; - right: 10px; - top: 0; - height: 32px; - display: flex; - align-items: center; - } - } - - &.lc-accordion-field { - // collapsed - &.lc-field-is-collapsed { - > .lc-field-head .lc-field-icon { - transform: rotate(180deg); - } - > .lc-field-body { - display: none; - } - } - - // 邻近的保持上下距离 - + .lc-field { - margin-top: @y-gap; - } - } - - // 2rd level reset - .lc-field-body { - .lc-inline-field { - padding: @y-gap @x-gap/2 0 @x-gap/2; - &:first-child { - padding-top: 0; - } - + .lc-accordion-field, +.lc-block-field { - margin-top: @y-gap; - } - } - - .lc-field { - border-top: none !important; - } - - .lc-accordion-field, .lc-block-field { - > .lc-field-head { - padding-left: @x-gap/2; - background: var(--color-block-background-light); - border-bottom-color: var(--color-line-light); - > .lc-field-icon { - margin-right: @x-gap/2; - } - } - } - - // 3rd level field title width should short - .lc-field-body .lc-inline-field { - > .lc-field-head { - width: 50px; - .lc-title-label { - width: 50px; - } - } - } - } -} diff --git a/packages/plugin-settings-pane/src/field/index.ts b/packages/plugin-settings-pane/src/field/index.ts deleted file mode 100644 index 2f50d53ff..000000000 --- a/packages/plugin-settings-pane/src/field/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { TitleContent } from '@ali/lowcode-globals'; -import './index.less'; -import { Field, PopupField, EntryField, PlainField } from './fields'; - -export interface FieldProps { - className?: string; - title?: TitleContent | null; - display?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry'; - collapsed?: boolean; - onExpandChange?: (collapsed: boolean) => void; - [extra: string]: any; -} - -export function createField(props: FieldProps, children: ReactNode, type?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry') { - if (type === 'popup') { - return createElement(PopupField, props, children); - } - if (type === 'entry') { - return createElement(EntryField, props, children); - } - if (type === 'plain' || !props.title) { - return createElement(PlainField, props, children); - } - return createElement(Field, { ...props, defaultDisplay: type }, children); -} - -export { Field, PopupField, EntryField, PlainField }; diff --git a/packages/plugin-settings-pane/src/icons/convert.tsx b/packages/plugin-settings-pane/src/icons/convert.tsx deleted file mode 100644 index 71ab8630e..000000000 --- a/packages/plugin-settings-pane/src/icons/convert.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; - -export function IconConvert(props: IconProps) { - return ( - <SVGIcon viewBox="0 0 1024 1024" {...props}> - <path d="M508.16 889.6C291.84 889.6 115.2 714.24 115.2 497.92 115.2 281.6 291.84 106.24 509.44 106.24c43.52 0 85.76 6.4 124.16 20.48l-10.24 30.72c-35.84-11.52-72.96-17.92-113.92-17.92-199.68 0-362.24 161.28-362.24 359.68s162.56 358.4 360.96 358.4 359.68-161.28 359.68-359.68c0-66.56-17.92-131.84-51.2-185.6L844.8 294.4c37.12 60.16 56.32 130.56 56.32 203.52-1.28 216.32-176.64 391.68-392.96 391.68z" /> - <path d="M627.2 140.8m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> - <path d="M832 304.64m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> - <path d="M348.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - <path d="M508.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - <path d="M668.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - </SVGIcon> - ); -} - -IconConvert.displayName = 'Convert'; diff --git a/packages/plugin-settings-pane/src/index.tsx b/packages/plugin-settings-pane/src/index.tsx deleted file mode 100644 index 7816548bc..000000000 --- a/packages/plugin-settings-pane/src/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { createSettingFieldView } from './settings/settings-pane'; -import './transducers/register'; -import './setters/register'; -import './style.less'; -import SettingsMainView from './settings/main-view'; - -export default SettingsMainView; - -export { createSettingFieldView }; diff --git a/packages/plugin-settings-pane/src/popup/index.tsx b/packages/plugin-settings-pane/src/popup/index.tsx deleted file mode 100644 index 503e986f9..000000000 --- a/packages/plugin-settings-pane/src/popup/index.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { createContext, ReactNode, Component, PureComponent } from 'react'; -import { EventEmitter } from 'events'; -import { Balloon } from '@alifd/next'; -import { uniqueId } from '@ali/lowcode-globals'; -import './style.less'; - -export const PopupContext = createContext<PopupPipe>({} as any); - -export class PopupPipe { - private emitter = new EventEmitter(); - private currentId?: string; - - create(props?: object): { send: (content: ReactNode, title: ReactNode) => void; show: (target: Element) => void } { - let sendContent: ReactNode = null; - let sendTitle: ReactNode = null; - const id = uniqueId('popup'); - return { - send: (content: ReactNode, title: ReactNode) => { - sendContent = content; - sendTitle = title; - if (this.currentId === id) { - this.popup({ - ...props, - content, - title, - }); - } - }, - show: (target: Element, actionKey?: string) => { - this.currentId = id; - this.popup( - { - ...props, - actionKey, - content: sendContent, - title: sendTitle, - }, - target, - ); - }, - }; - } - - private popup(props: object, target?: Element) { - Promise.resolve().then(() => { - this.emitter.emit('popupchange', props, target); - }); - } - - onPopupChange(fn: (props: object, target?: Element) => void): () => void { - this.emitter.on('popupchange', fn); - return () => { - this.emitter.removeListener('popupchange', fn); - }; - } - - purge() { - this.emitter.removeAllListeners(); - } -} - -export default class PopupService extends Component<{ actionKey?: string; safeId?: string }> { - private popupPipe = new PopupPipe(); - - componentWillUnmount() { - this.popupPipe.purge(); - } - - render() { - const { children, actionKey, safeId } = this.props; - return ( - <PopupContext.Provider value={this.popupPipe}> - {children} - <PopupContent key={'pop' + actionKey} safeId={safeId} /> - </PopupContext.Provider> - ); - } -} - -export class PopupContent extends PureComponent<{ safeId?: string }> { - static contextType = PopupContext; - state: any = { - visible: false, - pos: {}, - }; - - private dispose = (this.context as PopupPipe).onPopupChange((props, target) => { - const state: any = { - ...props, - visible: true, - }; - if (target) { - const rect = target.getBoundingClientRect(); - state.pos = { - top: rect.top, - height: rect.height, - }; - // todo: compute the align method - } - this.setState(state); - }); - - componentWillUnmount() { - this.dispose(); - } - - render() { - const { content, visible, width, title, pos, actionKey } = this.state; - if (!visible) { - return null; - } - let avoidLaterHidden = true; - setTimeout(() => { - avoidLaterHidden = false; - }, 10); - - const id = uniqueId('ball'); - - return ( - <Balloon - className="lc-ballon" - align="l" - id={this.props.safeId} - safeNode={id} - visible={visible} - style={{ width }} - onVisibleChange={(visible) => { - if (avoidLaterHidden) { - return; - } - if (!visible) { - this.setState({ visible: false }); - } - }} - trigger={<div className="lc-popup-placeholder" style={pos} />} - triggerType="click" - animation={false} - // needAdjust - shouldUpdatePosition - > - <div className="lc-ballon-title">{title}</div> - <div className="lc-ballon-content"> - <PopupService actionKey={actionKey} safeId={id}> - {content} - </PopupService> - </div> - </Balloon> - ); - } -} diff --git a/packages/plugin-settings-pane/src/popup/style.less b/packages/plugin-settings-pane/src/popup/style.less deleted file mode 100644 index b115fd371..000000000 --- a/packages/plugin-settings-pane/src/popup/style.less +++ /dev/null @@ -1,22 +0,0 @@ -.lc-popup-placeholder { - position: fixed; - width: 100%; - pointer-events: none; -} - -.lc-ballon { - padding: 10px; - max-width: 640px; - width: 640px; - .lc-ballon-title { - font-size: 14px; - } - .lc-ballon-content { - margin-top: 10px; - // width: 300px; - } - .next-balloon-close { - top: 4px; - right: 4px; - } -} diff --git a/packages/plugin-settings-pane/src/setters/array-setter/bugs.md b/packages/plugin-settings-pane/src/setters/array-setter/bugs.md deleted file mode 100644 index 8fe96cc16..000000000 --- a/packages/plugin-settings-pane/src/setters/array-setter/bugs.md +++ /dev/null @@ -1,5 +0,0 @@ -* 拖拽排序有问题 -* forceInline 有问题 -* 部分改变不响应 -* 样式还原 -* autofocus diff --git a/packages/plugin-settings-pane/src/setters/array-setter/index.tsx b/packages/plugin-settings-pane/src/setters/array-setter/index.tsx deleted file mode 100644 index 344bd8a0f..000000000 --- a/packages/plugin-settings-pane/src/setters/array-setter/index.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import { Component, Fragment } from 'react'; -import { Icon, Button, Message } from '@alifd/next'; -import { Title, SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-globals'; -import { createSettingFieldView } from '../../settings/settings-pane'; -import { PopupContext, PopupPipe } from '../../popup'; -import Sortable from './sortable'; -import './style.less'; -import { SettingField } from '@ali/lowcode-designer'; - -interface ArraySetterState { - items: SettingField[]; - itemsMap: Map<string | number, SettingField>; - prevLength: number; -} - -interface ArraySetterProps { - value: any[]; - field: SettingField; - itemSetter?: SetterType; - columns?: FieldConfig[]; - multiValue?: boolean; -} - -export class ListSetter extends Component<ArraySetterProps, ArraySetterState> { - static getDerivedStateFromProps(props: ArraySetterProps, state: ArraySetterState) { - const { value, field } = props; - const newLength = value && Array.isArray(value) ? value.length : 0; - if (state && state.prevLength === newLength) { - return null; - } - - // props value length change will go here - const originLength = state ? state.items.length : 0; - if (state && originLength === newLength) { - return { - prevLength: newLength, - }; - } - - const itemsMap = state ? state.itemsMap : new Map<string | number, SettingField>(); - let items = state ? state.items.slice() : []; - if (newLength > originLength) { - for (let i = originLength; i < newLength; i++) { - const item = field.createField({ - name: i, - setter: props.itemSetter, - // FIXME: - forceInline: 1, - }); - items[i] = item; - itemsMap.set(item.id, item); - } - } else if (newLength < originLength) { - const deletes = items.splice(newLength); - deletes.forEach((item) => { - itemsMap.delete(item.id); - }); - } - return { - items, - itemsMap, - prevLength: newLength, - }; - } - - state: ArraySetterState = { - items: [], - itemsMap: new Map<string | number, SettingField>(), - prevLength: 0, - }; - - onSort(sortedIds: Array<string | number>) { - const { itemsMap } = this.state; - const items = sortedIds.map((id, index) => { - const item = itemsMap.get(id)!; - item.setKey(index); - return item; - }); - this.setState({ - items, - }); - } - - private scrollToLast: boolean = false; - onAdd() { - const { items, itemsMap } = this.state; - const { itemSetter } = this.props; - const initialValue = typeof itemSetter === 'object' ? (itemSetter as any).initialValue : null; - const item = this.props.field.createField({ - name: items.length, - setter: itemSetter, - // FIXME: - forceInline: 1, - }); - items.push(item); - itemsMap.set(item.id, item); - item.setValue(typeof initialValue === 'function' ? initialValue(item) : initialValue); - this.scrollToLast = true; - this.setState({ - items: items.slice(), - }); - } - - onRemove(field: SettingField) { - const { items } = this.state; - let i = items.indexOf(field); - if (i < 0) { - return; - } - items.splice(i, 1); - const l = items.length; - while (i < l) { - items[i].setKey(i); - i++; - } - field.remove(); - this.setState({ items: items.slice() }); - } - - componentWillUnmount() { - this.state.items.forEach((field) => { - field.purge(); - }); - } - - shouldComponentUpdate(_: any, nextState: ArraySetterState) { - if (nextState.items !== this.state.items) { - return true; - } - return false; - } - - render() { - let columns: any = null; - if (this.props.columns) { - columns = this.props.columns.map((column) => <Title key={column.name} title={column.title || (column.name as string)} />); - } - - const { items } = this.state; - const scrollToLast = this.scrollToLast; - this.scrollToLast = false; - const lastIndex = items.length - 1; - - const content = - items.length > 0 ? ( - <div className="lc-setter-list-scroll-body"> - <Sortable itemClassName="lc-setter-list-card" onSort={this.onSort.bind(this)}> - {items.map((field, index) => ( - <ArrayItem - key={field.id} - scrollIntoView={scrollToLast && index === lastIndex} - field={field} - onRemove={this.onRemove.bind(this, field)} - /> - ))} - </Sortable> - </div> - ) : this.props.multiValue ? ( - <Message type="warning">当前选择了多个节点,且值不一致,修改会覆盖所有值</Message> - ) : ( - <Message type="notice">当前项目为空</Message> - ); - - return ( - <div className="lc-setter-list lc-block-setter"> - {/*<div className="lc-block-setter-actions"> - <Button size="medium" onClick={this.onAdd.bind(this)}> - <Icon type="add" /> - <span>添加</span> - </Button> - </div>*/} - {columns && <div className="lc-setter-list-columns">{columns}</div>} - {content} - <Button className="lc-setter-list-add" type="primary" onClick={this.onAdd.bind(this)}> - <Icon type="add" /> - <span>添加一项</span> - </Button> - </div> - ); - } -} - -class ArrayItem extends Component<{ - field: SettingField; - onRemove: () => void; - scrollIntoView: boolean; -}> { - shouldComponentUpdate() { - return false; - } - private shell?: HTMLDivElement | null; - componentDidMount() { - if (this.props.scrollIntoView && this.shell) { - this.shell.parentElement!.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); - } - } - render() { - const { onRemove, field } = this.props; - return ( - <div className="lc-listitem" ref={(ref) => (this.shell = ref)}> - <div draggable className="lc-listitem-handler"> - <Icon type="ellipsis" size="small" /> - </div> - <div className="lc-listitem-body">{createSettingFieldView(field, field.parent)}</div> - <div className="lc-listitem-actions"> - <div className="lc-listitem-action" onClick={onRemove}> - <Icon type="ashbin" size="small" /> - </div> - </div> - </div> - ); - } -} - -class TableSetter extends ListSetter { - // todo: - // forceInline = 1 - // has more actions -} - -export default class ArraySetter extends Component<{ - value: any[]; - field: SettingField; - itemSetter?: SetterType; - mode?: 'popup' | 'list'; - forceInline?: boolean; - multiValue?: boolean; -}> { - static contextType = PopupContext; - private pipe: any; - render() { - const { mode, forceInline, ...props } = this.props; - const { field, itemSetter } = props; - let columns: FieldConfig[] | undefined; - if ((itemSetter as SetterConfig)?.componentName === 'ObjectSetter') { - const items: FieldConfig[] = (itemSetter as any).props?.config?.items; - if (items && Array.isArray(items)) { - columns = items.filter((item) => item.isRequired || item.important || (item.setter as any)?.isRequired); - if (columns.length > 4) { - columns = columns.slice(0, 4); - } - } - } - - if (mode === 'popup' || forceInline) { - const title = ( - <Fragment> - 编辑: - <Title title={field.title} /> - </Fragment> - ); - if (!this.pipe) { - let width = 360; - if (columns) { - if (columns.length === 3) { - width = 480; - } else if (columns.length > 3) { - width = 600; - } - } - this.pipe = (this.context as PopupPipe).create({ width }); - } - this.pipe.send(<TableSetter key={field.id} {...props} columns={columns} />, title); - return ( - <Button - type={forceInline ? 'normal' : 'primary'} - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon type="edit" /> - {forceInline ? title : '编辑数组'} - </Button> - ); - } else { - return <ListSetter {...props} columns={columns?.slice(0, 2)} />; - } - } -} diff --git a/packages/plugin-settings-pane/src/setters/array-setter/sortable.less b/packages/plugin-settings-pane/src/setters/array-setter/sortable.less deleted file mode 100644 index 12e9512cd..000000000 --- a/packages/plugin-settings-pane/src/setters/array-setter/sortable.less +++ /dev/null @@ -1,29 +0,0 @@ -.lc-sortable { - position: relative; - - .lc-sortable-card { - box-sizing: border-box; - &:after, &:before { - content: ""; - display: table; - } - &:after { - clear: both; - } - - &.lc-dragging { - outline: 2px dashed var(--color-brand); - outline-offset: -2px; - > * { - visibility: hidden; - } - border-color: transparent !important; - box-shadow: none !important; - background: transparent !important; - } - } - - [draggable] { - cursor: ns-resize; - } -} diff --git a/packages/plugin-settings-pane/src/setters/array-setter/sortable.tsx b/packages/plugin-settings-pane/src/setters/array-setter/sortable.tsx deleted file mode 100644 index 3329470f1..000000000 --- a/packages/plugin-settings-pane/src/setters/array-setter/sortable.tsx +++ /dev/null @@ -1,220 +0,0 @@ -import { Component, Children, ReactElement } from 'react'; -import classNames from 'classnames'; -import './sortable.less'; - -class Sortable extends Component<{ - className?: string; - itemClassName?: string; - onSort?: (sortedIds: Array<string | number>) => void; - dragImageSourceHandler?: (elem: Element) => Element; - children: ReactElement[]; -}> { - private shell?: HTMLDivElement | null; - private items?: Array<string | number>; - private willDetach?: () => void; - componentDidMount() { - const box = this.shell!; - - let isDragEnd: boolean = false; - - /** - * target node to be dragged - */ - let source: Element | null; - - /** - * node to be placed - */ - let ref: Element | null; - - /** - * next sibling of the source node - */ - let origRef: Element | null; - - /** - * accurately locate the node from event - */ - const locate = (e: DragEvent) => { - let y = e.clientY; - if (e.view !== window && e.view!.frameElement) { - y += e.view!.frameElement.getBoundingClientRect().top; - } - let node = box.firstElementChild as HTMLDivElement; - while (node) { - if (node !== source && node.dataset.id) { - const rect = node.getBoundingClientRect(); - - if (rect.height <= 0) continue; - if (y < rect.top + rect.height / 2) { - break; - } - } - node = node.nextElementSibling as HTMLDivElement; - } - return node; - }; - - /** - * find the source node - */ - const getSource = (e: DragEvent) => { - const target = e.target as Element; - if (!target || !box.contains(target) || target === box) { - return null; - } - - let node = box.firstElementChild; - while (node) { - if (node.contains(target)) { - return node; - } - node = node.nextElementSibling; - } - - return null; - }; - - const sort = (beforeId: string | number | null | undefined) => { - if (!source) return; - - const sourceId = (source as HTMLDivElement).dataset.id; - const items = this.items!; - const origIndex = items.findIndex(id => id == sourceId); - - let newIndex = beforeId ? items.findIndex(id => id == beforeId) : items.length; - - if (origIndex < 0 || newIndex < 0) return; - if (this.props.onSort) { - if (newIndex > origIndex) { - newIndex -= 1; - } - if (origIndex === newIndex) return; - const item = items.splice(origIndex, 1); - items.splice(newIndex, 0, item[0]); - - this.props.onSort(items); - } - }; - - const dragstart = (e: DragEvent) => { - isDragEnd = false; - source = getSource(e); - if (!source) { - return false; - } - origRef = source.nextElementSibling; - const rect = source.getBoundingClientRect(); - let dragSource = source; - if (this.props.dragImageSourceHandler) { - dragSource = this.props.dragImageSourceHandler(source); - } - if (e.dataTransfer) { - e.dataTransfer.setDragImage(dragSource, e.clientX - rect.left, e.clientY - rect.top); - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.dropEffect = 'move'; - try { - e.dataTransfer.setData('application/json', {} as any); - } catch (ex) { - // eslint-disable-line - } - } - - setTimeout(() => { - source!.classList.add('lc-dragging'); - }, 0); - return true; - }; - - const placeAt = (beforeRef: Element | null) => { - if (beforeRef) { - if (beforeRef !== source) { - box.insertBefore(source!, beforeRef); - } - } else { - box.appendChild(source!); - } - }; - - const adjust = (e: DragEvent) => { - if (isDragEnd) return; - ref = locate(e); - placeAt(ref); - }; - - let lastDragEvent: DragEvent | null; - const drag = (e: DragEvent) => { - if (!source) return; - e.preventDefault(); - if (lastDragEvent) { - if (lastDragEvent.clientX === e.clientX && lastDragEvent.clientY === e.clientY) { - return; - } - } - lastDragEvent = e; - if (e.dataTransfer) { - e.dataTransfer.effectAllowed = 'move'; - } - adjust(e); - }; - - const dragend = (e: DragEvent) => { - isDragEnd = true; - if (!source) return; - e.preventDefault(); - source.classList.remove('lc-dragging'); - placeAt(origRef); - sort(ref ? (ref as HTMLDivElement).dataset.id : null); - source = null; - ref = null; - origRef = null; - lastDragEvent = null; - }; - - box.addEventListener('dragstart', dragstart); - document.addEventListener('dragover', drag); - document.addEventListener('drag', drag); - document.addEventListener('dragend', dragend); - - this.willDetach = () => { - box.removeEventListener('dragstart', dragstart); - document.removeEventListener('dragover', drag); - document.removeEventListener('drag', drag); - document.removeEventListener('dragend', dragend); - }; - } - - componentWillUnmount() { - if (this.willDetach) { - this.willDetach(); - } - } - - render() { - const { className, itemClassName, children } = this.props; - const items: Array<string | number> = []; - const cards = Children.map(children, child => { - const id = child.key!; - items.push(id); - return ( - <div key={id} data-id={id} className={classNames('lc-sortable-card', itemClassName)}> - {child} - </div> - ); - }); - this.items = items; - - return ( - <div - className={classNames('lc-sortable', className)} - ref={ref => { - this.shell = ref; - }} - > - {cards} - </div> - ); - } -} - -export default Sortable; diff --git a/packages/plugin-settings-pane/src/setters/array-setter/style.less b/packages/plugin-settings-pane/src/setters/array-setter/style.less deleted file mode 100644 index 8e0da024b..000000000 --- a/packages/plugin-settings-pane/src/setters/array-setter/style.less +++ /dev/null @@ -1,103 +0,0 @@ -.lc-setter-list { - [draggable] { - cursor: move; - } - color: var(--color-text); - - .next-btn { - display: inline-flex; - align-items: center; - line-height: 1 !important; - max-width: 100%; - text-overflow: ellipsis; - } - - .lc-setter-list-add { - display: block; - width: 100%; - margin-top: 8px;; - } - - - .lc-setter-list-columns { - display: flex; - > .lc-title { - flex: 1; - justify-content: center; - } - margin-left: 47px; - margin-right: 28px; - margin-bottom: 5px; - } - - .lc-setter-list-scroll-body { - margin: -8px -5px; - padding: 8px 10px; - overflow-y: auto; - max-height: 300px; - } - - .lc-setter-list-card { - border: 1px solid rgba(31,56,88,.2); - background-color: var(--color-block-background-light); - border-radius: 3px; - &:not(:last-child) { - margin-bottom: 5px; - } - - .lc-listitem { - position: relative; - outline: none; - display: flex; - align-items: stretch; - height: 34px; - - .lc-listitem-actions { - margin: 0 3px; - display: inline-flex; - align-items: center; - justify-content: flex-end; - .lc-listitem-action { - text-align: center; - cursor: pointer; - opacity: 0.6; - &:hover { - opacity: 1; - } - } - } - .lc-listitem-body { - flex: 1; - display: flex; - align-items: stretch; - overflow: hidden; - min-width: 0; - text-overflow: ellipsis; - .lc-field { - padding: 0 !important; - display: flex; - align-items: center; - >.lc-field-body { - justify-content: center; - } - } - > * { - width: 100%; - } - .next-btn { - display: block; - width: 100%; - } - } - .lc-listitem-handler { - margin-left: 2px; - display: inline-flex; - align-items: center; - .next-icon-ellipsis { - transform: rotate(90deg); - } - opacity: 0.6; - } - } - } -} diff --git a/packages/plugin-settings-pane/src/setters/mixed-setter/index.tsx b/packages/plugin-settings-pane/src/setters/mixed-setter/index.tsx deleted file mode 100644 index 5217322c2..000000000 --- a/packages/plugin-settings-pane/src/setters/mixed-setter/index.tsx +++ /dev/null @@ -1,257 +0,0 @@ -import React, { Component, isValidElement } from 'react'; -import classNames from 'classnames'; -import { Dropdown, Button, Menu } from '@alifd/next'; -import { - getSetter, - getSettersMap, - SetterConfig, - computed, - obx, - CustomView, - DynamicProps, - DynamicSetter, - TitleContent, - isSetterConfig, - Title, - createSetterContent, - observer, - isDynamicSetter, - shallowIntl, - EmbedTip, - isI18nData, -} from '@ali/lowcode-globals'; -import { IconConvert } from '../../icons/convert'; - -import './style.less'; -import { SettingField } from '@ali/lowcode-designer'; - -export interface SetterItem { - name: string; - title: TitleContent; - setter: string | DynamicSetter | CustomView; - props?: object | DynamicProps; - condition?: (field: SettingField) => boolean; - initialValue?: any | ((field: SettingField) => any); - list: boolean; -} - -function nomalizeSetters(setters?: Array<string | SetterConfig | CustomView | DynamicSetter>): SetterItem[] { - if (!setters) { - const normalized: SetterItem[] = []; - getSettersMap().forEach((setter, name) => { - if (name === 'MixedSetter') { - return; - } - normalized.push({ - name, - title: setter.title || name, - setter: name, - condition: setter.condition, - initialValue: setter.initialValue, - list: setter.recommend || false, - }); - }); - return normalized; - } - const names: string[] = []; - function generateName(n: string) { - let idx = 1; - let got = n; - while (names.indexOf(got) > -1) { - got = `${n}:${idx++}`; - } - names.push(got); - return got; - } - return setters.map((setter) => { - const config: any = { - setter, - list: true, - }; - if (isSetterConfig(setter)) { - config.setter = setter.componentName; - config.props = setter.props; - config.condition = setter.condition; - config.initialValue = setter.initialValue; - config.title = setter.title; - } - if (typeof config.setter === 'string') { - config.name = config.setter; - names.push(config.name); - const info = getSetter(config.setter); - if (!config.title) { - config.title = info?.title || config.setter; - } - if (!config.condition) { - config.condition = info?.condition; - } - if (!config.initialValue) { - config.initialValue = info?.initialValue; - } - } else { - config.name = generateName((config.setter as any).displayName || (config.setter as any).name || 'CustomSetter'); - if (!config.title) { - config.title = config.name; - } - } - return config; - }); -} - -@observer -export default class MixedSetter extends Component<{ - field: SettingField; - setters?: Array<string | SetterConfig | CustomView | DynamicSetter>; - onSetterChange?: (field: SettingField, name: string) => void; - onChange?: (val: any) => void; - value?: any; - className?: string; -}> { - private setters = nomalizeSetters(this.props.setters); - @obx.ref private used?: string; - @computed private getCurrentSetter() { - const { field } = this.props; - let firstMatched: SetterItem | undefined; - for (const setter of this.setters) { - const matched = !setter.condition || setter.condition(field); - if (matched) { - if (setter.name === this.used) { - return setter; - } - if (!firstMatched) { - firstMatched = setter; - } - } - } - return firstMatched; - } - - private useSetter = (name: string) => { - if (name === this.used) { - return; - } - const { field, onChange } = this.props; - const setter = this.setters.find((item) => item.name === name); - this.used = name; - if (setter) { - let newValue: any = setter.initialValue; - if (newValue && typeof newValue === 'function') { - newValue = newValue(field); - } - onChange && onChange(newValue); - } - }; - - private shell: HTMLDivElement | null = null; - private checkIsBlockField() { - if (this.shell) { - const setter = this.shell.firstElementChild; - if (setter && setter.classList.contains('lc-block-setter')) { - this.shell.classList.add('lc-block-setter'); - } else { - this.shell.classList.remove('lc-block-setter'); - } - } - } - componentDidUpdate() { - this.checkIsBlockField(); - } - componentDidMount() { - this.checkIsBlockField(); - } - - render() { - const { className, field, setters, onSetterChange, ...restProps } = this.props; - - const currentSetter = this.getCurrentSetter(); - const isTwoType = this.setters.length < 3; - - let setterContent: any; - const triggerTitle: any = { - tip: { - type: 'i18n', - 'zh-CN': '切换格式', - 'en-US': 'Switch Format', - }, - icon: <IconConvert size={24} />, - }; - if (currentSetter) { - const { setter, title, props } = currentSetter; - let setterProps: any = {}; - let setterType: any; - if (isDynamicSetter(setter)) { - setterType = setter.call(field, field); - } else { - setterType = setter; - } - if (props) { - setterProps = props; - if (typeof setterProps === 'function') { - setterProps = setterProps(field); - } - } - - setterContent = createSetterContent(setterType, { - ...shallowIntl(setterProps), - field, - ...restProps, - }); - if (title) { - if (typeof title !== 'object' || isI18nData(title) || isValidElement(title)) { - triggerTitle.tip = title; - } else { - triggerTitle.tip = title.tip || title.label; - } - } - } else { - // 未匹配的 null 值,显示 NullValue 空值 - // 未匹配的 其它 值,显示 InvalidValue 非法值 - if (restProps.value == null) { - setterContent = <span>NullValue</span>; - } else { - setterContent = <span>InvalidValue</span>; - } - } - const usedName = currentSetter?.name || this.used; - let moreBtnNode = ( - <Title - title={triggerTitle} - className="lc-switch-trigger" - onClick={ - isTwoType - ? () => { - if (this.setters[0]?.name === usedName) { - this.useSetter(this.setters[1]?.name); - } else { - this.useSetter(this.setters[0]?.name); - } - } - : undefined - } - /> - ); - if (!isTwoType) { - moreBtnNode = ( - <Dropdown trigger={moreBtnNode} triggerType="click" align="tr br"> - <Menu selectMode="single" hasSelectedIcon={true} selectedKeys={usedName} onItemClick={this.useSetter}> - {this.setters.filter(setter => setter.list || setter.name === usedName).map((setter) => { - return ( - <Menu.Item key={setter.name}> - <Title title={setter.title} /> - </Menu.Item> - ); - })} - </Menu> - </Dropdown> - ); - } - - return ( - <div ref={(shell) => (this.shell = shell)} className={classNames('lc-setter-mixed', className)}> - {setterContent} - - <div className="lc-setter-actions">{moreBtnNode}</div> - </div> - ); - } -} diff --git a/packages/plugin-settings-pane/src/setters/mixed-setter/style.less b/packages/plugin-settings-pane/src/setters/mixed-setter/style.less deleted file mode 100644 index 6efebb28c..000000000 --- a/packages/plugin-settings-pane/src/setters/mixed-setter/style.less +++ /dev/null @@ -1,30 +0,0 @@ -.lc-setter-mixed { - flex: 1; - min-width: 0; - margin-right: 26px; - display: block; - position: relative; - >.lc-setter-actions { - position: absolute; - right: -2px; - top: 50%; - transform: translate(100%, -50%); - .lc-switch-trigger { - cursor: pointer; - opacity: 0.6; - &:hover { - opacity: 1; - } - } - } - .next-input,.next-date-picker { - width: 100%; - } - &.lc-block-setter { - position: static; - margin-right: 0; - >.lc-setter-actions { - transform: none; - } - } -} diff --git a/packages/plugin-settings-pane/src/setters/object-setter/index.tsx b/packages/plugin-settings-pane/src/setters/object-setter/index.tsx deleted file mode 100644 index 2f84c8adb..000000000 --- a/packages/plugin-settings-pane/src/setters/object-setter/index.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Component, Fragment } from 'react'; -import { Icon, Button } from '@alifd/next'; -import { Title, SetterType, FieldConfig } from '@ali/lowcode-globals'; -import { createSettingFieldView } from '../../settings/settings-pane'; -import { PopupContext, PopupPipe } from '../../popup'; -import { SettingField } from '@ali/lowcode-designer'; -import './style.less'; - -export default class ObjectSetter extends Component<{ - field: SettingField; - descriptor?: string | ((rowField: SettingField) => string); - config: ObjectSetterConfig; - mode?: 'popup' | 'form'; - // 1: in tablerow 2: in listrow 3: in column-cell - forceInline?: number; -}> { - render() { - const { mode, forceInline = 0, ...props } = this.props; - if (forceInline || mode === 'popup') { - if (forceInline > 2 || mode === 'popup') { - // popup - return <RowSetter {...props} primaryButton={forceInline ? false : true} />; - } else { - return <RowSetter columns={forceInline > 1 ? 2 : 4} {...props} />; - } - } else { - // form - return <FormSetter {...props} />; - } - } -} - -interface ObjectSetterConfig { - items?: FieldConfig[]; - extraSetter?: SetterType; -} - -interface RowSetterProps { - field: SettingField; - descriptor?: string | ((rowField: SettingField) => string); - config: ObjectSetterConfig; - columns?: number; - primaryButton?: boolean; -} - -class RowSetter extends Component<RowSetterProps> { - static contextType = PopupContext; - - state: any = { - descriptor: '', - }; - - private items?: SettingField[]; - constructor(props: RowSetterProps) { - super(props); - const { config, descriptor, field, columns } = props; - const items: SettingField[] = []; - if (columns && config.items) { - const l = Math.min(config.items.length, columns); - for (let i = 0; i < l; i++) { - const conf = config.items[i]; - if (conf.isRequired || conf.important || (conf.setter as any)?.isRequired) { - const item = field.createField({ - ...conf, - // in column-cell - forceInline: 3, - }); - items.push(item); - } - } - } - - if (items.length > 0) { - this.items = items; - } - - let firstRun: boolean = true; - field.onEffect(() => { - let state: any = {}; - if (descriptor) { - if (typeof descriptor === 'function') { - state.descriptor = descriptor(field); - } else { - state.descriptor = field.getPropValue(descriptor); - } - } else { - state.descriptor = field.title; - } - - if (firstRun) { - firstRun = false; - this.state = state; - } else { - this.setState(state); - } - }); - } - - shouldComponentUpdate(_: any, nextState: any) { - if (this.state.decriptor !== nextState.decriptor) { - return true; - } - return false; - } - - private pipe: any; - render() { - const items = this.items; - const { field, primaryButton, config } = this.props; - - if (!this.pipe) { - this.pipe = (this.context as PopupPipe).create({ width: 320 }); - } - - const title = ( - <Fragment> - 编辑: - <Title title={this.state.descriptor} /> - </Fragment> - ); - - this.pipe.send(<FormSetter key={field.id} field={field} config={config} />, title); - - if (items) { - return ( - <div className="lc-setter-object-row"> - <div - className="lc-setter-object-row-edit" - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon size="small" type="edit" /> - </div> - <div className="lc-setter-object-row-body">{items.map((item) => createSettingFieldView(item, field))}</div> - </div> - ); - } - - return ( - <Button - type={primaryButton === false ? 'normal' : 'primary'} - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon type="edit" /> - {title} - </Button> - ); - } -} - -interface FormSetterProps { - field: SettingField; - config: ObjectSetterConfig; -} -class FormSetter extends Component<FormSetterProps> { - private items: SettingField[]; - constructor(props: RowSetterProps) { - super(props); - const { config, field } = props; - this.items = (config.items || []).map((conf) => field.createField(conf)); - - // TODO: extraConfig for custom fields - } - - shouldComponentUpdate() { - return false; - } - - render() { - const { field } = this.props; - return ( - <div className="lc-setter-object lc-block-setter"> - {this.items.map((item, index) => createSettingFieldView(item, field, index))} - </div> - ); - } -} diff --git a/packages/plugin-settings-pane/src/setters/object-setter/style.less b/packages/plugin-settings-pane/src/setters/object-setter/style.less deleted file mode 100644 index 6d6064df1..000000000 --- a/packages/plugin-settings-pane/src/setters/object-setter/style.less +++ /dev/null @@ -1,31 +0,0 @@ -.lc-setter-object-row { - display: flex; - align-items: stretch; - width: 100%; - .lc-setter-object-row-edit { - width: 20px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - } - .lc-setter-object-row-body { - display: flex; - flex: 1; - min-width: 0; - align-items: center; - .lc-field { - padding: 0 !important; - .lc-field-body { - padding: 0 !important; margin: 0 !important; - } - } - > * { - flex: 1; - flex-shrink: 1; - margin-left: 2px; - min-width: 0; - overflow: hidden; - } - } -} diff --git a/packages/plugin-settings-pane/src/setters/register.ts b/packages/plugin-settings-pane/src/setters/register.ts deleted file mode 100644 index 13eb3f56f..000000000 --- a/packages/plugin-settings-pane/src/setters/register.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { registerSetter, isPlainObject } from '@ali/lowcode-globals'; -import ArraySetter from './array-setter'; -import ObjectSetter from './object-setter'; -import MixedSetter from './mixed-setter'; - -registerSetter('ArraySetter', { - component: ArraySetter, - defaultProps: {}, - title: 'ArraySetter', // TODO - condition: (field: any) => { - const v = field.getValue(); - return v == null || Array.isArray(v); - }, - initialValue: [], - recommend: true, -}); -registerSetter('ObjectSetter', { - component: ObjectSetter, - // todo: defaultProps - defaultProps: {}, - title: 'ObjectSetter', // TODO - condition: (field: any) => { - const v = field.getValue(); - return v == null || isPlainObject(v); - }, - initialValue: {}, - recommend: true, -}); -registerSetter('MixedSetter', MixedSetter); diff --git a/packages/plugin-settings-pane/src/settings/main-view.tsx b/packages/plugin-settings-pane/src/settings/main-view.tsx deleted file mode 100644 index e77fb9e2e..000000000 --- a/packages/plugin-settings-pane/src/settings/main-view.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { Component, PureComponent } from 'react'; -import { Tab, Breadcrumb } from '@alifd/next'; -import { Title, createIcon, observer } from '@ali/lowcode-globals'; -import { Node, isSettingField, SettingField } from '@ali/lowcode-designer'; -import { Pane as OutlinePane } from '@ali/lowcode-plugin-outline-pane'; -import Editor from '@ali/lowcode-editor-core'; -import { SettingsMain } from './main'; -import SettingsPane from './settings-pane'; - -@observer -export default class SettingsMainView extends Component<{ editor: Editor }> { - private main = new SettingsMain(this.props.editor); - - shouldComponentUpdate() { - return false; - } - - componentWillUnmount() { - this.main.purge(); - } - - renderBreadcrumb() { - const { settings } = this.main; - if (!settings) { - return null; - } - if (settings.isMultiple) { - return ( - <div className="lc-settings-navigator"> - {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} - <Title title={settings.componentMeta!.title} /> - <span>x {settings.nodes.length}</span> - </div> - ); - } - - let node: Node | null = settings.first; - const items = []; - let l = 3; - while (l-- > 0 && node) { - const props = - l === 2 - ? {} - : { - onMouseOver: hoverNode.bind(null, node, true), - onMouseOut: hoverNode.bind(null, node, false), - onClick: selectNode.bind(null, node), - }; - items.unshift(<Breadcrumb.Item {...props} key={node.id}><Title title={node.title} /></Breadcrumb.Item>); - node = node.parent; - } - - return ( - <div className="lc-settings-navigator"> - {createIcon(this.main.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} - <Breadcrumb className="lc-settings-node-breadcrumb">{items}</Breadcrumb> - </div> - ); - } - - render() { - const { settings } = this.main; - if (!settings) { - // 未选中节点,提示选中 或者 显示根节点设置 - return ( - <div className="lc-settings-main"> - <OutlinePaneEntry main={this.main} /> - <div className="lc-settings-notice"> - <p>请在左侧画布选中节点</p> - </div> - </div> - ); - } - - if (!settings.isSameComponent) { - // todo: future support 获取设置项交集编辑 - return ( - <div className="lc-settings-main"> - <OutlinePaneEntry main={this.main} /> - <div className="lc-settings-notice"> - <p>请选中同一类型节点编辑</p> - </div> - </div> - ); - } - - const { items } = settings; - if (items.length > 5 || items.some(item => !isSettingField(item) || !item.isGroup)) { - return ( - <div className="lc-settings-main"> - <OutlinePaneEntry main={this.main} /> - {this.renderBreadcrumb()} - <div className="lc-settings-body"> - <SettingsPane target={settings} /> - </div> - </div> - ); - } - - return ( - <div className="lc-settings-main"> - <OutlinePaneEntry main={this.main} /> - <Tab - navClassName="lc-settings-tabs" - animation={false} - excessMode="dropdown" - contentClassName="lc-settings-tabs-content" - extra={this.renderBreadcrumb()} - > - {(items as SettingField[]).map(field => ( - <Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}> - <SettingsPane target={field} key={field.id} /> - </Tab.Item> - ))} - </Tab> - </div> - ); - } -} - -class OutlinePaneEntry extends PureComponent<{ main: SettingsMain }> { - state = { - outlineInited: false, - }; - private dispose = this.props.main.onceOutlineVisible(() => { - this.setState({ - outlineInited: true, - }); - }); - componentWillUnmount() { - this.dispose(); - } - render() { - if (!this.state.outlineInited) { - return null; - } - return <OutlinePane editor={this.props.main.editor} config={{ - name: '__IN_SETTINGS__' - }} />; - } -} - -function hoverNode(node: Node, flag: boolean) { - node.hover(flag); -} -function selectNode(node: Node) { - node.select(); -} diff --git a/packages/plugin-settings-pane/src/settings/main.ts b/packages/plugin-settings-pane/src/settings/main.ts deleted file mode 100644 index f752add28..000000000 --- a/packages/plugin-settings-pane/src/settings/main.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { EventEmitter } from 'events'; -import { obx, computed } from '@ali/lowcode-globals'; -import { Node, Designer, Selection, SettingTopEntry } from '@ali/lowcode-designer'; -import { getTreeMaster } from '@ali/lowcode-plugin-outline-pane'; -import Editor from '@ali/lowcode-editor-core'; - -function generateSessionId(nodes: Node[]) { - return nodes - .map((node) => node.id) - .sort() - .join(','); -} - -export class SettingsMain { - private emitter = new EventEmitter(); - private _sessionId = ''; - @obx.ref private _settings?: SettingTopEntry; - - @computed get length(): number | undefined { - return this._settings?.nodes.length; - } - - @computed get componentMeta() { - return this._settings?.componentMeta; - } - - get settings() { - return this._settings; - } - - private disposeListener: () => void; - - private designer?: Designer; - - constructor(readonly editor: Editor) { - this.init(); - } - - private async init() { - const setupSelection = (selection?: Selection) => { - if (selection) { - this.setup(selection.getNodes()); - } else { - this.setup([]); - } - }; - this.editor.on('designer.selection.change', setupSelection); - this.disposeListener = () => { - this.editor.removeListener('designer.selection.change', setupSelection); - }; - const designer = await this.editor.onceGot(Designer); - this.designer = designer; - getTreeMaster(designer).onceEnableBuiltin(() => { - this.emitter.emit('outline-visible'); - }); - setupSelection(designer.currentSelection); - } - - private setup(nodes: Node[]) { - // check nodes change - const sessionId = generateSessionId(nodes); - if (sessionId === this._sessionId) { - return; - } - this._sessionId = sessionId; - if (nodes.length < 1) { - this._settings = undefined; - return; - } - - if (!this.designer) { - this.designer = nodes[0].document.designer; - } - - this._settings = this.designer.createSettingEntry(this.editor, nodes); - } - - onceOutlineVisible(fn: () => void): () => void { - this.emitter.on('outline-visible', fn); - return () => { - this.emitter.removeListener('outline-visible', fn); - }; - } - - purge() { - this.disposeListener(); - this.emitter.removeAllListeners(); - } -} diff --git a/packages/plugin-settings-pane/src/settings/settings-pane.tsx b/packages/plugin-settings-pane/src/settings/settings-pane.tsx deleted file mode 100644 index 11edc8a4c..000000000 --- a/packages/plugin-settings-pane/src/settings/settings-pane.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import { Component } from 'react'; -import { - createContent, - CustomView, - intl, - shallowIntl, - isSetterConfig, - createSetterContent, - observer, -} from '@ali/lowcode-globals'; -import { Field, createField } from '../field'; -import PopupService from '../popup'; -import { SettingField, isSettingField, SettingTopEntry, SettingEntry } from '@ali/lowcode-designer'; - -@observer -class SettingFieldView extends Component<{ field: SettingField }> { - render() { - const { field } = this.props; - const { extraProps } = field; - const { condition, defaultValue } = extraProps; - const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; - if (!visible) { - return null; - } - const { setter } = field; - - let setterProps: any = {}; - let setterType: any; - if (Array.isArray(setter)) { - setterType = 'MixedSetter'; - setterProps = { - setters: setter, - }; - } else if (isSetterConfig(setter)) { - setterType = setter.componentName; - if (setter.props) { - setterProps = setter.props; - if (typeof setterProps === 'function') { - setterProps = setterProps(field); - } - } - } else if (setter) { - setterType = setter; - } - let value = null; - if (field.type === 'field') { - if (defaultValue != null && !('defaultValue' in setterProps)) { - setterProps.defaultValue = defaultValue; - } - if (field.valueState > 0) { - value = field.getValue(); - } else { - setterProps.multiValue = true; - if (!('placeholder' in setterProps)) { - // FIXME! move to locale file - setterProps.placeholder = intl({ - type: 'i18n', - 'zh-CN': '多种值', - 'en-US': 'Multiple Value', - }); - } - } - } - - // todo: error handling - - return createField({ - title: field.title, - collapsed: !field.expanded, - onExpandChange: (expandState) => field.setExpanded(expandState), - }, createSetterContent(setterType, { - ...shallowIntl(setterProps), - forceInline: extraProps.forceInline, - key: field.id, - // === injection - prop: field, // for compatible vision - field, - // === IO - value, // reaction point - onChange: (value: any) => { - this.setState({ - value, - }); - field.setValue(value); - }, - }), extraProps.forceInline ? 'plain' : extraProps.display); - } -} - -@observer -class SettingGroupView extends Component<{ field: SettingField }> { - shouldComponentUpdate() { - return false; - } - - render() { - const { field } = this.props; - const { extraProps } = field; - const { condition } = extraProps; - const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; - - if (!visible) { - return null; - } - - // todo: split collapsed state | field.items for optimize - return ( - <Field defaultDisplay="accordion" title={field.title} collapsed={!field.expanded} onExpandChange={(expandState) => { - field.setExpanded(expandState); - }}> - {field.items.map((item, index) => createSettingFieldView(item, field, index))} - </Field> - ); - } -} - -export function createSettingFieldView(item: SettingField | CustomView, field: SettingEntry, index?: number) { - if (isSettingField(item)) { - if (item.isGroup) { - return <SettingGroupView field={item} key={item.id} />; - } else { - return <SettingFieldView field={item} key={item.id} />; - } - } else { - return createContent(item, { key: index, field }); - } -} - -@observer -export default class SettingsPane extends Component<{ target: SettingTopEntry | SettingField }> { - shouldComponentUpdate() { - return false; - } - - render() { - const { target } = this.props; - const items = target.items - return ( - <div className="lc-settings-pane"> - {/* todo: add head for single use */} - <PopupService> - <div className="lc-settings-content"> - {items.map((item, index) => createSettingFieldView(item, target, index))} - </div> - </PopupService> - </div> - ); - } -} diff --git a/packages/plugin-settings-pane/src/style.less b/packages/plugin-settings-pane/src/style.less deleted file mode 100644 index 9b2c2b403..000000000 --- a/packages/plugin-settings-pane/src/style.less +++ /dev/null @@ -1,124 +0,0 @@ -.lc-settings-main { - position: relative; - height: 100%; - overflow: hidden; - - .lc-settings-notice { - text-align: center; - font-size: 12px; - font-family: PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica,Arial,sans-serif; - color: var(--color-text ,rgba(0,0,0,.6)); - padding: 50px 15px 0; - } - - .lc-settings-navigator { - height: 30px; - display: flex; - align-items: center; - padding-left: 5px; - border-bottom: 1px solid var(--color-line-normal); - .lc-settings-navigator-icon { - width: 16px; - height: 16px; - * { - fill: var(--color-icon-normal, rgba(31, 56, 88, 0.4)); - } - } - .lc-settings-node-breadcrumb { - margin-left: 5px; - .next-breadcrumb { - display: inline-flex; - align-items: stretch; - height: 24px; - } - .next-breadcrumb-item { - display: inline-flex; - align-items: center; - cursor: default; - &:not(:last-child):hover { - cursor: pointer; - } - .next-breadcrumb-text { - font-size: 12px; - } - } - } - } - - .lc-settings-body { - position: absolute; - top: 30px; - right: 0; - left: 0; - bottom: 0; - overflow-y: auto; - } - - // ====== reset fusion-tabs ===== - .lc-settings-tabs { - position: relative; - overflow: visible; - > .next-tabs-nav-extra { - position: absolute !important; - top: 40px !important; - left: 0 !important; - height: 30px; - right: 0; - transform: none !important; - - } - .next-tabs-nav-container { - .next-tabs-nav { - display: flex; - .next-tabs-tab.lc-settings-tab-item { - flex: 1; - min-width: 0; - outline: none; - .next-tabs-tab-inner { - text-align: center; - padding: 12px 0; - } - } - } - } - } - - .lc-settings-tabs-content { - position: absolute; - top: 70px; - left:0; - right: 0; - bottom: 0; - .next-tabs-tabpane { - position: absolute; - top: 0; - right: 0; - left: 0; - bottom: 0; - overflow-y: auto; - outline: none !important; - box-shadow: none !important; - } - } - .lc-outline-pane { - position: absolute; - z-index: 100; - background-color: white; - top: 0; - bottom: 0; - display: none; - } -} - -.lc-settings-pane { - padding-bottom: 50px; - .next-btn { - line-height: 1 !important; - } -} - -html.lc-cursor-dragging:not(.lowcode-has-fixed-tree) { - .lc-settings-main .lc-outline-pane { - display: block; - } -} diff --git a/packages/plugin-settings-pane/src/transducers/addon-combine.ts b/packages/plugin-settings-pane/src/transducers/addon-combine.ts deleted file mode 100644 index 4f6b3e42d..000000000 --- a/packages/plugin-settings-pane/src/transducers/addon-combine.ts +++ /dev/null @@ -1,256 +0,0 @@ -import { TransformedComponentMetadata, FieldConfig } from '@ali/lowcode-globals'; -import { SettingField } from '../settings/setting-field'; - -export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { - const { componentName, configure = {} } = metadata; - if (componentName === 'Leaf') { - return { - ...metadata, - configure: { - ...configure, - combined: [ - { - name: 'children', - title: { type: 'i18n', 'zh-CN': '内容设置', 'en-US': 'Content' }, - setter: { - componentName: 'MixinSetter', - props: { - // TODO: - setters: [ - { - componentName: 'StringSetter', - props: { - // TODO: textarea mode - multiline: true, - }, - initialValue: '', - }, - { - componentName: 'ExpressionSetter', - initialValue: { - type: 'JSExpression', - value: '', - }, - }, - ], - }, - }, - }, - ], - }, - }; - } - - const { props, events = {}, styles } = configure as any; - const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; - const eventsDefinition: any[] = []; - const supportedLifecycles = - events.supportedLifecycles || - (isRoot - ? [ - { - description: '初始化时', - name: 'constructor', - }, - { - description: '装载后', - name: 'componentDidMount', - }, - { - description: '更新时', - name: 'componentDidMount', - }, - { - description: '卸载时', - name: 'componentWillUnmount', - }, - ] - : null); - if (supportedLifecycles) { - eventsDefinition.push({ - type: 'lifeCycleEvent', - title: '生命周期', - list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)), - }); - } - if (events.supportedEvents) { - eventsDefinition.push({ - type: 'events', - title: '事件', - list: (events.supportedEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), - }); - } - // 通用设置 - const propsGroup = props || []; - propsGroup.push({ - name: '#generals', - title: { type: 'i18n', 'zh-CN': '通用', 'en-US': 'General' }, - items: [ - { - name: 'id', - title: 'ID', - setter: 'StringSetter', - }, - { - name: 'key', - title: 'Key', - // todo: use Mixin - setter: 'StringSetter', - }, - { - name: 'ref', - title: 'Ref', - setter: 'StringSetter', - }, - /* - { - name: '!more', - title: '更多', - setter: 'PropertiesSetter', - },*/ - ], - }); - const combined: FieldConfig[] = [ - { - title: { type: 'i18n', 'zh-CN': '属性', 'en-US': 'Props' }, - name: '#props', - items: propsGroup, - }, - ]; - const stylesGroup: FieldConfig[] = []; - if (styles?.supportClassName) { - stylesGroup.push({ - name: 'className', - title: { type: 'i18n', 'zh-CN': '类名绑定', 'en-US': 'ClassName' }, - setter: 'ClassNameSetter', - }); - } - if (styles?.supportInlineStyle) { - stylesGroup.push({ - name: 'style', - title: { type: 'i18n', 'zh-CN': '行内样式', 'en-US': 'Style' }, - setter: 'StyleSetter', - }); - } - if (stylesGroup.length > 0) { - combined.push({ - name: '#styles', - title: { type: 'i18n', 'zh-CN': '样式', 'en-US': 'Styles' }, - items: stylesGroup, - }); - } - - if (eventsDefinition.length > 0) { - combined.push({ - name: '#events', - title: { type: 'i18n', 'zh-CN': '事件', 'en-US': 'Events' }, - items: [ - { - name: '!events', - title: { type: 'i18n', 'zh-CN': '事件设置', 'en-US': 'Events' }, - setter: { - componentName: 'EventsSetter', - props: { - definition: eventsDefinition, - }, - }, - getValue(field: SettingField, val?: any[]) { - // todo: - return val; - }, - - setValue(field: SettingField, eventDataList: any[]) { - // todo: - return; - }, - }, - ], - }); - } - - if (isRoot) { - /* - combined.push({ - name: '#advanced', - title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, - items: [], - }); - */ - } else { - combined.push({ - name: '#advanced', - title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, - items: [ - { - name: '__condition', - title: { type: 'i18n', 'zh-CN': '条件显示', 'en-US': 'Condition' }, - setter: 'ExpressionSetter', - }, - { - name: '#loop', - title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' }, - items: [ - { - name: '__loop', - title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, - setter: { - componentName: 'MixinSetter', - props: { - // TODO: - setters: [ - { - componentName: 'JSONSetter', - props: { - mode: 'popup', - placeholder: { type: 'i18n', 'zh-CN': '编辑数据', 'en-US': 'Edit Data' }, - }, - }, - { - componentName: 'ExpressionSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '绑定数据', 'en-US': 'Bind Data' }, - }, - }, - ], - }, - }, - }, - { - name: '__loopArgs.0', - title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' }, - setter: { - componentName: 'StringSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '默认为: item', 'en-US': 'Defaults: item' }, - } - }, - }, - { - name: '__loopArgs.1', - title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' }, - setter: { - componentName: 'StringSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '默认为: index', 'en-US': 'Defaults: index' }, - } - }, - }, - { - name: 'key', - title: 'Key', - setter: 'ExpressionSetter', - }, - ], - }, - ], - }); - } - - return { - ...metadata, - configure: { - ...configure, - combined, - }, - }; -} diff --git a/packages/plugin-settings-pane/src/transducers/parse-props.ts b/packages/plugin-settings-pane/src/transducers/parse-props.ts deleted file mode 100644 index 43bd44221..000000000 --- a/packages/plugin-settings-pane/src/transducers/parse-props.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { - FieldConfig, - PropConfig, - PropType, - SetterType, - OneOf, - Shape, - ObjectOf, - ArrayOf, - TransformedComponentMetadata, -} from '@ali/lowcode-globals'; - -function propConfigToFieldConfig(propConfig: PropConfig): FieldConfig { - const { name, description } = propConfig; - const title = { - label: { - type: 'i18n', - 'en-US': name, - 'zh-CN': description?.slice(0, 10) || name, - }, - tip: description ? `${name} | ${description}` : undefined, - }; - return { - title, - ...propConfig, - setter: propTypeToSetter(propConfig.propType), - }; -} - -function propTypeToSetter(propType: PropType): SetterType { - let typeName: string; - let isRequired: boolean | undefined = false; - if (typeof propType === 'string') { - typeName = propType; - } else { - typeName = propType.type; - isRequired = propType.isRequired; - } - // TODO: use mixinSetter wrapper - switch (typeName) { - case 'string': - return { - componentName: 'StringSetter', - isRequired, - initialValue: '', - }; - - case 'number': - return { - componentName: 'NumberSetter', - isRequired, - initialValue: 0, - }; - case 'bool': - return { - componentName: 'NumberSetter', - isRequired, - initialValue: false, - }; - case 'oneOf': - const dataSource = ((propType as OneOf).value || []).map((value, index) => { - const t = typeof value; - return { - label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`, - value, - }; - }); - const componentName = dataSource.length > 4 ? 'SelectSetter' : 'RadioGroupSetter'; - return { - componentName, - props: { dataSource }, - isRequired, - initialValue: dataSource[0] ? dataSource[0].value : null, - }; - - case 'element': - case 'node': // TODO: use Mixin - return { - // slotSetter - componentName: 'NodeSetter', - props: { - mode: typeName, - }, - isRequired, - initialValue: { - type: 'JSSlot', - value: '', - }, - }; - case 'shape': - case 'exact': - const items = (propType as Shape).value.map((item) => propConfigToFieldConfig(item)); - return { - componentName: 'ObjectSetter', - props: { - config: { - items, - extraSetter: typeName === 'shape' ? propTypeToSetter('any') : null, - }, - }, - isRequired, - initialValue: (field: any) => { - const data: any = {}; - items.forEach((item) => { - let initial = item.defaultValue; - if (initial == null && item.setter && typeof item.setter === 'object') { - initial = (item.setter as any).initialValue; - } - data[item.name] = initial ? (typeof initial === 'function' ? initial(field) : initial) : null; - }); - return data; - }, - }; - case 'object': - case 'objectOf': - return { - componentName: 'ObjectSetter', - props: { - config: { - extraSetter: propTypeToSetter(typeName === 'objectOf' ? (propType as ObjectOf).value : 'any'), - }, - }, - isRequired, - }; - case 'array': - case 'arrayOf': - return { - componentName: 'ArraySetter', - props: { - itemSetter: propTypeToSetter(typeName === 'arrayOf' ? (propType as ArrayOf).value : 'any'), - }, - isRequired, - initialValue: [], - }; - case 'func': - return { - componentName: 'FunctionSetter', - isRequired, - initialValue: { - type: 'JSFunction', - value: 'function(){}', - }, - }; - case 'oneOfType': - return { - componentName: 'MixinSetter', - props: { - // TODO: - // setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), - }, - isRequired, - }; - } - - return { - componentName: 'MixinSetter', - isRequired, - }; -} - -const EVENT_RE = /^on[A-Z][\w]*$/; - -export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { - const { configure } = metadata; - if (configure.props) { - return metadata; - } - - if (!metadata.props) { - return { - ...metadata, - configure: { - ...configure, - props: [], - }, - }; - } - const { component = {}, events = {}, styles = {} } = configure; - const supportedEvents: any[] | null = (events as any).supportedEvents ? null : []; - const props: FieldConfig[] = []; - - metadata.props.forEach((prop) => { - const { name, propType, description } = prop; - if ( - name === 'children' && - (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') - ) { - if (component.isContainer !== false) { - component.isContainer = true; - return; - } - } - - if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) { - if (supportedEvents) { - supportedEvents.push({ - name, - description, - }); - (events as any).supportedEvents = supportedEvents; - } - return; - } - - if (name === 'className' && (propType === 'string' || propType === 'any')) { - if ((styles as any).supportClassName == null) { - (styles as any).supportClassName = true; - } - return; - } - - if (name === 'style' && (propType === 'object' || propType === 'any')) { - if ((styles as any).supportInlineStyle == null) { - (styles as any).supportInlineStyle = true; - } - return; - } - - props.push(propConfigToFieldConfig(prop)); - }); - - return { - ...metadata, - configure: { - ...configure, - props, - events, - styles, - component, - }, - }; -} diff --git a/packages/plugin-settings-pane/src/transducers/register.ts b/packages/plugin-settings-pane/src/transducers/register.ts deleted file mode 100644 index a09e685ed..000000000 --- a/packages/plugin-settings-pane/src/transducers/register.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { registerMetadataTransducer } from '@ali/lowcode-globals'; -import parseProps from './parse-props'; -import addonCombine from './addon-combine'; - -// parseProps -registerMetadataTransducer(parseProps, 10, 'parse-props'); - -// addon/platform custom -registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/plugin-settings-pane/src/utils.js b/packages/plugin-settings-pane/src/utils.js deleted file mode 100644 index b8f5bbdcc..000000000 --- a/packages/plugin-settings-pane/src/utils.js +++ /dev/null @@ -1,41 +0,0 @@ -function getHotterFromSetter(setter) { - return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line -} - -function getTransducerFromSetter(setter) { - return setter && ( - setter.transducer || setter.Transducer - || (setter.type && (setter.type.transducer || setter.type.Transducer)) - ) || null; // eslint-disable-line -} - -function combineTransducer(transducer, arr, context) { - if (!transducer && Array.isArray(arr)) { - const [toHot, toNative] = arr; - transducer = { toHot, toNative }; - } - - return { - toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line - toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line - }; -} - -export class Transducer { - constructor(context, config) { - this.setterTransducer = combineTransducer( - getTransducerFromSetter(config.setter), - getHotterFromSetter(config.setter), - context, - ); - this.context = context; - } - - toHot(data) { - return this.setterTransducer.toHot(data); - } - - toNative(data) { - return this.setterTransducer.toNative(data); - } -} diff --git a/packages/plugin-settings-pane/src/variables.less b/packages/plugin-settings-pane/src/variables.less deleted file mode 100644 index f61f2341c..000000000 --- a/packages/plugin-settings-pane/src/variables.less +++ /dev/null @@ -1,170 +0,0 @@ -/* - * 基础的 DPL 定义使用了 kuma base 的定义,参考: - * https://github.com/uxcore/kuma-base/tree/master/variables - */ - -/** - * =========================================================== - * ==================== Font Family ========================== - * =========================================================== - */ - -/* - * @font-family: "STHeiti", "Microsoft Yahei", "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, Verdana, sans-serif; - */ - - @font-family: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Helvetica, Arial, sans-serif; - @font-family-code: Monaco, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', Helvetica, Arial, sans-serif; - - /** - * =========================================================== - * ===================== Color DPL =========================== - * =========================================================== - */ - - @brand-color-1: rgba(0, 108, 255, 1); - @brand-color-2: rgba(25, 122, 255, 1); - @brand-color-3: rgba(0, 96, 229, 1); - - @brand-color-1-3: rgba(0, 108, 255, 0.6); - @brand-color-1-4: rgba(0, 108, 255, 0.4); - @brand-color-1-5: rgba(0, 108, 255, 0.3); - @brand-color-1-6: rgba(0, 108, 255, 0.2); - @brand-color-1-7: rgba(0, 108, 255, 0.1); - - @brand-color: @brand-color-1; - - @white-alpha-1: rgb(255, 255, 255); // W-1 - @white-alpha-2: rgba(255, 255, 255, 0.8); // W-2 A80 - @white-alpha-3: rgba(255, 255, 255, 0.6); // W-3 A60 - @white-alpha-4: rgba(255, 255, 255, 0.4); // W-4 A40 - @white-alpha-5: rgba(255, 255, 255, 0.3); // W-5 A30 - @white-alpha-6: rgba(255, 255, 255, 0.2); // W-6 A20 - @white-alpha-7: rgba(255, 255, 255, 0.1); // W-7 A10 - @white-alpha-8: rgba(255, 255, 255, 0.06); // W-8 A6 - - @dark-alpha-1: rgba(0, 0, 0, 1); // D-1 A100 - @dark-alpha-2: rgba(0, 0, 0, 0.8); // D-2 A80 - @dark-alpha-3: rgba(0, 0, 0, 0.6); // D-3 A60 - @dark-alpha-4: rgba(0, 0, 0, 0.4); // D-4 A40 - @dark-alpha-5: rgba(0, 0, 0, 0.3); // D-5 A30 - @dark-alpha-6: rgba(0, 0, 0, 0.2); // D-6 A20 - @dark-alpha-7: rgba(0, 0, 0, 0.1); // D-7 A10 - @dark-alpha-8: rgba(0, 0, 0, 0.06); // D-8 A6 - @dark-alpha-9: rgba(0, 0, 0, 0.04); // D-9 A4 - - @normal-alpha-1: rgba(31, 56, 88, 1); // N-1 A100 - @normal-alpha-2: rgba(31, 56, 88, 0.8); // N-2 A80 - @normal-alpha-3: rgba(31, 56, 88, 0.6); // N-3 A60 - @normal-alpha-4: rgba(31, 56, 88, 0.4); // N-4 A40 - @normal-alpha-5: rgba(31, 56, 88, 0.3); // N-5 A30 - @normal-alpha-6: rgba(31, 56, 88, 0.2); // N-6 A20 - @normal-alpha-7: rgba(31, 56, 88, 0.1); // N-7 A10 - @normal-alpha-8: rgba(31, 56, 88, 0.06); // N-8 A6 - @normal-alpha-9: rgba(31, 56, 88, 0.04); // N-9 A4 - - @normal-3: #77879c; - @normal-4: #a3aebd; - @normal-5: #bac3cc; - @normal-6: #d1d7de; - - @gray-dark: #333; // N2_4 - @gray: #666; // N2_3 - @gray-light: #999; // N2_2 - @gray-lighter: #ccc; // N2_1 - - @brand-secondary: #2c2f33; // B2_3 - // 补色 - @brand-complement: #00b3e8; // B3_1 - // 复合 - @brand-comosite: #00c587; // B3_2 - // 浓度 - @brand-deep: #73461d; // B3_3 - - // F1-1 - @brand-danger: rgb(240, 70, 49); - // F1-2 (10% white) - @brand-danger-hover: rgba(240, 70, 49, 0.9); - // F1-3 (5% black) - @brand-danger-focus: rgba(240, 70, 49, 0.95); - - // F2-1 - @brand-warning: rgb(250, 189, 14); - // F3-1 - @brand-success: rgb(102, 188, 92); - // F4-1 - @brand-link: rgb(102, 188, 92); - // F4-2 - @brand-link-hover: #2e76a6; - - // F1-1-7 A10 - @brand-danger-alpha-7: rgba(240, 70, 49, 0.9); - // F1-1-8 A6 - @brand-danger-alpha-8: rgba(240, 70, 49, 0.8); - // F2-1-2 A80 - @brand-warning-alpha-2: rgba(250, 189, 14, 0.8); - // F2-1-7 A10 - @brand-warning-alpha-7: rgba(250, 189, 14, 0.9); - // F3-1-2 A80 - @brand-success-alpha-2: rgba(102, 188, 92, 0.8); - // F3-1-7 A10 - @brand-success-alpha-7: rgba(102, 188, 92, 0.9); - // F4-1-7 A10 - @brand-link-alpha-7: rgba(102, 188, 92, 0.9); - - // 文本色 - @text-primary-color: @dark-alpha-3; - @text-secondary-color: @normal-alpha-3; - @text-thirdary-color: @dark-alpha-4; - @text-disabled-color: @normal-alpha-5; - @text-helper-color: @dark-alpha-4; - @text-danger-color: @brand-danger; - @text-ali-color: #ec6c00; - - /** - * =========================================================== - * =================== Shadow Box ============================ - * =========================================================== - */ - - @box-shadow-1: 0 1px 4px 0 rgba(31, 56, 88, 0.15); // 1 级阴影,物体由原来存在于底面的物体展开,物体和底面关联紧密 - @box-shadow-2: 0 2px 10px 0 rgba(31, 56, 88, 0.15); // 2 级阴影,hover状态,物体层级较高 - @box-shadow-3: 0 4px 15px 0 rgba(31, 56, 88, 0.15); // 3 级阴影,当物体层级高于所有界面元素,弹窗用 - - /** - * =========================================================== - * ================= FontSize of Level ======================= - * =========================================================== - */ - - @fontSize-1: 26px; - @fontSize-2: 20px; - @fontSize-3: 16px; - @fontSize-4: 14px; - @fontSize-5: 12px; - - @fontLineHeight-1: 38px; - @fontLineHeight-2: 30px; - @fontLineHeight-3: 26px; - @fontLineHeight-4: 24px; - @fontLineHeight-5: 20px; - - /** - * =========================================================== - * ================= FontSize of Level ======================= - * =========================================================== - */ - - @global-border-radius: 3px; - @input-border-radius: 3px; - @popup-border-radius: 6px; - - /** - * =========================================================== - * ===================== Transistion ========================= - * =========================================================== - */ - - @transition-duration: 0.3s; - @transition-ease: cubic-bezier(0.23, 1, 0.32, 1); - @transition-delay: 0s; diff --git a/packages/plugin-source-editor/src/index.tsx b/packages/plugin-source-editor/src/index.tsx index 9039c2a67..fb957dbb6 100644 --- a/packages/plugin-source-editor/src/index.tsx +++ b/packages/plugin-source-editor/src/index.tsx @@ -1,9 +1,8 @@ import { Component, isValidElement, ReactElement, ReactNode } from 'react'; import { Tab, Search, Input, Button } from '@alifd/next'; -import Editor from '@ali/lowcode-editor-core'; +import { Editor } from '@ali/lowcode-editor-core'; import { js_beautify, css_beautify } from 'js-beautify'; import MonacoEditor from 'react-monaco-editor'; -import Panel from '../../vision-polyfill/src/skeleton/widget/panel'; // import lolizer from './sorceEditorPlugin', @@ -47,12 +46,12 @@ interface FunctionEventParam { export default class SourceEditor extends Component<{ editor: Editor; - panel?: Panel + panel?: any }> { - private monocoEditer: Object; - private editorCmd: Object; + private monocoEditer: any; + private editorCmd: any; - state = { + state: any = { isShow: false, tabKey: TAB_KEY.JS_TAB, }; @@ -117,18 +116,13 @@ export default class SourceEditor extends Component<{ } openPluginPannel = () => { - const { editor, panel } = this.props; - // 判断面板是否处于激活状态 - if (!editor.leftNav || editor.leftNav != 'sourceEditor') { - // 打开面板 - editor.emit('leftNav.change', 'sourceEditor'); - } + const { panel } = this.props; if (panel) { panel.show(); } } - callEditorEvent = (eventName, params) => { + callEditorEvent = (eventName: any, params: any) => { if (!this.monocoEditer) { this.editorCmd = { eventName, @@ -146,7 +140,7 @@ export default class SourceEditor extends Component<{ }; - initCode = (schema) => { + initCode = (schema: any) => { let jsCode = js_beautify(transfrom.schema2Code(schema), { indent_size: 2, indent_empty_lines: true }); let css; @@ -167,13 +161,13 @@ export default class SourceEditor extends Component<{ */ addFunction(params: FunctionEventParam) { const count = this.monocoEditer.getModel().getLineCount() || 0; - const range = new monaco.Range(count, 1, count, 1); + const range = new (window as any).monaco.Range(count, 1, count, 1); const functionCode = transfrom.getNewFunctionCode(params.functionName); this.monocoEditer.executeEdits('log-source', [ { identifier: 'event_id', range: range, text: functionCode, forceMoveMarkers: true }, ]); setTimeout(() => { - let newPosition = new monaco.Position(count + 1, 2); + let newPosition = new (window as any).monaco.Position(count + 1, 2); this.monocoEditer.setPosition(newPosition); this.monocoEditer.focus(); }, 100); @@ -204,7 +198,7 @@ export default class SourceEditor extends Component<{ } } - editorDidMount = (editor, monaco) => { + editorDidMount = (editor: any, monaco: any) => { console.log('editorDidMount', editor); this.monocoEditer = editor; @@ -247,13 +241,13 @@ export default class SourceEditor extends Component<{ // }); }; - onTabChange = (key) => { + onTabChange = (key: any) => { this.setState({ selectTab: key, }); }; - updateCode = (newCode) => { + updateCode = (newCode: any) => { const { selectTab } = this.state; if (selectTab === TAB_KEY.JS_TAB) { this.setState({ @@ -283,7 +277,7 @@ export default class SourceEditor extends Component<{ {isShow && ( <MonacoEditor value={selectTab == TAB_KEY.JS_TAB ? jsCode : css} - {...defaultEditorOption} + {...defaultEditorOption as any} {...{ language: selectTab == TAB_KEY.JS_TAB ? 'javascript' : 'css' }} onChange={(newCode) => this.updateCode(newCode)} editorDidMount={this.editorDidMount} diff --git a/packages/plugin-source-editor/src/module.d.ts b/packages/plugin-source-editor/src/module.d.ts new file mode 100644 index 000000000..0a8caf778 --- /dev/null +++ b/packages/plugin-source-editor/src/module.d.ts @@ -0,0 +1 @@ +declare module "js-beautify"; diff --git a/packages/plugin-undo-redo/package.json b/packages/plugin-undo-redo/package.json index 8220080f0..a51075418 100644 --- a/packages/plugin-undo-redo/package.json +++ b/packages/plugin-undo-redo/package.json @@ -22,6 +22,8 @@ "@ali/lowcode-designer": "^0.9.3", "@ali/lowcode-editor-core": "^0.8.6", "@ali/lowcode-editor-skeleton": "^0.8.7", + "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-undo-redo/src/index.tsx b/packages/plugin-undo-redo/src/index.tsx index 945b62490..249ed6649 100644 --- a/packages/plugin-undo-redo/src/index.tsx +++ b/packages/plugin-undo-redo/src/index.tsx @@ -1,10 +1,11 @@ import React, { PureComponent } from 'react'; import './index.scss'; -import Editor, { PluginProps } from '@ali/lowcode-editor-core'; +import { Editor } from '@ali/lowcode-editor-core'; import { TopIcon } from '@ali/lowcode-editor-skeleton'; import { Designer } from '@ali/lowcode-designer'; +import { PluginProps } from '@ali/lowcode-types'; -export interface IProps { +export interface IProps extends PluginProps { editor: Editor; logo?: string; } @@ -14,10 +15,7 @@ export interface IState { redoEnable: boolean; } -export default class UndoRedo extends PureComponent< - IProps & PluginProps, - IState -> { +export default class UndoRedo extends PureComponent<IProps, IState> { public static display = 'LowcodeUndoRedo'; private history: any; @@ -80,18 +78,8 @@ export default class UndoRedo extends PureComponent< const { undoEnable, redoEnable } = this.state; return ( <div className="lowcode-plugin-undo-redo"> - <TopIcon - icon="houtui" - title="后退" - disabled={!undoEnable} - onClick={this.handleUndoClick} - /> - <TopIcon - icon="qianjin" - title="前进" - disabled={!redoEnable} - onClick={this.handleRedoClick} - /> + <TopIcon icon="houtui" title="后退" disabled={!undoEnable} onClick={this.handleUndoClick} /> + <TopIcon icon="qianjin" title="前进" disabled={!redoEnable} onClick={this.handleRedoClick} /> </div> ); } diff --git a/packages/plugin-zh-en/package.json b/packages/plugin-zh-en/package.json index fac4b38d7..220a12831 100644 --- a/packages/plugin-zh-en/package.json +++ b/packages/plugin-zh-en/package.json @@ -15,7 +15,8 @@ }, "dependencies": { "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-globals": "^0.9.3", + "@ali/lowcode-utils": "^0.8.0", + "@ali/lowcode-types": "^0.8.0", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-zh-en/src/icons/en.tsx b/packages/plugin-zh-en/src/icons/en.tsx index b0c773309..01b545973 100644 --- a/packages/plugin-zh-en/src/icons/en.tsx +++ b/packages/plugin-zh-en/src/icons/en.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconEn(props: IconProps) { return ( diff --git a/packages/plugin-zh-en/src/icons/zh.tsx b/packages/plugin-zh-en/src/icons/zh.tsx index 98ddad296..b5b324dd2 100644 --- a/packages/plugin-zh-en/src/icons/zh.tsx +++ b/packages/plugin-zh-en/src/icons/zh.tsx @@ -1,4 +1,4 @@ -import { SVGIcon, IconProps } from '@ali/lowcode-globals'; +import { SVGIcon, IconProps } from '@ali/lowcode-utils'; export function IconZh(props: IconProps) { return ( diff --git a/packages/plugin-zh-en/src/locale/index.ts b/packages/plugin-zh-en/src/locale/index.ts index 913dd42f8..dfd17521f 100644 --- a/packages/plugin-zh-en/src/locale/index.ts +++ b/packages/plugin-zh-en/src/locale/index.ts @@ -1,4 +1,4 @@ -import { createIntl } from '@ali/lowcode-globals'; +import { createIntl } from '@ali/lowcode-editor-core'; import en_US from './en-US.json'; import zh_CN from './zh-CN.json'; diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index aec6c9bce..cca8bc1ea 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -14,7 +14,8 @@ }, "dependencies": { "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-globals": "^0.9.3", + "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", "@ali/lowcode-react-renderer": "^0.8.4", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", diff --git a/packages/setters/src/index.tsx b/packages/setters/src/index.tsx index 90ee52426..59b691ebd 100644 --- a/packages/setters/src/index.tsx +++ b/packages/setters/src/index.tsx @@ -30,7 +30,7 @@ export const DateYearSetter = DatePicker.YearPicker; export const DateMonthSetter = DatePicker.MonthPicker; export const DateRangeSetter = DatePicker.RangePicker; -export { ExpressionSetter, MixinSetter, EventsSetter } +export { ExpressionSetter, EventsSetter } // todo: export const ClassNameSetter = () => { diff --git a/packages/types/package.json b/packages/types/package.json index 9bbd9d826..9937c1d98 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -14,21 +14,14 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@alifd/next": "^1.19.16", - "classnames": "^2.2.6", - "monaco-editor": "^0.20.0", "react": "^16", - "react-dom": "^16.7.0" + "power-di": "^2.2.4" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@types/classnames": "^2.2.7", "@types/node": "^13.7.1", "@types/react": "^16", - "@types/react-dom": "^16", - "build-plugin-component": "^0.2.10", - "build-plugin-fusion": "^0.1.0", - "build-plugin-moment-locales": "^0.1.0" + "build-plugin-component": "^0.2.10" }, "ava": { "compileEnhancements": false, diff --git a/packages/types/src/setter-config.ts b/packages/types/src/setter-config.ts index 7bac84279..19eb46f99 100644 --- a/packages/types/src/setter-config.ts +++ b/packages/types/src/setter-config.ts @@ -1,8 +1,15 @@ -import { isReactComponent } from '@ali/lowcode-utils'; -import { ComponentType, ReactElement, isValidElement } from 'react'; +import { ComponentClass, Component, ComponentType, ReactElement, isValidElement } from 'react'; import { TitleContent } from './title'; import { SettingTarget } from './setting-target'; +function isReactClass(obj: any): obj is ComponentClass<any> { + return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component); +} + +function isReactComponent(obj: any): obj is ComponentType<any> { + return obj && (isReactClass(obj) || typeof obj === 'function'); +} + export type CustomView = ReactElement | ComponentType<any>; export type DynamicProps = (target: SettingTarget) => object; diff --git a/packages/utils/README.md b/packages/utils/README.md new file mode 100644 index 000000000..604aaccb8 --- /dev/null +++ b/packages/utils/README.md @@ -0,0 +1 @@ +公用函数集合 diff --git a/packages/utils/build.json b/packages/utils/build.json new file mode 100644 index 000000000..bd5cf18dd --- /dev/null +++ b/packages/utils/build.json @@ -0,0 +1,5 @@ +{ + "plugins": [ + "build-plugin-component" + ] +} diff --git a/packages/utils/package.json b/packages/utils/package.json index e69de29bb..18b5b1318 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -0,0 +1,40 @@ +{ + "name": "@ali/lowcode-utils", + "version": "0.8.0", + "description": "Utils for Ali lowCode engine", + "files": [ + "es", + "lib" + ], + "main": "lib/index.js", + "module": "es/index.js", + "scripts": { + "build": "build-scripts build --skip-demo", + "test": "ava", + "test:snapshot": "ava --update-snapshots" + }, + "dependencies": { + "react": "^16", + "@alifd/next": "^1.19.16", + "@ali/lowcode-utils": "^0.8.0" + }, + "devDependencies": { + "@alib/build-scripts": "^0.1.18", + "@types/node": "^13.7.1", + "@types/react": "^16", + "build-plugin-component": "^0.2.10" + }, + "ava": { + "compileEnhancements": false, + "snapshotDir": "test/fixtures/__snapshots__", + "extensions": [ + "ts" + ], + "require": [ + "ts-node/register" + ] + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + } +} diff --git a/packages/plugin-settings-pane/tsconfig.json b/packages/utils/tsconfig.json similarity index 100% rename from packages/plugin-settings-pane/tsconfig.json rename to packages/utils/tsconfig.json diff --git a/packages/vision-polyfill/src/bundle/prototype.ts b/packages/vision-polyfill/src/bundle/prototype.ts index 11030b8f9..8fa44e3cd 100644 --- a/packages/vision-polyfill/src/bundle/prototype.ts +++ b/packages/vision-polyfill/src/bundle/prototype.ts @@ -1,12 +1,11 @@ import { ComponentType, ReactElement } from 'react'; +import { ComponentMetadata, FieldConfig, InitialItem } from '@ali/lowcode-types'; import { - ComponentMetadata, - uniqueId, + ComponentMeta, + addBuiltinComponentAction, + isComponentMeta, registerMetadataTransducer, - FieldConfig, - InitialItem, -} from '@ali/lowcode-globals'; -import { ComponentMeta, addBuiltinComponentAction, isComponentMeta } from '@ali/lowcode-designer'; +} from '@ali/lowcode-designer'; import { OldPropConfig, OldPrototypeConfig, @@ -16,6 +15,7 @@ import { upgradeConfigure, } from './upgrade-metadata'; import { designer } from '../editor'; +import { uniqueId } from '@ali/lowcode-utils'; const GlobalPropsConfigure: Array<{ position: string; initials?: InitialItem[]; config: FieldConfig }> = []; const Overrides: { diff --git a/packages/vision-polyfill/src/bundle/trunk.ts b/packages/vision-polyfill/src/bundle/trunk.ts index cd676fdf2..a35625282 100644 --- a/packages/vision-polyfill/src/bundle/trunk.ts +++ b/packages/vision-polyfill/src/bundle/trunk.ts @@ -1,6 +1,6 @@ import { ReactElement, ComponentType } from 'react'; import { EventEmitter } from 'events'; -import { registerSetter } from '@ali/lowcode-globals'; +import { registerSetter } from '@ali/lowcode-editor-core'; import Bundle from './bundle'; export class Trunk { diff --git a/packages/vision-polyfill/src/bundle/upgrade-metadata.ts b/packages/vision-polyfill/src/bundle/upgrade-metadata.ts index 00a81efb7..e64ed5556 100644 --- a/packages/vision-polyfill/src/bundle/upgrade-metadata.ts +++ b/packages/vision-polyfill/src/bundle/upgrade-metadata.ts @@ -1,10 +1,11 @@ import { ComponentType, ReactElement, isValidElement, ComponentClass } from 'react'; -import { isI18nData, SettingTarget, InitialItem, isPlainObject, isJSSlot, isJSExpression } from '@ali/lowcode-globals'; +import { isPlainObject } from '@ali/lowcode-utils'; +import { isI18nData, SettingTarget, InitialItem, isJSSlot, isJSExpression } from '@ali/lowcode-types'; type Field = SettingTarget; export enum DISPLAY_TYPE { - NONE = 'none', // => condition'plain' + NONE = 'none', // => condition'plain' PLAIN = 'plain', INLINE = 'inline', BLOCK = 'block', @@ -35,7 +36,7 @@ export interface OldPropConfig { }; defaultValue?: any; // => extraProps.defaultValue initialValue?: any | ((value: any, defaultValue: any) => any); // => initials.initialValue - initial?: (value: any, defaultValue: any) => any // => initials.initialValue + initial?: (value: any, defaultValue: any) => any; // => initials.initialValue display?: DISPLAY_TYPE; // => fieldExtraProps fieldStyle?: DISPLAY_TYPE; // => fieldExtraProps @@ -71,12 +72,12 @@ export interface OldPropConfig { mutator?( // => setValue this: Field, value: any, - /* - hotValue: any, // => x + hotValue: any, + ): /* preValue: any, // => x preHotValue: any, // => x */ - ): void; + void; /** * other values' change will trigger sync function here */ @@ -218,13 +219,13 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) newConfig.title = { label: title, tip: tip.content, - docUrl: tip.url + docUrl: tip.url, }; } else { newConfig.title = { ...(title as any), tip: tip.content, - docUrl: tip.url + docUrl: tip.url, }; } } @@ -260,7 +261,9 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) if (ignore != null || disabled != null) { // FIXME! addFilter extraProps.virtual = (field: Field) => { - if (isDisabled(field)) { return true; } + if (isDisabled(field)) { + return true; + } if (typeof ignore === 'function') { return ignore.call(field, field.getValue()) === true; @@ -302,7 +305,7 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) } return currentValue == null ? defaults : currentValue; - } + }, }); if (sync) { @@ -311,11 +314,11 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) if (value !== undefined) { field.setValue(value); } - } + }; } if (mutator && !slotName) { extraProps.setValue = (field: Field, value: any) => { - mutator.call(field, value); + mutator.call(field, value, value); }; } @@ -324,18 +327,20 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) if (!newConfig.title && slotTitle) { newConfig.title = slotTitle; } - const setters: any[] = [{ - componentName: 'SlotSetter', - initialValue: (field: any, value: any) => { - if (isJSSlot(value)) { - return value; - } - return { - type: 'JSSlot', - value: value == null ? initialChildren : value - }; + const setters: any[] = [ + { + componentName: 'SlotSetter', + initialValue: (field: any, value: any) => { + if (isJSSlot(value)) { + return value; + } + return { + type: 'JSSlot', + value: value == null ? initialChildren : value, + }; + }, }, - }]; + ]; if (allowTextInput !== false) { setters.unshift('StringSetter'); // FIXME: use I18nSetter @@ -351,19 +356,21 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) let primarySetter: any; if (type === 'composite') { const initials: InitialItem[] = []; - const objItems = items ? upgradeConfigure(items, (item) => { - initials.push(item); - }) : []; + const objItems = items + ? upgradeConfigure(items, (item) => { + initials.push(item); + }) + : []; const initial = (target: SettingTarget, value?: any) => { // TODO: const defaults = extraProps.defaultValue; const data: any = {}; - initials.forEach(item => { + initials.forEach((item) => { // FIXME! Target may be a wrong data[item.name] = item.initial(target, isPlainObject(value) ? value[item.name] : null); }); return data; - } + }; addInitial({ name, initial, @@ -385,9 +392,11 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) primarySetter = setter.map(({ setter, condition }) => { return { componentName: setter, - condition: condition ? (field: Field) => { - return condition.call(field, field.getValue()); - } : null, + condition: condition + ? (field: Field) => { + return condition.call(field, field.getValue()); + } + : null, }; }); } else { @@ -396,7 +405,9 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) } if (supportVariable) { if (primarySetter) { - const setters = Array.isArray(primarySetter) ? primarySetter.concat('ExpressionSetter') : [primarySetter, 'ExpressionSetter']; + const setters = Array.isArray(primarySetter) + ? primarySetter.concat('ExpressionSetter') + : [primarySetter, 'ExpressionSetter']; primarySetter = { componentName: 'MixedSetter', props: { @@ -405,8 +416,8 @@ export function upgradePropConfig(config: OldPropConfig, addInitial: AddIntial) if (useVariableChange) { useVariableChange.call(field, { isUseVariable: name === 'ExpressionSetter' }); } - } - } + }, + }, }; } else { primarySetter = 'ExpressionSetter'; @@ -447,7 +458,7 @@ export function upgradeActions(actions?: Array<ComponentType<any> | ReactElement return actions.map((content) => { const type: any = isValidElement(content) ? content.type : content; if (typeof content === 'function') { - const fn = content as (() => ReactElement); + const fn = content as () => ReactElement; content = (({ node }: any) => { fn.call(node); }) as any; @@ -457,7 +468,7 @@ export function upgradeActions(actions?: Array<ComponentType<any> | ReactElement content, important: true, }; - }) + }); } /** @@ -492,10 +503,11 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { canDroping, // hooks - canDraging, canDragging, // handleDragging + canDraging, + canDragging, // handleDragging // events didDropOut, // onNodeRemove - didDropIn, // onNodeAdd + didDropIn, // onNodeAdd subtreeModified, // onSubtreeModified canResizing, // resizing @@ -504,7 +516,6 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { onResizeEnd, // onResizeEnd } = oldConfig; - const meta: any = { componentName, title, @@ -566,7 +577,7 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { experimental.context = context; } if (snippets) { - experimental.snippets = snippets.map(data => { + experimental.snippets = snippets.map((data) => { const { schema = {} } = data; if (!schema.children && initialChildren && typeof initialChildren !== 'function') { schema.children = initialChildren; @@ -596,9 +607,12 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { } } if (initialChildren) { - experimental.initialChildren = typeof initialChildren === 'function' ? (field: Field) => { - return initialChildren.call(field, (field as any).props); - } : initialChildren; + experimental.initialChildren = + typeof initialChildren === 'function' + ? (field: Field) => { + return initialChildren.call(field, (field as any).props); + } + : initialChildren; } if (view) { experimental.view = view; @@ -644,21 +658,21 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { // todo: what is trigger? const { trigger, deltaX, deltaY } = e; onResize(e, trigger, currentNode, deltaX, deltaY); - } + }; } if (onResizeStart) { callbacks.onResizeStart = (e: any, currentNode: any) => { // todo: what is trigger? const { trigger } = e; onResizeStart(e, trigger, currentNode); - } + }; } if (onResizeEnd) { callbacks.onResizeEnd = (e: any, currentNode: any) => { // todo: what is trigger? const { trigger } = e; onResizeEnd(e, trigger, currentNode); - } + }; } experimental.callbacks = callbacks; @@ -675,5 +689,3 @@ export function upgradeMetadata(oldConfig: OldPrototypeConfig) { meta.experimental = experimental; return meta; } - - diff --git a/packages/vision-polyfill/src/demo/index.ts b/packages/vision-polyfill/src/demo/index.ts index af165b707..93bf90a09 100644 --- a/packages/vision-polyfill/src/demo/index.ts +++ b/packages/vision-polyfill/src/demo/index.ts @@ -6,7 +6,7 @@ import getTrunkPane from '@ali/ve-trunk-pane'; import EventBindDialog from '@ali/lowcode-plugin-event-bind-dialog'; import loadUrls from './loader'; import { upgradeAssetsBundle } from './upgrade-assets'; -import { isCSSUrl } from '@ali/lowcode-globals'; +import { isCSSUrl } from '@ali/lowcode-utils'; const { editor, skeleton } = Engine; diff --git a/packages/vision-polyfill/src/drag-engine.ts b/packages/vision-polyfill/src/drag-engine.ts index b6e2fc8a1..97849cd57 100644 --- a/packages/vision-polyfill/src/drag-engine.ts +++ b/packages/vision-polyfill/src/drag-engine.ts @@ -1,5 +1,5 @@ import { designer } from './editor'; -import { DragObjectType, isNode, TransformStage } from '@ali/lowcode-designer'; +import { DragObjectType, isNode } from '@ali/lowcode-designer'; const dragon = designer.dragon; const DragEngine = { diff --git a/packages/vision-polyfill/src/editor.ts b/packages/vision-polyfill/src/editor.ts index 8c5a1afed..c4f8922d2 100644 --- a/packages/vision-polyfill/src/editor.ts +++ b/packages/vision-polyfill/src/editor.ts @@ -1,11 +1,11 @@ -import { globalContext, isPlainObject, isJSBlock } from '@ali/lowcode-globals'; -import Editor from '@ali/lowcode-editor-core'; +import { isJSBlock } from '@ali/lowcode-types'; +import { isPlainObject } from '@ali/lowcode-utils'; +import { globalContext, Editor } from '@ali/lowcode-editor-core'; import { Designer, TransformStage } from '@ali/lowcode-designer'; import { registerSetters } from '@ali/lowcode-setters'; import Outline from '@ali/lowcode-plugin-outline-pane'; -import SettingsPane from '@ali/lowcode-plugin-settings-pane'; import DesignerPlugin from '@ali/lowcode-plugin-designer'; -import { Skeleton } from './skeleton/skeleton'; +import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton'; import Preview from '@ali/lowcode-plugin-sample-preview'; @@ -78,7 +78,7 @@ skeleton.add({ area: 'rightArea', name: 'settingsPane', type: 'Panel', - content: SettingsPane, + content: SettingsPrimaryPane, }); skeleton.add({ area: 'leftArea', diff --git a/packages/vision-polyfill/src/module.d.ts b/packages/vision-polyfill/src/module.d.ts new file mode 100644 index 000000000..3e142d5dd --- /dev/null +++ b/packages/vision-polyfill/src/module.d.ts @@ -0,0 +1,3 @@ +declare module "@ali/visualengine"; +declare module "@ali/visualengine-utils"; +declare module "@ali/ve-trunk-pane" diff --git a/packages/vision-polyfill/src/pages.ts b/packages/vision-polyfill/src/pages.ts index 198ad0db6..4cb868667 100644 --- a/packages/vision-polyfill/src/pages.ts +++ b/packages/vision-polyfill/src/pages.ts @@ -1,5 +1,5 @@ import { designer } from './editor'; -import { RootSchema } from '@ali/lowcode-globals'; +import { RootSchema } from '@ali/lowcode-types'; import { DocumentModel } from '@ali/lowcode-designer'; const { project } = designer; diff --git a/packages/vision-polyfill/src/panes.ts b/packages/vision-polyfill/src/panes.ts index 268bc2d75..c45c4b886 100644 --- a/packages/vision-polyfill/src/panes.ts +++ b/packages/vision-polyfill/src/panes.ts @@ -1,6 +1,6 @@ import { skeleton, editor } from './editor'; import { ReactElement } from 'react'; -import { IWidgetBaseConfig } from './skeleton/types'; +import { IWidgetBaseConfig } from '@ali/lowcode-editor-skeleton'; export interface IContentItemConfig { title: string; diff --git a/packages/vision-polyfill/src/prop.ts b/packages/vision-polyfill/src/prop.ts index fb00d47ef..478fe0ec2 100644 --- a/packages/vision-polyfill/src/prop.ts +++ b/packages/vision-polyfill/src/prop.ts @@ -4,7 +4,7 @@ import { fromJS, Iterable, Map as IMMap } from 'immutable'; import logger from '@ali/vu-logger'; import { uniqueId, cloneDeep, isDataEqual, combineInitial, Transducer } from '@ali/ve-utils'; import I18nUtil from '@ali/ve-i18n-util'; -import { getSetter } from '@ali/lowcode-globals'; +import { getSetter } from '@ali/lowcode-editor-core'; import { editor } from './editor'; import { OldPropConfig, DISPLAY_TYPE } from './bundle/upgrade-metadata'; @@ -264,7 +264,7 @@ export default class Prop implements IVariableSettable { }) { const accessor = this.config.accessor; if (accessor && (!options || !options.disableAccessor)) { - const value = accessor.call(this, this.value); + const value = accessor.call(this as any, this.value); if (!disableCache) { this.value = value; } @@ -314,7 +314,7 @@ export default class Prop implements IVariableSettable { const sync = this.config.sync; if (sync) { - const value = sync.call(this, this.getValue(true)); + const value = sync.call(this as any, this.getValue(true)); if (value !== undefined) { this.setValue(value); } @@ -377,7 +377,7 @@ export default class Prop implements IVariableSettable { this.emitter.emit('ve.prop.useVariableChange', { isUseVariable: flag }); if (this.config.useVariableChange) { - this.config.useVariableChange.call(this, { isUseVariable: flag }); + this.config.useVariableChange.call(this as any, { isUseVariable: flag }); } } @@ -418,7 +418,7 @@ export default class Prop implements IVariableSettable { } if (mutator && !extraOptions.disableMutator) { - mutator.call(this, this.value); + mutator.call(this as any, this.value); } if (this.modify(force)) { @@ -485,7 +485,7 @@ export default class Prop implements IVariableSettable { if (!options || !options.disableMutator) { const mutator = this.config.mutator; if (mutator) { - mutator.call(this, value); + mutator.call(this as any, value); } } @@ -512,7 +512,7 @@ export default class Prop implements IVariableSettable { let hidden = this.config.hidden; if (typeof hidden === 'function') { - hidden = hidden.call(this, this.getValue()); + hidden = hidden.call(this as any, this.getValue()); } return hidden === true; } @@ -520,7 +520,7 @@ export default class Prop implements IVariableSettable { public isDisabled() { let disabled = this.config.disabled; if (typeof disabled === 'function') { - disabled = disabled.call(this, this.getValue()); + disabled = disabled.call(this as any, this.getValue()); } return disabled === true; } @@ -530,7 +530,7 @@ export default class Prop implements IVariableSettable { let ignore = this.config.ignore; if (typeof ignore === 'function') { - ignore = ignore.call(this, this.getValue()); + ignore = ignore.call(this as any, this.getValue()); } return ignore === true; } diff --git a/packages/vision-polyfill/src/skeleton/area.ts b/packages/vision-polyfill/src/skeleton/area.ts deleted file mode 100644 index 3877e175d..000000000 --- a/packages/vision-polyfill/src/skeleton/area.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { obx, computed } from '@ali/lowcode-globals'; -import WidgetContainer from './widget/widget-container'; -import { Skeleton } from './skeleton'; -import { IWidget } from './widget/widget'; -import { IWidgetBaseConfig } from './types'; - -export default class Area<C extends IWidgetBaseConfig = any, T extends IWidget = IWidget> { - @obx private _visible: boolean = true; - - @computed get visible() { - if (this.exclusive) { - return this.container.current != null; - } - return this._visible; - } - - get current() { - if (this.exclusive) { - return this.container.current; - } - return null; - } - - readonly container: WidgetContainer<T, C>; - constructor(readonly skeleton: Skeleton, readonly name: string, handle: (item: T | C) => T, private exclusive?: boolean, defaultSetCurrent: boolean = false) { - this.container = skeleton.createContainer(name, handle, exclusive, () => this.visible, defaultSetCurrent); - } - - @computed isEmpty(): boolean { - return this.container.items.length < 1; - } - - add(config: T | C): T { - return this.container.add(config); - } - - private lastCurrent: T | null = null; - setVisible(flag: boolean) { - if (this.exclusive) { - const current = this.container.current; - if (flag && !current) { - this.container.active(this.lastCurrent || this.container.getAt(0)) - } else if (current) { - this.lastCurrent = current; - this.container.unactive(current); - } - return; - } - this._visible = flag; - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md b/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md deleted file mode 100644 index 8fe96cc16..000000000 --- a/packages/vision-polyfill/src/skeleton/components/array-setter/bugs.md +++ /dev/null @@ -1,5 +0,0 @@ -* 拖拽排序有问题 -* forceInline 有问题 -* 部分改变不响应 -* 样式还原 -* autofocus diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx deleted file mode 100644 index 344bd8a0f..000000000 --- a/packages/vision-polyfill/src/skeleton/components/array-setter/index.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import { Component, Fragment } from 'react'; -import { Icon, Button, Message } from '@alifd/next'; -import { Title, SetterType, FieldConfig, SetterConfig } from '@ali/lowcode-globals'; -import { createSettingFieldView } from '../../settings/settings-pane'; -import { PopupContext, PopupPipe } from '../../popup'; -import Sortable from './sortable'; -import './style.less'; -import { SettingField } from '@ali/lowcode-designer'; - -interface ArraySetterState { - items: SettingField[]; - itemsMap: Map<string | number, SettingField>; - prevLength: number; -} - -interface ArraySetterProps { - value: any[]; - field: SettingField; - itemSetter?: SetterType; - columns?: FieldConfig[]; - multiValue?: boolean; -} - -export class ListSetter extends Component<ArraySetterProps, ArraySetterState> { - static getDerivedStateFromProps(props: ArraySetterProps, state: ArraySetterState) { - const { value, field } = props; - const newLength = value && Array.isArray(value) ? value.length : 0; - if (state && state.prevLength === newLength) { - return null; - } - - // props value length change will go here - const originLength = state ? state.items.length : 0; - if (state && originLength === newLength) { - return { - prevLength: newLength, - }; - } - - const itemsMap = state ? state.itemsMap : new Map<string | number, SettingField>(); - let items = state ? state.items.slice() : []; - if (newLength > originLength) { - for (let i = originLength; i < newLength; i++) { - const item = field.createField({ - name: i, - setter: props.itemSetter, - // FIXME: - forceInline: 1, - }); - items[i] = item; - itemsMap.set(item.id, item); - } - } else if (newLength < originLength) { - const deletes = items.splice(newLength); - deletes.forEach((item) => { - itemsMap.delete(item.id); - }); - } - return { - items, - itemsMap, - prevLength: newLength, - }; - } - - state: ArraySetterState = { - items: [], - itemsMap: new Map<string | number, SettingField>(), - prevLength: 0, - }; - - onSort(sortedIds: Array<string | number>) { - const { itemsMap } = this.state; - const items = sortedIds.map((id, index) => { - const item = itemsMap.get(id)!; - item.setKey(index); - return item; - }); - this.setState({ - items, - }); - } - - private scrollToLast: boolean = false; - onAdd() { - const { items, itemsMap } = this.state; - const { itemSetter } = this.props; - const initialValue = typeof itemSetter === 'object' ? (itemSetter as any).initialValue : null; - const item = this.props.field.createField({ - name: items.length, - setter: itemSetter, - // FIXME: - forceInline: 1, - }); - items.push(item); - itemsMap.set(item.id, item); - item.setValue(typeof initialValue === 'function' ? initialValue(item) : initialValue); - this.scrollToLast = true; - this.setState({ - items: items.slice(), - }); - } - - onRemove(field: SettingField) { - const { items } = this.state; - let i = items.indexOf(field); - if (i < 0) { - return; - } - items.splice(i, 1); - const l = items.length; - while (i < l) { - items[i].setKey(i); - i++; - } - field.remove(); - this.setState({ items: items.slice() }); - } - - componentWillUnmount() { - this.state.items.forEach((field) => { - field.purge(); - }); - } - - shouldComponentUpdate(_: any, nextState: ArraySetterState) { - if (nextState.items !== this.state.items) { - return true; - } - return false; - } - - render() { - let columns: any = null; - if (this.props.columns) { - columns = this.props.columns.map((column) => <Title key={column.name} title={column.title || (column.name as string)} />); - } - - const { items } = this.state; - const scrollToLast = this.scrollToLast; - this.scrollToLast = false; - const lastIndex = items.length - 1; - - const content = - items.length > 0 ? ( - <div className="lc-setter-list-scroll-body"> - <Sortable itemClassName="lc-setter-list-card" onSort={this.onSort.bind(this)}> - {items.map((field, index) => ( - <ArrayItem - key={field.id} - scrollIntoView={scrollToLast && index === lastIndex} - field={field} - onRemove={this.onRemove.bind(this, field)} - /> - ))} - </Sortable> - </div> - ) : this.props.multiValue ? ( - <Message type="warning">当前选择了多个节点,且值不一致,修改会覆盖所有值</Message> - ) : ( - <Message type="notice">当前项目为空</Message> - ); - - return ( - <div className="lc-setter-list lc-block-setter"> - {/*<div className="lc-block-setter-actions"> - <Button size="medium" onClick={this.onAdd.bind(this)}> - <Icon type="add" /> - <span>添加</span> - </Button> - </div>*/} - {columns && <div className="lc-setter-list-columns">{columns}</div>} - {content} - <Button className="lc-setter-list-add" type="primary" onClick={this.onAdd.bind(this)}> - <Icon type="add" /> - <span>添加一项</span> - </Button> - </div> - ); - } -} - -class ArrayItem extends Component<{ - field: SettingField; - onRemove: () => void; - scrollIntoView: boolean; -}> { - shouldComponentUpdate() { - return false; - } - private shell?: HTMLDivElement | null; - componentDidMount() { - if (this.props.scrollIntoView && this.shell) { - this.shell.parentElement!.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); - } - } - render() { - const { onRemove, field } = this.props; - return ( - <div className="lc-listitem" ref={(ref) => (this.shell = ref)}> - <div draggable className="lc-listitem-handler"> - <Icon type="ellipsis" size="small" /> - </div> - <div className="lc-listitem-body">{createSettingFieldView(field, field.parent)}</div> - <div className="lc-listitem-actions"> - <div className="lc-listitem-action" onClick={onRemove}> - <Icon type="ashbin" size="small" /> - </div> - </div> - </div> - ); - } -} - -class TableSetter extends ListSetter { - // todo: - // forceInline = 1 - // has more actions -} - -export default class ArraySetter extends Component<{ - value: any[]; - field: SettingField; - itemSetter?: SetterType; - mode?: 'popup' | 'list'; - forceInline?: boolean; - multiValue?: boolean; -}> { - static contextType = PopupContext; - private pipe: any; - render() { - const { mode, forceInline, ...props } = this.props; - const { field, itemSetter } = props; - let columns: FieldConfig[] | undefined; - if ((itemSetter as SetterConfig)?.componentName === 'ObjectSetter') { - const items: FieldConfig[] = (itemSetter as any).props?.config?.items; - if (items && Array.isArray(items)) { - columns = items.filter((item) => item.isRequired || item.important || (item.setter as any)?.isRequired); - if (columns.length > 4) { - columns = columns.slice(0, 4); - } - } - } - - if (mode === 'popup' || forceInline) { - const title = ( - <Fragment> - 编辑: - <Title title={field.title} /> - </Fragment> - ); - if (!this.pipe) { - let width = 360; - if (columns) { - if (columns.length === 3) { - width = 480; - } else if (columns.length > 3) { - width = 600; - } - } - this.pipe = (this.context as PopupPipe).create({ width }); - } - this.pipe.send(<TableSetter key={field.id} {...props} columns={columns} />, title); - return ( - <Button - type={forceInline ? 'normal' : 'primary'} - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon type="edit" /> - {forceInline ? title : '编辑数组'} - </Button> - ); - } else { - return <ListSetter {...props} columns={columns?.slice(0, 2)} />; - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less deleted file mode 100644 index 12e9512cd..000000000 --- a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.less +++ /dev/null @@ -1,29 +0,0 @@ -.lc-sortable { - position: relative; - - .lc-sortable-card { - box-sizing: border-box; - &:after, &:before { - content: ""; - display: table; - } - &:after { - clear: both; - } - - &.lc-dragging { - outline: 2px dashed var(--color-brand); - outline-offset: -2px; - > * { - visibility: hidden; - } - border-color: transparent !important; - box-shadow: none !important; - background: transparent !important; - } - } - - [draggable] { - cursor: ns-resize; - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx b/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx deleted file mode 100644 index 3329470f1..000000000 --- a/packages/vision-polyfill/src/skeleton/components/array-setter/sortable.tsx +++ /dev/null @@ -1,220 +0,0 @@ -import { Component, Children, ReactElement } from 'react'; -import classNames from 'classnames'; -import './sortable.less'; - -class Sortable extends Component<{ - className?: string; - itemClassName?: string; - onSort?: (sortedIds: Array<string | number>) => void; - dragImageSourceHandler?: (elem: Element) => Element; - children: ReactElement[]; -}> { - private shell?: HTMLDivElement | null; - private items?: Array<string | number>; - private willDetach?: () => void; - componentDidMount() { - const box = this.shell!; - - let isDragEnd: boolean = false; - - /** - * target node to be dragged - */ - let source: Element | null; - - /** - * node to be placed - */ - let ref: Element | null; - - /** - * next sibling of the source node - */ - let origRef: Element | null; - - /** - * accurately locate the node from event - */ - const locate = (e: DragEvent) => { - let y = e.clientY; - if (e.view !== window && e.view!.frameElement) { - y += e.view!.frameElement.getBoundingClientRect().top; - } - let node = box.firstElementChild as HTMLDivElement; - while (node) { - if (node !== source && node.dataset.id) { - const rect = node.getBoundingClientRect(); - - if (rect.height <= 0) continue; - if (y < rect.top + rect.height / 2) { - break; - } - } - node = node.nextElementSibling as HTMLDivElement; - } - return node; - }; - - /** - * find the source node - */ - const getSource = (e: DragEvent) => { - const target = e.target as Element; - if (!target || !box.contains(target) || target === box) { - return null; - } - - let node = box.firstElementChild; - while (node) { - if (node.contains(target)) { - return node; - } - node = node.nextElementSibling; - } - - return null; - }; - - const sort = (beforeId: string | number | null | undefined) => { - if (!source) return; - - const sourceId = (source as HTMLDivElement).dataset.id; - const items = this.items!; - const origIndex = items.findIndex(id => id == sourceId); - - let newIndex = beforeId ? items.findIndex(id => id == beforeId) : items.length; - - if (origIndex < 0 || newIndex < 0) return; - if (this.props.onSort) { - if (newIndex > origIndex) { - newIndex -= 1; - } - if (origIndex === newIndex) return; - const item = items.splice(origIndex, 1); - items.splice(newIndex, 0, item[0]); - - this.props.onSort(items); - } - }; - - const dragstart = (e: DragEvent) => { - isDragEnd = false; - source = getSource(e); - if (!source) { - return false; - } - origRef = source.nextElementSibling; - const rect = source.getBoundingClientRect(); - let dragSource = source; - if (this.props.dragImageSourceHandler) { - dragSource = this.props.dragImageSourceHandler(source); - } - if (e.dataTransfer) { - e.dataTransfer.setDragImage(dragSource, e.clientX - rect.left, e.clientY - rect.top); - e.dataTransfer.effectAllowed = 'move'; - e.dataTransfer.dropEffect = 'move'; - try { - e.dataTransfer.setData('application/json', {} as any); - } catch (ex) { - // eslint-disable-line - } - } - - setTimeout(() => { - source!.classList.add('lc-dragging'); - }, 0); - return true; - }; - - const placeAt = (beforeRef: Element | null) => { - if (beforeRef) { - if (beforeRef !== source) { - box.insertBefore(source!, beforeRef); - } - } else { - box.appendChild(source!); - } - }; - - const adjust = (e: DragEvent) => { - if (isDragEnd) return; - ref = locate(e); - placeAt(ref); - }; - - let lastDragEvent: DragEvent | null; - const drag = (e: DragEvent) => { - if (!source) return; - e.preventDefault(); - if (lastDragEvent) { - if (lastDragEvent.clientX === e.clientX && lastDragEvent.clientY === e.clientY) { - return; - } - } - lastDragEvent = e; - if (e.dataTransfer) { - e.dataTransfer.effectAllowed = 'move'; - } - adjust(e); - }; - - const dragend = (e: DragEvent) => { - isDragEnd = true; - if (!source) return; - e.preventDefault(); - source.classList.remove('lc-dragging'); - placeAt(origRef); - sort(ref ? (ref as HTMLDivElement).dataset.id : null); - source = null; - ref = null; - origRef = null; - lastDragEvent = null; - }; - - box.addEventListener('dragstart', dragstart); - document.addEventListener('dragover', drag); - document.addEventListener('drag', drag); - document.addEventListener('dragend', dragend); - - this.willDetach = () => { - box.removeEventListener('dragstart', dragstart); - document.removeEventListener('dragover', drag); - document.removeEventListener('drag', drag); - document.removeEventListener('dragend', dragend); - }; - } - - componentWillUnmount() { - if (this.willDetach) { - this.willDetach(); - } - } - - render() { - const { className, itemClassName, children } = this.props; - const items: Array<string | number> = []; - const cards = Children.map(children, child => { - const id = child.key!; - items.push(id); - return ( - <div key={id} data-id={id} className={classNames('lc-sortable-card', itemClassName)}> - {child} - </div> - ); - }); - this.items = items; - - return ( - <div - className={classNames('lc-sortable', className)} - ref={ref => { - this.shell = ref; - }} - > - {cards} - </div> - ); - } -} - -export default Sortable; diff --git a/packages/vision-polyfill/src/skeleton/components/array-setter/style.less b/packages/vision-polyfill/src/skeleton/components/array-setter/style.less deleted file mode 100644 index 8e0da024b..000000000 --- a/packages/vision-polyfill/src/skeleton/components/array-setter/style.less +++ /dev/null @@ -1,103 +0,0 @@ -.lc-setter-list { - [draggable] { - cursor: move; - } - color: var(--color-text); - - .next-btn { - display: inline-flex; - align-items: center; - line-height: 1 !important; - max-width: 100%; - text-overflow: ellipsis; - } - - .lc-setter-list-add { - display: block; - width: 100%; - margin-top: 8px;; - } - - - .lc-setter-list-columns { - display: flex; - > .lc-title { - flex: 1; - justify-content: center; - } - margin-left: 47px; - margin-right: 28px; - margin-bottom: 5px; - } - - .lc-setter-list-scroll-body { - margin: -8px -5px; - padding: 8px 10px; - overflow-y: auto; - max-height: 300px; - } - - .lc-setter-list-card { - border: 1px solid rgba(31,56,88,.2); - background-color: var(--color-block-background-light); - border-radius: 3px; - &:not(:last-child) { - margin-bottom: 5px; - } - - .lc-listitem { - position: relative; - outline: none; - display: flex; - align-items: stretch; - height: 34px; - - .lc-listitem-actions { - margin: 0 3px; - display: inline-flex; - align-items: center; - justify-content: flex-end; - .lc-listitem-action { - text-align: center; - cursor: pointer; - opacity: 0.6; - &:hover { - opacity: 1; - } - } - } - .lc-listitem-body { - flex: 1; - display: flex; - align-items: stretch; - overflow: hidden; - min-width: 0; - text-overflow: ellipsis; - .lc-field { - padding: 0 !important; - display: flex; - align-items: center; - >.lc-field-body { - justify-content: center; - } - } - > * { - width: 100%; - } - .next-btn { - display: block; - width: 100%; - } - } - .lc-listitem-handler { - margin-left: 2px; - display: inline-flex; - align-items: center; - .next-icon-ellipsis { - transform: rotate(90deg); - } - opacity: 0.6; - } - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/field/fields.tsx b/packages/vision-polyfill/src/skeleton/components/field/fields.tsx deleted file mode 100644 index d36928604..000000000 --- a/packages/vision-polyfill/src/skeleton/components/field/fields.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { Component } from 'react'; -import classNames from 'classnames'; -import { Icon } from '@alifd/next'; -import { Title, TitleContent } from '@ali/lowcode-globals'; -import { PopupPipe, PopupContext } from '../popup'; -import './index.less'; - -export interface FieldProps { - className?: string; - title?: TitleContent | null; - defaultDisplay?: 'accordion' | 'inline' | 'block'; - collapsed?: boolean; - onExpandChange?: (expandState: boolean) => void; -} - -export class Field extends Component<FieldProps> { - state = { - collapsed: this.props.collapsed, - display: this.props.defaultDisplay || 'inline', - }; - - private toggleExpand = () => { - const { onExpandChange } = this.props; - const collapsed = !this.state.collapsed; - this.setState({ - collapsed, - }); - onExpandChange && onExpandChange(!collapsed); - }; - private body: HTMLDivElement | null = null; - private dispose?: () => void; - private deployBlockTesting() { - if (this.dispose) { - this.dispose(); - } - const body = this.body; - if (!body) { - return; - } - const check = () => { - const setter = body.firstElementChild; - if (setter && setter.classList.contains('lc-block-setter')) { - this.setState({ - display: 'block', - }); - } else { - this.setState({ - display: 'inline', - }); - } - }; - const observer = new MutationObserver(check); - check(); - observer.observe(body, { - childList: true, - subtree: true, - attributes: true, - attributeFilter: ['class'], - }); - this.dispose = () => observer.disconnect(); - } - componentDidMount() { - const { defaultDisplay } = this.props; - if (!defaultDisplay || defaultDisplay === 'inline') { - this.deployBlockTesting(); - } - } - componentWillUnmount() { - if (this.dispose) { - this.dispose(); - } - } - - render() { - const { className, children, title } = this.props; - const { display, collapsed } = this.state; - const isAccordion = display === 'accordion'; - return ( - <div - className={classNames(`lc-field lc-${display}-field`, className, { - 'lc-field-is-collapsed': isAccordion && collapsed, - })} - > - <div className="lc-field-head" onClick={isAccordion ? this.toggleExpand : undefined}> - <div className="lc-field-title"> - <Title title={title || ''} /> - </div> - {isAccordion && <Icon className="lc-field-icon" type="arrow-up" size="xs" />} - </div> - <div key="body" ref={(shell) => (this.body = shell)} className="lc-field-body"> - {children} - </div> - </div> - ); - } -} - -export interface PopupFieldProps extends FieldProps { - width?: number; -} - -export class PopupField extends Component<PopupFieldProps> { - static contextType = PopupContext; - private pipe: any; - - static defaultProps: PopupFieldProps = { - width: 300, - }; - - render() { - const { className, children, title, width } = this.props; - if (!this.pipe) { - this.pipe = (this.context as PopupPipe).create({ width }); - } - - const titleElement = title && ( - <div className="lc-field-title"> - <Title title={title} /> - </div> - ); - - this.pipe.send(<div className="lc-field-body">{children}</div>, titleElement); - - return ( - <div className={classNames('lc-field lc-popup-field', className)}> - {title && ( - <div - className="lc-field-head" - onClick={(e) => { - this.pipe.show((e as any).target); - }} - > - <div className="lc-field-title"> - <Title title={title} /> - </div> - <Icon className="lc-field-icon" type="arrow-left" size="xs" /> - </div> - )} - </div> - ); - } -} - -export interface EntryFieldProps extends FieldProps { - stageName?: string; -} - -export class EntryField extends Component<EntryFieldProps> { - render() { - const { stageName, title, className } = this.props; - const classNameList = classNames('engine-setting-field', 'engine-entry-field', className); - const fieldProps: any = {}; - - if (stageName) { - // 为 stage 切换奠定基础 - fieldProps['data-stage-target'] = stageName; - } - - const innerElements = [ - <span className="engine-field-title" key="field-title"> - {title} - </span>, - // renderTip(tip, { propName }), - // <Icons name="arrow" className="engine-field-arrow" size="12px" key="engine-field-arrow-icon" />, - ]; - - return ( - <div className={classNameList} {...fieldProps}> - {innerElements} - </div> - ); - } -} - -export class PlainField extends Component<FieldProps> { - render() { - const { className, children } = this.props; - return ( - <div className={classNames(`lc-field lc-plain-field`, className)}> - <div className="lc-field-body">{children}</div> - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/field/index.less b/packages/vision-polyfill/src/skeleton/components/field/index.less deleted file mode 100644 index 5fecb74d9..000000000 --- a/packages/vision-polyfill/src/skeleton/components/field/index.less +++ /dev/null @@ -1,154 +0,0 @@ -@import '../variables.less'; - -@x-gap: 10px; -@y-gap: 8px; - -.lc-field { - // head - .lc-field-head { - display: flex; - align-items: center; - justify-content: space-between; - - .lc-field-title { - display: flex; - align-items: center; - } - .lc-field-icon { - margin-right: @x-gap; - transform-origin: center; - transition: transform 0.1s; - } - } - - &.lc-plain-field { - // for top-level style - padding: 8px 10px; - > .lc-field-body { - flex: 1; - min-width: 0; - display: flex; - align-items: center; - } - } - - &.lc-inline-field { - display: flex; - align-items: center; - // for top-level style - padding: 8px 10px; - - > .lc-field-head { - width: 70px; - margin-right: 1px; - .lc-title-label { - width: 70px; - word-break: break-all; - } - } - > .lc-field-body { - flex: 1; - min-width: 0; - display: flex; - align-items: center; - } - } - - &.lc-block-field, &.lc-accordion-field { - display: block; - &:not(:first-child) { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); - } - > .lc-field-head { - padding-left: @x-gap; - height: 32px; - display: flex; - align-items: center; - font-weight: 500; - background: var(--color-block-background-shallow, rgba(31,56,88,.06)); - border-bottom: 1px solid var(--color-line-normal, @dark-alpha-2); - color: var(--color-title, @white-alpha-2); - user-select: none; - } - - > .lc-field-body { - padding: @y-gap @x-gap/2; - } - - + .lc-inline-field { - border-top: 1px solid var(--color-line-normal, @dark-alpha-2); - } - } - - .lc-setter-actions { - display: flex; - align-items: center; - } - - &.lc-block-field { - position: relative; - >.lc-field-body>.lc-block-setter>.lc-setter-actions { - position: absolute; - right: 10px; - top: 0; - height: 32px; - display: flex; - align-items: center; - } - } - - &.lc-accordion-field { - // collapsed - &.lc-field-is-collapsed { - > .lc-field-head .lc-field-icon { - transform: rotate(180deg); - } - > .lc-field-body { - display: none; - } - } - - // 邻近的保持上下距离 - + .lc-field { - margin-top: @y-gap; - } - } - - // 2rd level reset - .lc-field-body { - .lc-inline-field { - padding: @y-gap @x-gap/2 0 @x-gap/2; - &:first-child { - padding-top: 0; - } - + .lc-accordion-field, +.lc-block-field { - margin-top: @y-gap; - } - } - - .lc-field { - border-top: none !important; - } - - .lc-accordion-field, .lc-block-field { - > .lc-field-head { - padding-left: @x-gap/2; - background: var(--color-block-background-light); - border-bottom-color: var(--color-line-light); - > .lc-field-icon { - margin-right: @x-gap/2; - } - } - } - - // 3rd level field title width should short - .lc-field-body .lc-inline-field { - > .lc-field-head { - width: 50px; - .lc-title-label { - width: 50px; - } - } - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/field/index.ts b/packages/vision-polyfill/src/skeleton/components/field/index.ts deleted file mode 100644 index 2f50d53ff..000000000 --- a/packages/vision-polyfill/src/skeleton/components/field/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { TitleContent } from '@ali/lowcode-globals'; -import './index.less'; -import { Field, PopupField, EntryField, PlainField } from './fields'; - -export interface FieldProps { - className?: string; - title?: TitleContent | null; - display?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry'; - collapsed?: boolean; - onExpandChange?: (collapsed: boolean) => void; - [extra: string]: any; -} - -export function createField(props: FieldProps, children: ReactNode, type?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry') { - if (type === 'popup') { - return createElement(PopupField, props, children); - } - if (type === 'entry') { - return createElement(EntryField, props, children); - } - if (type === 'plain' || !props.title) { - return createElement(PlainField, props, children); - } - return createElement(Field, { ...props, defaultDisplay: type }, children); -} - -export { Field, PopupField, EntryField, PlainField }; diff --git a/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx deleted file mode 100644 index 5217322c2..000000000 --- a/packages/vision-polyfill/src/skeleton/components/mixed-setter/index.tsx +++ /dev/null @@ -1,257 +0,0 @@ -import React, { Component, isValidElement } from 'react'; -import classNames from 'classnames'; -import { Dropdown, Button, Menu } from '@alifd/next'; -import { - getSetter, - getSettersMap, - SetterConfig, - computed, - obx, - CustomView, - DynamicProps, - DynamicSetter, - TitleContent, - isSetterConfig, - Title, - createSetterContent, - observer, - isDynamicSetter, - shallowIntl, - EmbedTip, - isI18nData, -} from '@ali/lowcode-globals'; -import { IconConvert } from '../../icons/convert'; - -import './style.less'; -import { SettingField } from '@ali/lowcode-designer'; - -export interface SetterItem { - name: string; - title: TitleContent; - setter: string | DynamicSetter | CustomView; - props?: object | DynamicProps; - condition?: (field: SettingField) => boolean; - initialValue?: any | ((field: SettingField) => any); - list: boolean; -} - -function nomalizeSetters(setters?: Array<string | SetterConfig | CustomView | DynamicSetter>): SetterItem[] { - if (!setters) { - const normalized: SetterItem[] = []; - getSettersMap().forEach((setter, name) => { - if (name === 'MixedSetter') { - return; - } - normalized.push({ - name, - title: setter.title || name, - setter: name, - condition: setter.condition, - initialValue: setter.initialValue, - list: setter.recommend || false, - }); - }); - return normalized; - } - const names: string[] = []; - function generateName(n: string) { - let idx = 1; - let got = n; - while (names.indexOf(got) > -1) { - got = `${n}:${idx++}`; - } - names.push(got); - return got; - } - return setters.map((setter) => { - const config: any = { - setter, - list: true, - }; - if (isSetterConfig(setter)) { - config.setter = setter.componentName; - config.props = setter.props; - config.condition = setter.condition; - config.initialValue = setter.initialValue; - config.title = setter.title; - } - if (typeof config.setter === 'string') { - config.name = config.setter; - names.push(config.name); - const info = getSetter(config.setter); - if (!config.title) { - config.title = info?.title || config.setter; - } - if (!config.condition) { - config.condition = info?.condition; - } - if (!config.initialValue) { - config.initialValue = info?.initialValue; - } - } else { - config.name = generateName((config.setter as any).displayName || (config.setter as any).name || 'CustomSetter'); - if (!config.title) { - config.title = config.name; - } - } - return config; - }); -} - -@observer -export default class MixedSetter extends Component<{ - field: SettingField; - setters?: Array<string | SetterConfig | CustomView | DynamicSetter>; - onSetterChange?: (field: SettingField, name: string) => void; - onChange?: (val: any) => void; - value?: any; - className?: string; -}> { - private setters = nomalizeSetters(this.props.setters); - @obx.ref private used?: string; - @computed private getCurrentSetter() { - const { field } = this.props; - let firstMatched: SetterItem | undefined; - for (const setter of this.setters) { - const matched = !setter.condition || setter.condition(field); - if (matched) { - if (setter.name === this.used) { - return setter; - } - if (!firstMatched) { - firstMatched = setter; - } - } - } - return firstMatched; - } - - private useSetter = (name: string) => { - if (name === this.used) { - return; - } - const { field, onChange } = this.props; - const setter = this.setters.find((item) => item.name === name); - this.used = name; - if (setter) { - let newValue: any = setter.initialValue; - if (newValue && typeof newValue === 'function') { - newValue = newValue(field); - } - onChange && onChange(newValue); - } - }; - - private shell: HTMLDivElement | null = null; - private checkIsBlockField() { - if (this.shell) { - const setter = this.shell.firstElementChild; - if (setter && setter.classList.contains('lc-block-setter')) { - this.shell.classList.add('lc-block-setter'); - } else { - this.shell.classList.remove('lc-block-setter'); - } - } - } - componentDidUpdate() { - this.checkIsBlockField(); - } - componentDidMount() { - this.checkIsBlockField(); - } - - render() { - const { className, field, setters, onSetterChange, ...restProps } = this.props; - - const currentSetter = this.getCurrentSetter(); - const isTwoType = this.setters.length < 3; - - let setterContent: any; - const triggerTitle: any = { - tip: { - type: 'i18n', - 'zh-CN': '切换格式', - 'en-US': 'Switch Format', - }, - icon: <IconConvert size={24} />, - }; - if (currentSetter) { - const { setter, title, props } = currentSetter; - let setterProps: any = {}; - let setterType: any; - if (isDynamicSetter(setter)) { - setterType = setter.call(field, field); - } else { - setterType = setter; - } - if (props) { - setterProps = props; - if (typeof setterProps === 'function') { - setterProps = setterProps(field); - } - } - - setterContent = createSetterContent(setterType, { - ...shallowIntl(setterProps), - field, - ...restProps, - }); - if (title) { - if (typeof title !== 'object' || isI18nData(title) || isValidElement(title)) { - triggerTitle.tip = title; - } else { - triggerTitle.tip = title.tip || title.label; - } - } - } else { - // 未匹配的 null 值,显示 NullValue 空值 - // 未匹配的 其它 值,显示 InvalidValue 非法值 - if (restProps.value == null) { - setterContent = <span>NullValue</span>; - } else { - setterContent = <span>InvalidValue</span>; - } - } - const usedName = currentSetter?.name || this.used; - let moreBtnNode = ( - <Title - title={triggerTitle} - className="lc-switch-trigger" - onClick={ - isTwoType - ? () => { - if (this.setters[0]?.name === usedName) { - this.useSetter(this.setters[1]?.name); - } else { - this.useSetter(this.setters[0]?.name); - } - } - : undefined - } - /> - ); - if (!isTwoType) { - moreBtnNode = ( - <Dropdown trigger={moreBtnNode} triggerType="click" align="tr br"> - <Menu selectMode="single" hasSelectedIcon={true} selectedKeys={usedName} onItemClick={this.useSetter}> - {this.setters.filter(setter => setter.list || setter.name === usedName).map((setter) => { - return ( - <Menu.Item key={setter.name}> - <Title title={setter.title} /> - </Menu.Item> - ); - })} - </Menu> - </Dropdown> - ); - } - - return ( - <div ref={(shell) => (this.shell = shell)} className={classNames('lc-setter-mixed', className)}> - {setterContent} - - <div className="lc-setter-actions">{moreBtnNode}</div> - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less b/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less deleted file mode 100644 index 6efebb28c..000000000 --- a/packages/vision-polyfill/src/skeleton/components/mixed-setter/style.less +++ /dev/null @@ -1,30 +0,0 @@ -.lc-setter-mixed { - flex: 1; - min-width: 0; - margin-right: 26px; - display: block; - position: relative; - >.lc-setter-actions { - position: absolute; - right: -2px; - top: 50%; - transform: translate(100%, -50%); - .lc-switch-trigger { - cursor: pointer; - opacity: 0.6; - &:hover { - opacity: 1; - } - } - } - .next-input,.next-date-picker { - width: 100%; - } - &.lc-block-setter { - position: static; - margin-right: 0; - >.lc-setter-actions { - transform: none; - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx b/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx deleted file mode 100644 index 2f84c8adb..000000000 --- a/packages/vision-polyfill/src/skeleton/components/object-setter/index.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import { Component, Fragment } from 'react'; -import { Icon, Button } from '@alifd/next'; -import { Title, SetterType, FieldConfig } from '@ali/lowcode-globals'; -import { createSettingFieldView } from '../../settings/settings-pane'; -import { PopupContext, PopupPipe } from '../../popup'; -import { SettingField } from '@ali/lowcode-designer'; -import './style.less'; - -export default class ObjectSetter extends Component<{ - field: SettingField; - descriptor?: string | ((rowField: SettingField) => string); - config: ObjectSetterConfig; - mode?: 'popup' | 'form'; - // 1: in tablerow 2: in listrow 3: in column-cell - forceInline?: number; -}> { - render() { - const { mode, forceInline = 0, ...props } = this.props; - if (forceInline || mode === 'popup') { - if (forceInline > 2 || mode === 'popup') { - // popup - return <RowSetter {...props} primaryButton={forceInline ? false : true} />; - } else { - return <RowSetter columns={forceInline > 1 ? 2 : 4} {...props} />; - } - } else { - // form - return <FormSetter {...props} />; - } - } -} - -interface ObjectSetterConfig { - items?: FieldConfig[]; - extraSetter?: SetterType; -} - -interface RowSetterProps { - field: SettingField; - descriptor?: string | ((rowField: SettingField) => string); - config: ObjectSetterConfig; - columns?: number; - primaryButton?: boolean; -} - -class RowSetter extends Component<RowSetterProps> { - static contextType = PopupContext; - - state: any = { - descriptor: '', - }; - - private items?: SettingField[]; - constructor(props: RowSetterProps) { - super(props); - const { config, descriptor, field, columns } = props; - const items: SettingField[] = []; - if (columns && config.items) { - const l = Math.min(config.items.length, columns); - for (let i = 0; i < l; i++) { - const conf = config.items[i]; - if (conf.isRequired || conf.important || (conf.setter as any)?.isRequired) { - const item = field.createField({ - ...conf, - // in column-cell - forceInline: 3, - }); - items.push(item); - } - } - } - - if (items.length > 0) { - this.items = items; - } - - let firstRun: boolean = true; - field.onEffect(() => { - let state: any = {}; - if (descriptor) { - if (typeof descriptor === 'function') { - state.descriptor = descriptor(field); - } else { - state.descriptor = field.getPropValue(descriptor); - } - } else { - state.descriptor = field.title; - } - - if (firstRun) { - firstRun = false; - this.state = state; - } else { - this.setState(state); - } - }); - } - - shouldComponentUpdate(_: any, nextState: any) { - if (this.state.decriptor !== nextState.decriptor) { - return true; - } - return false; - } - - private pipe: any; - render() { - const items = this.items; - const { field, primaryButton, config } = this.props; - - if (!this.pipe) { - this.pipe = (this.context as PopupPipe).create({ width: 320 }); - } - - const title = ( - <Fragment> - 编辑: - <Title title={this.state.descriptor} /> - </Fragment> - ); - - this.pipe.send(<FormSetter key={field.id} field={field} config={config} />, title); - - if (items) { - return ( - <div className="lc-setter-object-row"> - <div - className="lc-setter-object-row-edit" - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon size="small" type="edit" /> - </div> - <div className="lc-setter-object-row-body">{items.map((item) => createSettingFieldView(item, field))}</div> - </div> - ); - } - - return ( - <Button - type={primaryButton === false ? 'normal' : 'primary'} - onClick={(e) => { - this.pipe.show((e as any).target, field.id); - }} - > - <Icon type="edit" /> - {title} - </Button> - ); - } -} - -interface FormSetterProps { - field: SettingField; - config: ObjectSetterConfig; -} -class FormSetter extends Component<FormSetterProps> { - private items: SettingField[]; - constructor(props: RowSetterProps) { - super(props); - const { config, field } = props; - this.items = (config.items || []).map((conf) => field.createField(conf)); - - // TODO: extraConfig for custom fields - } - - shouldComponentUpdate() { - return false; - } - - render() { - const { field } = this.props; - return ( - <div className="lc-setter-object lc-block-setter"> - {this.items.map((item, index) => createSettingFieldView(item, field, index))} - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/object-setter/style.less b/packages/vision-polyfill/src/skeleton/components/object-setter/style.less deleted file mode 100644 index 6d6064df1..000000000 --- a/packages/vision-polyfill/src/skeleton/components/object-setter/style.less +++ /dev/null @@ -1,31 +0,0 @@ -.lc-setter-object-row { - display: flex; - align-items: stretch; - width: 100%; - .lc-setter-object-row-edit { - width: 20px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - } - .lc-setter-object-row-body { - display: flex; - flex: 1; - min-width: 0; - align-items: center; - .lc-field { - padding: 0 !important; - .lc-field-body { - padding: 0 !important; margin: 0 !important; - } - } - > * { - flex: 1; - flex-shrink: 1; - margin-left: 2px; - min-width: 0; - overflow: hidden; - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/popup/index.tsx b/packages/vision-polyfill/src/skeleton/components/popup/index.tsx deleted file mode 100644 index 503e986f9..000000000 --- a/packages/vision-polyfill/src/skeleton/components/popup/index.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { createContext, ReactNode, Component, PureComponent } from 'react'; -import { EventEmitter } from 'events'; -import { Balloon } from '@alifd/next'; -import { uniqueId } from '@ali/lowcode-globals'; -import './style.less'; - -export const PopupContext = createContext<PopupPipe>({} as any); - -export class PopupPipe { - private emitter = new EventEmitter(); - private currentId?: string; - - create(props?: object): { send: (content: ReactNode, title: ReactNode) => void; show: (target: Element) => void } { - let sendContent: ReactNode = null; - let sendTitle: ReactNode = null; - const id = uniqueId('popup'); - return { - send: (content: ReactNode, title: ReactNode) => { - sendContent = content; - sendTitle = title; - if (this.currentId === id) { - this.popup({ - ...props, - content, - title, - }); - } - }, - show: (target: Element, actionKey?: string) => { - this.currentId = id; - this.popup( - { - ...props, - actionKey, - content: sendContent, - title: sendTitle, - }, - target, - ); - }, - }; - } - - private popup(props: object, target?: Element) { - Promise.resolve().then(() => { - this.emitter.emit('popupchange', props, target); - }); - } - - onPopupChange(fn: (props: object, target?: Element) => void): () => void { - this.emitter.on('popupchange', fn); - return () => { - this.emitter.removeListener('popupchange', fn); - }; - } - - purge() { - this.emitter.removeAllListeners(); - } -} - -export default class PopupService extends Component<{ actionKey?: string; safeId?: string }> { - private popupPipe = new PopupPipe(); - - componentWillUnmount() { - this.popupPipe.purge(); - } - - render() { - const { children, actionKey, safeId } = this.props; - return ( - <PopupContext.Provider value={this.popupPipe}> - {children} - <PopupContent key={'pop' + actionKey} safeId={safeId} /> - </PopupContext.Provider> - ); - } -} - -export class PopupContent extends PureComponent<{ safeId?: string }> { - static contextType = PopupContext; - state: any = { - visible: false, - pos: {}, - }; - - private dispose = (this.context as PopupPipe).onPopupChange((props, target) => { - const state: any = { - ...props, - visible: true, - }; - if (target) { - const rect = target.getBoundingClientRect(); - state.pos = { - top: rect.top, - height: rect.height, - }; - // todo: compute the align method - } - this.setState(state); - }); - - componentWillUnmount() { - this.dispose(); - } - - render() { - const { content, visible, width, title, pos, actionKey } = this.state; - if (!visible) { - return null; - } - let avoidLaterHidden = true; - setTimeout(() => { - avoidLaterHidden = false; - }, 10); - - const id = uniqueId('ball'); - - return ( - <Balloon - className="lc-ballon" - align="l" - id={this.props.safeId} - safeNode={id} - visible={visible} - style={{ width }} - onVisibleChange={(visible) => { - if (avoidLaterHidden) { - return; - } - if (!visible) { - this.setState({ visible: false }); - } - }} - trigger={<div className="lc-popup-placeholder" style={pos} />} - triggerType="click" - animation={false} - // needAdjust - shouldUpdatePosition - > - <div className="lc-ballon-title">{title}</div> - <div className="lc-ballon-content"> - <PopupService actionKey={actionKey} safeId={id}> - {content} - </PopupService> - </div> - </Balloon> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/popup/style.less b/packages/vision-polyfill/src/skeleton/components/popup/style.less deleted file mode 100644 index b115fd371..000000000 --- a/packages/vision-polyfill/src/skeleton/components/popup/style.less +++ /dev/null @@ -1,22 +0,0 @@ -.lc-popup-placeholder { - position: fixed; - width: 100%; - pointer-events: none; -} - -.lc-ballon { - padding: 10px; - max-width: 640px; - width: 640px; - .lc-ballon-title { - font-size: 14px; - } - .lc-ballon-content { - margin-top: 10px; - // width: 300px; - } - .next-balloon-close { - top: 4px; - right: 4px; - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/register.ts b/packages/vision-polyfill/src/skeleton/components/register.ts deleted file mode 100644 index 3c096aa82..000000000 --- a/packages/vision-polyfill/src/skeleton/components/register.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { registerSetter, isPlainObject } from '@ali/lowcode-globals'; -import ArraySetter from './array-setter'; -import ObjectSetter from './settings-pane/src/setters/object-setter'; -import MixedSetter from './mixed-setter'; - -registerSetter('ArraySetter', { - component: ArraySetter, - defaultProps: {}, - title: 'ArraySetter', // TODO - condition: (field: any) => { - const v = field.getValue(); - return v == null || Array.isArray(v); - }, - initialValue: [], - recommend: true, -}); -registerSetter('ObjectSetter', { - component: ObjectSetter, - // todo: defaultProps - defaultProps: {}, - title: 'ObjectSetter', // TODO - condition: (field: any) => { - const v = field.getValue(); - return v == null || isPlainObject(v); - }, - initialValue: {}, - recommend: true, -}); -registerSetter('MixedSetter', MixedSetter); diff --git a/packages/vision-polyfill/src/skeleton/components/settings/index.ts b/packages/vision-polyfill/src/skeleton/components/settings/index.ts deleted file mode 100644 index f51b7b704..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createSettingFieldView } from './settings-pane'; -import './transducers/register'; -import '../../register'; -import './style.less'; -import SettingsMainView from './settings-primary-view'; - -export default SettingsMainView; - -export { createSettingFieldView }; diff --git a/packages/vision-polyfill/src/skeleton/components/settings/main.ts b/packages/vision-polyfill/src/skeleton/components/settings/main.ts deleted file mode 100644 index f752add28..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/main.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { EventEmitter } from 'events'; -import { obx, computed } from '@ali/lowcode-globals'; -import { Node, Designer, Selection, SettingTopEntry } from '@ali/lowcode-designer'; -import { getTreeMaster } from '@ali/lowcode-plugin-outline-pane'; -import Editor from '@ali/lowcode-editor-core'; - -function generateSessionId(nodes: Node[]) { - return nodes - .map((node) => node.id) - .sort() - .join(','); -} - -export class SettingsMain { - private emitter = new EventEmitter(); - private _sessionId = ''; - @obx.ref private _settings?: SettingTopEntry; - - @computed get length(): number | undefined { - return this._settings?.nodes.length; - } - - @computed get componentMeta() { - return this._settings?.componentMeta; - } - - get settings() { - return this._settings; - } - - private disposeListener: () => void; - - private designer?: Designer; - - constructor(readonly editor: Editor) { - this.init(); - } - - private async init() { - const setupSelection = (selection?: Selection) => { - if (selection) { - this.setup(selection.getNodes()); - } else { - this.setup([]); - } - }; - this.editor.on('designer.selection.change', setupSelection); - this.disposeListener = () => { - this.editor.removeListener('designer.selection.change', setupSelection); - }; - const designer = await this.editor.onceGot(Designer); - this.designer = designer; - getTreeMaster(designer).onceEnableBuiltin(() => { - this.emitter.emit('outline-visible'); - }); - setupSelection(designer.currentSelection); - } - - private setup(nodes: Node[]) { - // check nodes change - const sessionId = generateSessionId(nodes); - if (sessionId === this._sessionId) { - return; - } - this._sessionId = sessionId; - if (nodes.length < 1) { - this._settings = undefined; - return; - } - - if (!this.designer) { - this.designer = nodes[0].document.designer; - } - - this._settings = this.designer.createSettingEntry(this.editor, nodes); - } - - onceOutlineVisible(fn: () => void): () => void { - this.emitter.on('outline-visible', fn); - return () => { - this.emitter.removeListener('outline-visible', fn); - }; - } - - purge() { - this.disposeListener(); - this.emitter.removeAllListeners(); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/package.json b/packages/vision-polyfill/src/skeleton/components/settings/package.json deleted file mode 100644 index 2a0fab24e..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@ali/lowcode-plugin-settings-pane", - "version": "0.8.10", - "description": "Settings pane for Ali lowCode engine", - "files": [ - "es", - "lib" - ], - "main": "lib/index.js", - "module": "es/index.js", - "scripts": { - "build": "build-scripts build --skip-demo", - "test": "ava", - "test:snapshot": "ava --update-snapshots" - }, - "dependencies": { - "@ali/lowcode-designer": "^0.9.2", - "@ali/lowcode-editor-core": "^0.8.5", - "@ali/lowcode-globals": "^0.9.2", - "@ali/lowcode-plugin-outline-pane": "^0.8.8", - "@ali/ve-stage-box": "^4.0.0", - "@alifd/next": "^1.19.16", - "classnames": "^2.2.6", - "react": "^16" - }, - "devDependencies": { - "@alib/build-scripts": "^0.1.18", - "@types/classnames": "^2.2.7", - "@types/node": "^13.7.1", - "@types/react": "^16", - "build-plugin-component": "^0.2.10", - "build-plugin-fusion": "^0.1.1", - "build-plugin-moment-locales": "^0.1.0" - }, - "ava": { - "compileEnhancements": false, - "snapshotDir": "test/fixtures/__snapshots__", - "extensions": [ - "ts" - ], - "require": [ - "ts-node/register" - ] - }, - "license": "MIT", - "publishConfig": { - "registry": "https://registry.npm.alibaba-inc.com" - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx b/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx deleted file mode 100644 index 11edc8a4c..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/settings-pane.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import { Component } from 'react'; -import { - createContent, - CustomView, - intl, - shallowIntl, - isSetterConfig, - createSetterContent, - observer, -} from '@ali/lowcode-globals'; -import { Field, createField } from '../field'; -import PopupService from '../popup'; -import { SettingField, isSettingField, SettingTopEntry, SettingEntry } from '@ali/lowcode-designer'; - -@observer -class SettingFieldView extends Component<{ field: SettingField }> { - render() { - const { field } = this.props; - const { extraProps } = field; - const { condition, defaultValue } = extraProps; - const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; - if (!visible) { - return null; - } - const { setter } = field; - - let setterProps: any = {}; - let setterType: any; - if (Array.isArray(setter)) { - setterType = 'MixedSetter'; - setterProps = { - setters: setter, - }; - } else if (isSetterConfig(setter)) { - setterType = setter.componentName; - if (setter.props) { - setterProps = setter.props; - if (typeof setterProps === 'function') { - setterProps = setterProps(field); - } - } - } else if (setter) { - setterType = setter; - } - let value = null; - if (field.type === 'field') { - if (defaultValue != null && !('defaultValue' in setterProps)) { - setterProps.defaultValue = defaultValue; - } - if (field.valueState > 0) { - value = field.getValue(); - } else { - setterProps.multiValue = true; - if (!('placeholder' in setterProps)) { - // FIXME! move to locale file - setterProps.placeholder = intl({ - type: 'i18n', - 'zh-CN': '多种值', - 'en-US': 'Multiple Value', - }); - } - } - } - - // todo: error handling - - return createField({ - title: field.title, - collapsed: !field.expanded, - onExpandChange: (expandState) => field.setExpanded(expandState), - }, createSetterContent(setterType, { - ...shallowIntl(setterProps), - forceInline: extraProps.forceInline, - key: field.id, - // === injection - prop: field, // for compatible vision - field, - // === IO - value, // reaction point - onChange: (value: any) => { - this.setState({ - value, - }); - field.setValue(value); - }, - }), extraProps.forceInline ? 'plain' : extraProps.display); - } -} - -@observer -class SettingGroupView extends Component<{ field: SettingField }> { - shouldComponentUpdate() { - return false; - } - - render() { - const { field } = this.props; - const { extraProps } = field; - const { condition } = extraProps; - const visible = field.isSingle && typeof condition === 'function' ? condition(field) !== false : true; - - if (!visible) { - return null; - } - - // todo: split collapsed state | field.items for optimize - return ( - <Field defaultDisplay="accordion" title={field.title} collapsed={!field.expanded} onExpandChange={(expandState) => { - field.setExpanded(expandState); - }}> - {field.items.map((item, index) => createSettingFieldView(item, field, index))} - </Field> - ); - } -} - -export function createSettingFieldView(item: SettingField | CustomView, field: SettingEntry, index?: number) { - if (isSettingField(item)) { - if (item.isGroup) { - return <SettingGroupView field={item} key={item.id} />; - } else { - return <SettingFieldView field={item} key={item.id} />; - } - } else { - return createContent(item, { key: index, field }); - } -} - -@observer -export default class SettingsPane extends Component<{ target: SettingTopEntry | SettingField }> { - shouldComponentUpdate() { - return false; - } - - render() { - const { target } = this.props; - const items = target.items - return ( - <div className="lc-settings-pane"> - {/* todo: add head for single use */} - <PopupService> - <div className="lc-settings-content"> - {items.map((item, index) => createSettingFieldView(item, target, index))} - </div> - </PopupService> - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx b/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx deleted file mode 100644 index caf45bc22..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/settings-primary-view.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import React, { Component, PureComponent } from 'react'; -import { Tab, Breadcrumb } from '@alifd/next'; -import { Title, createIcon, observer } from '@ali/lowcode-globals'; -import { Node, isSettingField, SettingField } from '@ali/lowcode-designer'; -import Editor from '@ali/lowcode-editor-core'; -import { SettingsMain } from './main'; -import SettingsPane from './settings-pane'; - -@observer -export default class SettingsMainView extends Component<{ editor: Editor }> { - private main = new SettingsMain(this.props.editor); - - shouldComponentUpdate() { - return false; - } - - componentWillUnmount() { - this.main.purge(); - } - - renderBreadcrumb() { - const { settings } = this.main; - if (!settings) { - return null; - } - if (settings.isMultiple) { - return ( - <div className="lc-settings-navigator"> - {createIcon(settings.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} - <Title title={settings.componentMeta!.title} /> - <span>x {settings.nodes.length}</span> - </div> - ); - } - - let node: Node | null = settings.first; - const items = []; - let l = 3; - while (l-- > 0 && node) { - const props = - l === 2 - ? {} - : { - onMouseOver: hoverNode.bind(null, node, true), - onMouseOut: hoverNode.bind(null, node, false), - onClick: selectNode.bind(null, node), - }; - items.unshift(<Breadcrumb.Item {...props} key={node.id}><Title title={node.title} /></Breadcrumb.Item>); - node = node.parent; - } - - return ( - <div className="lc-settings-navigator"> - {createIcon(this.main.componentMeta?.icon, { className: 'lc-settings-navigator-icon'})} - <Breadcrumb className="lc-settings-node-breadcrumb">{items}</Breadcrumb> - </div> - ); - } - - render() { - const { settings } = this.main; - if (!settings) { - // 未选中节点,提示选中 或者 显示根节点设置 - return ( - <div className="lc-settings-main"> - <div className="lc-settings-notice"> - <p>请在左侧画布选中节点</p> - </div> - </div> - ); - } - - if (!settings.isSameComponent) { - // todo: future support 获取设置项交集编辑 - return ( - <div className="lc-settings-main"> - <div className="lc-settings-notice"> - <p>请选中同一类型节点编辑</p> - </div> - </div> - ); - } - - const { items } = settings; - if (items.length > 5 || items.some(item => !isSettingField(item) || !item.isGroup)) { - return ( - <div className="lc-settings-main"> - {this.renderBreadcrumb()} - <div className="lc-settings-body"> - <SettingsPane target={settings} /> - </div> - </div> - ); - } - - return ( - <div className="lc-settings-main"> - <Tab - navClassName="lc-settings-tabs" - animation={false} - excessMode="dropdown" - contentClassName="lc-settings-tabs-content" - extra={this.renderBreadcrumb()} - > - {(items as SettingField[]).map(field => ( - <Tab.Item className="lc-settings-tab-item" title={<Title title={field.title} />} key={field.name}> - <SettingsPane target={field} key={field.id} /> - </Tab.Item> - ))} - </Tab> - </div> - ); - } -} - -function hoverNode(node: Node, flag: boolean) { - node.hover(flag); -} -function selectNode(node: Node) { - node.select(); -} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/style.less b/packages/vision-polyfill/src/skeleton/components/settings/style.less deleted file mode 100644 index 9b2c2b403..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/style.less +++ /dev/null @@ -1,124 +0,0 @@ -.lc-settings-main { - position: relative; - height: 100%; - overflow: hidden; - - .lc-settings-notice { - text-align: center; - font-size: 12px; - font-family: PingFang SC,Hiragino Sans GB,Microsoft YaHei,Helvetica,Arial,sans-serif; - color: var(--color-text ,rgba(0,0,0,.6)); - padding: 50px 15px 0; - } - - .lc-settings-navigator { - height: 30px; - display: flex; - align-items: center; - padding-left: 5px; - border-bottom: 1px solid var(--color-line-normal); - .lc-settings-navigator-icon { - width: 16px; - height: 16px; - * { - fill: var(--color-icon-normal, rgba(31, 56, 88, 0.4)); - } - } - .lc-settings-node-breadcrumb { - margin-left: 5px; - .next-breadcrumb { - display: inline-flex; - align-items: stretch; - height: 24px; - } - .next-breadcrumb-item { - display: inline-flex; - align-items: center; - cursor: default; - &:not(:last-child):hover { - cursor: pointer; - } - .next-breadcrumb-text { - font-size: 12px; - } - } - } - } - - .lc-settings-body { - position: absolute; - top: 30px; - right: 0; - left: 0; - bottom: 0; - overflow-y: auto; - } - - // ====== reset fusion-tabs ===== - .lc-settings-tabs { - position: relative; - overflow: visible; - > .next-tabs-nav-extra { - position: absolute !important; - top: 40px !important; - left: 0 !important; - height: 30px; - right: 0; - transform: none !important; - - } - .next-tabs-nav-container { - .next-tabs-nav { - display: flex; - .next-tabs-tab.lc-settings-tab-item { - flex: 1; - min-width: 0; - outline: none; - .next-tabs-tab-inner { - text-align: center; - padding: 12px 0; - } - } - } - } - } - - .lc-settings-tabs-content { - position: absolute; - top: 70px; - left:0; - right: 0; - bottom: 0; - .next-tabs-tabpane { - position: absolute; - top: 0; - right: 0; - left: 0; - bottom: 0; - overflow-y: auto; - outline: none !important; - box-shadow: none !important; - } - } - .lc-outline-pane { - position: absolute; - z-index: 100; - background-color: white; - top: 0; - bottom: 0; - display: none; - } -} - -.lc-settings-pane { - padding-bottom: 50px; - .next-btn { - line-height: 1 !important; - } -} - -html.lc-cursor-dragging:not(.lowcode-has-fixed-tree) { - .lc-settings-main .lc-outline-pane { - display: block; - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/settings/utils.js b/packages/vision-polyfill/src/skeleton/components/settings/utils.js deleted file mode 100644 index b8f5bbdcc..000000000 --- a/packages/vision-polyfill/src/skeleton/components/settings/utils.js +++ /dev/null @@ -1,41 +0,0 @@ -function getHotterFromSetter(setter) { - return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line -} - -function getTransducerFromSetter(setter) { - return setter && ( - setter.transducer || setter.Transducer - || (setter.type && (setter.type.transducer || setter.type.Transducer)) - ) || null; // eslint-disable-line -} - -function combineTransducer(transducer, arr, context) { - if (!transducer && Array.isArray(arr)) { - const [toHot, toNative] = arr; - transducer = { toHot, toNative }; - } - - return { - toHot: (transducer && transducer.toHot || (x => x)).bind(context), // eslint-disable-line - toNative: (transducer && transducer.toNative || (x => x)).bind(context), // eslint-disable-line - }; -} - -export class Transducer { - constructor(context, config) { - this.setterTransducer = combineTransducer( - getTransducerFromSetter(config.setter), - getHotterFromSetter(config.setter), - context, - ); - this.context = context; - } - - toHot(data) { - return this.setterTransducer.toHot(data); - } - - toNative(data) { - return this.setterTransducer.toNative(data); - } -} diff --git a/packages/vision-polyfill/src/skeleton/components/widget-views.tsx b/packages/vision-polyfill/src/skeleton/components/widget-views.tsx deleted file mode 100644 index 6d32600b1..000000000 --- a/packages/vision-polyfill/src/skeleton/components/widget-views.tsx +++ /dev/null @@ -1,236 +0,0 @@ -import { Component, ReactElement } from 'react'; -import classNames from 'classnames'; -import { Title, observer } from '@ali/lowcode-globals'; -import { DockProps } from '../types'; -import PanelDock from '../widget/panel-dock'; -import { composeTitle } from '../widget/utils'; -import WidgetContainer from '../widget/widget-container'; -import Panel from '../widget/panel'; -import { IWidget } from '../widget/widget'; -import { SkeletonEvents } from '../skeleton'; - -export function DockView({ title, icon, description, size, className, onClick }: DockProps) { - return ( - <Title - title={composeTitle(title, icon, description)} - className={classNames('lc-dock', className, { - [`lc-dock-${size}`]: size, - })} - onClick={onClick} - /> - ); -} - -@observer -export class PanelDockView extends Component<DockProps & { dock: PanelDock }> { - componentDidMount() { - this.checkActived(); - } - componentDidUpdate() { - this.checkActived(); - } - private lastActived: boolean = false; - checkActived() { - const { dock } = this.props; - if (dock.actived !== this.lastActived) { - this.lastActived = dock.actived; - if (this.lastActived) { - dock.skeleton.postEvent(SkeletonEvents.PANEL_DOCK_ACTIVE, dock.name, dock); - } else { - dock.skeleton.postEvent(SkeletonEvents.PANEL_DOCK_UNACTIVE, dock.name, dock); - } - } - } - - render() { - const { dock, className, onClick, ...props } = this.props; - return DockView({ - ...props, - className: classNames(className, { - actived: dock.actived, - }), - onClick: () => { - onClick && onClick(); - dock.togglePanel(); - }, - }); - } -} - -export class DialogDockView extends Component { - -} - -@observer -export class TitledPanelView extends Component<{ panel: Panel }> { - shouldComponentUpdate() { - return false; - } - componentDidMount() { - this.checkVisible(); - } - componentDidUpdate() { - this.checkVisible(); - } - private lastVisible: boolean = false; - checkVisible() { - const { panel } = this.props; - const currentVisible = panel.inited && panel.visible; - if (currentVisible !== this.lastVisible) { - this.lastVisible = currentVisible; - if (this.lastVisible) { - panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); - } else { - panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); - } - } - } - render() { - const { panel } = this.props; - if (!panel.inited) { - return null; - } - return ( - <div className={classNames('lc-titled-panel', { - hidden: !panel.visible, - })}> - <PanelTitle panel={panel} /> - <div className="lc-pane-body">{panel.body}</div> - </div> - ); - } -} - -@observer -export class PanelView extends Component<{ panel: Panel }> { - shouldComponentUpdate() { - return false; - } - componentDidMount() { - this.checkVisible(); - } - componentDidUpdate() { - this.checkVisible(); - } - private lastVisible: boolean = false; - checkVisible() { - const { panel } = this.props; - const currentVisible = panel.inited && panel.visible; - if (currentVisible !== this.lastVisible) { - this.lastVisible = currentVisible; - if (this.lastVisible) { - panel.skeleton.postEvent(SkeletonEvents.PANEL_SHOW, panel.name, panel); - // FIXME! remove this line - panel.skeleton.postEvent('leftPanel.show' as any, panel.name, panel); - } else { - panel.skeleton.postEvent(SkeletonEvents.PANEL_HIDE, panel.name, panel); - // FIXME! remove this line - panel.skeleton.postEvent('leftPanel.hide' as any, panel.name, panel); - } - } - } - render() { - const { panel } = this.props; - if (!panel.inited) { - return null; - } - return ( - <div - className={classNames('lc-panel', { - hidden: !panel.visible, - })} - > - {panel.body} - </div> - ); - } -} - -@observer -export class TabsPanelView extends Component<{ container: WidgetContainer<Panel> }> { - render() { - const { container } = this.props; - const titles: ReactElement[] = []; - const contents: ReactElement[] = []; - container.items.forEach((item: any) => { - titles.push(<PanelTitle key={item.id} panel={item} className="lc-tab-title" />); - contents.push(<PanelView key={item.id} panel={item} />); - }); - - return ( - <div className="lc-tabs"> - <div - className="lc-tabs-title" - onClick={(e) => { - const shell = e.currentTarget; - const t = e.target as Element; - let elt = shell.firstElementChild; - while (elt) { - if (elt.contains(t)) { - break; - } - elt = elt.nextElementSibling; - } - if (elt) { - container.active((elt as any).dataset.name); - } - }} - > - {titles} - </div> - <div className="lc-tabs-content">{contents}</div> - </div> - ); - } -} - -@observer -class PanelTitle extends Component<{ panel: Panel; className?: string }> { - render() { - const { panel, className } = this.props; - return ( - <div - className={classNames('lc-panel-title', className, { - actived: panel.actived, - })} - data-name={panel.name} - > - <Title title={panel.title || panel.name} /> - {/*pane.help ? <HelpTip tip={panel.help} /> : null*/} - </div> - ); - } -} - -@observer -export class WidgetView extends Component<{ widget: IWidget }> { - shouldComponentUpdate() { - return false; - } - componentDidMount() { - this.checkVisible(); - } - componentDidUpdate() { - this.checkVisible(); - } - private lastVisible: boolean = false; - checkVisible() { - const { widget } = this.props; - const currentVisible = widget.visible; - if (currentVisible !== this.lastVisible) { - this.lastVisible = currentVisible; - if (this.lastVisible) { - widget.skeleton.postEvent(SkeletonEvents.WIDGET_SHOW, widget.name, widget); - } else { - widget.skeleton.postEvent(SkeletonEvents.WIDGET_SHOW, widget.name, widget); - } - } - } - render() { - const { widget } = this.props; - if (!widget.visible) { - return null; - } - return widget.body; - } -} diff --git a/packages/vision-polyfill/src/skeleton/dock.ts b/packages/vision-polyfill/src/skeleton/dock.ts deleted file mode 100644 index 721c6b9c6..000000000 --- a/packages/vision-polyfill/src/skeleton/dock.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { uniqueId, createContent, obx } from '@ali/lowcode-globals'; -import { DockConfig } from "./types"; -import { Skeleton } from './skeleton'; -import { DockView, WidgetView } from './components/widget-views'; -import { IWidget } from './widget/widget'; - -/** - * 带图标(主要)/标题(次要)的扩展 - */ -export default class Dock implements IWidget { - readonly isWidget = true; - readonly id = uniqueId('dock'); - readonly name: string; - readonly align?: string; - - @obx.ref private _visible: boolean = true; - get visible(): boolean { - return this._visible; - } - - get content(): ReactNode { - return createElement(WidgetView, { - widget: this, - key: this.id, - }); - } - - private inited: boolean = false; - private _body: ReactNode; - get body() { - if (this.inited) { - return this._body; - } - - const { props, content, contentProps } = this.config; - - if (content) { - this._body = createContent(content, { - ...contentProps, - config: this.config, - editor: this.skeleton.editor, - }); - } else { - this._body = createElement(DockView, props); - } - return this._body; - } - - constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { - const { props = {}, name } = config; - this.name = name; - this.align = props.align; - } - - setVisible(flag: boolean) { - if (flag === this._visible) { - return; - } - if (flag) { - this._visible = true; - } else if (this.inited) { - this._visible = false; - } - } - - getContent() { - return this.content; - } - - getName() { - return this.name; - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } - - toggle() { - this.setVisible(!this._visible); - } -} diff --git a/packages/vision-polyfill/src/skeleton/icons/convert.tsx b/packages/vision-polyfill/src/skeleton/icons/convert.tsx deleted file mode 100644 index 71ab8630e..000000000 --- a/packages/vision-polyfill/src/skeleton/icons/convert.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { SVGIcon, IconProps } from "@ali/lowcode-globals"; - -export function IconConvert(props: IconProps) { - return ( - <SVGIcon viewBox="0 0 1024 1024" {...props}> - <path d="M508.16 889.6C291.84 889.6 115.2 714.24 115.2 497.92 115.2 281.6 291.84 106.24 509.44 106.24c43.52 0 85.76 6.4 124.16 20.48l-10.24 30.72c-35.84-11.52-72.96-17.92-113.92-17.92-199.68 0-362.24 161.28-362.24 359.68s162.56 358.4 360.96 358.4 359.68-161.28 359.68-359.68c0-66.56-17.92-131.84-51.2-185.6L844.8 294.4c37.12 60.16 56.32 130.56 56.32 203.52-1.28 216.32-176.64 391.68-392.96 391.68z" /> - <path d="M627.2 140.8m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> - <path d="M832 304.64m-15.36 0a15.36 15.36 0 1 0 30.72 0 15.36 15.36 0 1 0-30.72 0Z" /> - <path d="M348.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - <path d="M508.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - <path d="M668.16 497.92m-35.84 0a35.84 35.84 0 1 0 71.68 0 35.84 35.84 0 1 0-71.68 0Z" fill="#35A2D4" /> - </SVGIcon> - ); -} - -IconConvert.displayName = 'Convert'; diff --git a/packages/vision-polyfill/src/skeleton/index.ts b/packages/vision-polyfill/src/skeleton/index.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx deleted file mode 100644 index ae251cd2e..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/bottom-area.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; -import Panel from '../widget/panel'; - -@observer -export default class BottomArea extends Component<{ area: Area<any, Panel> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div className={classNames('lc-bottom-area', { - 'lc-area-visible': area.visible, - })}> - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((item) => item.content)} - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/left-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-area.tsx deleted file mode 100644 index 8fe785055..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/left-area.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; - -@observer -export default class LeftArea extends Component<{ area: Area }> { - render() { - const { area } = this.props; - return ( - <div className={classNames("lc-left-area", { - 'lc-area-visible': area.visible - })}> - <Contents area={area} /> - </div> - ); - } -} - - -@observer -class Contents extends Component<{ area: Area }> { - render() { - const { area } = this.props; - const top: any[] = []; - const bottom: any[] = []; - area.container.items.forEach(item => { - if (item.align === 'bottom') { - bottom.push(item.content); - } else { - top.push(item.content); - } - }); - return ( - <Fragment> - <div className="lc-left-area-top">{top}</div> - <div className="lc-left-area-bottom">{bottom}</div> - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx deleted file mode 100644 index bae3a9eae..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/left-fixed-pane.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import { Button, Icon } from '@alifd/next'; -import Area from '../area'; -import { PanelConfig } from '../types'; -import Panel from '../widget/panel'; - -@observer -export default class LeftFixedPane extends Component<{ area: Area<PanelConfig, Panel> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - return ( - <div - className={classNames('lc-left-fixed-pane', { - 'lc-area-visible': area.visible, - })} - > - <Button - text - className="lc-pane-close" - onClick={() => { - area.setVisible(false); - }} - > - <Icon type="close" /> - </Button> - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<PanelConfig, Panel> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((panel) => panel.content)} - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx b/packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx deleted file mode 100644 index fefe6d525..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/left-float-pane.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import { Button, Icon } from '@alifd/next'; -import Area from '../area'; -import Panel from '../widget/panel'; - -@observer -export default class LeftFloatPane extends Component<{ area: Area<any, Panel> }> { - shouldComponentUpdate() { - return false; - } - - private dispose?: () => void; - componentDidMount() { - const { area } = this.props; - const triggerClose = () => area.setVisible(false); - area.skeleton.editor.on('designer.dragstart', triggerClose); - this.dispose = () => { - area.skeleton.editor.removeListener('designer.dragstart', triggerClose); - } - } - - componentWillUnmount() { - this.dispose?.(); - } - - render() { - const { area } = this.props; - // TODO: add focusingManager - // focusin set focus (push|replace) - // focusout remove focus - // onEsc - const width = area.current?.config.props?.width; - const style = width ? { - width - } : undefined; - return ( - <div - className={classNames('lc-left-float-pane', { - 'lc-area-visible': area.visible, - })} - style={style} - > - <Button - text - className="lc-pane-close" - onClick={() => { - area.setVisible(false); - }} - > - <Icon type="close" /> - </Button> - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((panel) => panel.content)} - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/main-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/main-area.tsx deleted file mode 100644 index a531398b0..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/main-area.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Component } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; -import Panel from '../widget/panel'; -import Widget from '../widget/widget'; - -@observer -export default class MainArea extends Component<{ area: Area<any, Panel | Widget> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - return ( - <div className={classNames('lc-main-area')}> - {area.container.items.map((item) => item.content)} - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/right-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/right-area.tsx deleted file mode 100644 index b27223f1f..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/right-area.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; -import Panel from '../widget/panel'; - -@observer -export default class RightArea extends Component<{ area: Area<any, Panel> }> { - shouldComponentUpdate() { - return false; - } - render() { - const { area } = this.props; - return ( - <div className={classNames('lc-right-area', { - 'lc-area-visible': area.visible, - })}> - <Contents area={area} /> - </div> - ); - } -} - - -@observer -class Contents extends Component<{ area: Area<any, Panel> }> { - render() { - const { area } = this.props; - return ( - <Fragment> - {area.container.items.map((item) => item.content)} - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/theme.less b/packages/vision-polyfill/src/skeleton/layouts/theme.less deleted file mode 100644 index 5171884c0..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/theme.less +++ /dev/null @@ -1,60 +0,0 @@ -@import '~@ali/ve-less-variables/index.less'; - -/* - * Theme Colors - * - * 乐高设计器的主要主题色变量 - */ -:root { - --color-brand: @brand-color-1; - --color-brand-light: @brand-color-2; - --color-brand-dark: @brand-color-3; - - --color-canvas-background: @normal-alpha-8; - - --color-icon-normal: @normal-alpha-4; - --color-icon-hover: @normal-alpha-3; - --color-icon-active: @brand-color-1; - --color-icon-reverse: @white-alpha-1; - - --color-line-normal: @normal-alpha-7; - --color-line-darken: darken(@normal-alpha-7, 10%); - - --color-title: @dark-alpha-2; - --color-text: @dark-alpha-3; - --color-text-dark: darken(@dark-alpha-3, 10%); - --color-text-light: lighten(@dark-alpha-3, 10%); - --color-text-reverse: @white-alpha-2; - --color-text-regular: @normal-alpha-2; - - --color-field-label: @dark-alpha-4; - --color-field-text: @dark-alpha-3; - --color-field-placeholder: @normal-alpha-5; - --color-field-border: @normal-alpha-5; - --color-field-border-hover: @normal-alpha-4; - --color-field-border-active: @normal-alpha-3; - --color-field-background: @white-alpha-1; - - --color-function-success: @brand-success; - --color-function-success-dark: darken(@brand-success, 10%); - --color-function-success-light: lighten(@brand-success, 10%); - --color-function-warning: @brand-warning; - --color-function-warning-dark: darken(@brand-warning, 10%); - --color-function-warning-light: lighten(@brand-warning, 10%); - --color-function-information: @brand-link-hover; - --color-function-information-dark: darken(@brand-link-hover, 10%); - --color-function-information-light: lighten(@brand-link-hover, 10%); - --color-function-error: @brand-danger; - --color-function-error-dark: darken(@brand-danger, 10%); - --color-function-error-light: lighten(@brand-danger, 10%); - - --color-pane-background: @white-alpha-1; - --color-block-background-normal: @white-alpha-1; - --color-block-background-light: @normal-alpha-9; - --color-block-background-shallow: @normal-alpha-8; - --color-block-background-dark: @normal-alpha-7; - --color-block-background-disabled: @normal-alpha-6; - --color-block-background-deep-dark: @normal-5; - --color-layer-mask-background: @dark-alpha-7; - --color-layer-tooltip-background: rgba(44,47,51,0.8); -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx b/packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx deleted file mode 100644 index ea9c02ef0..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/toolbar.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; - -@observer -export default class Toolbar extends Component<{ area: Area }> { - render() { - const { area } = this.props; - if (area.isEmpty()) { - return null; - } - return ( - <div - className={classNames('lc-toolbar', { - 'lc-area-visible': area.visible, - })} - > - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area }> { - render() { - const { area } = this.props; - const left: any[] = []; - const center: any[] = []; - const right: any[] = []; - area.container.items.forEach((item) => { - if (item.align === 'center') { - center.push(item.content); - } else if (item.align === 'right') { - right.push(item.content); - } else { - left.push(item.content); - } - }); - return ( - <Fragment> - <div className="lc-toolbar-left">{left}</div> - <div className="lc-toolbar-center">{center}</div> - <div className="lc-toolbar-right">{right}</div> - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/top-area.tsx b/packages/vision-polyfill/src/skeleton/layouts/top-area.tsx deleted file mode 100644 index 13da4d17e..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/top-area.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Component, Fragment } from 'react'; -import classNames from 'classnames'; -import { observer } from '@ali/lowcode-globals'; -import Area from '../area'; - -@observer -export default class TopArea extends Component<{ area: Area }> { - render() { - const { area } = this.props; - return ( - <div className={classNames("lc-top-area", { - 'lc-area-visible': area.visible - })}> - <Contents area={area} /> - </div> - ); - } -} - -@observer -class Contents extends Component<{ area: Area }> { - render() { - const { area } = this.props; - const left: any[] = []; - const center: any[] = []; - const right: any[] = []; - area.container.items.forEach(item => { - if (item.align === 'center') { - center.push(item.content); - } else if (item.align === 'left') { - left.push(item.content); - } else { - right.push(item.content); - } - }); - return ( - <Fragment> - <div className="lc-top-area-left">{left}</div> - <div className="lc-top-area-center">{center}</div> - <div className="lc-top-area-right">{right}</div> - </Fragment> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/workbench.less b/packages/vision-polyfill/src/skeleton/layouts/workbench.less deleted file mode 100644 index 92deeeacd..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/workbench.less +++ /dev/null @@ -1,375 +0,0 @@ -@import "./theme.less"; - -:root { - --font-family: @font-family; - --font-size-label: @fontSize-4; - --font-size-text: @fontSize-5; - --font-size-btn-large: @fontSize-3; - --font-size-btn-medium: @fontSize-4; - --font-size-btn-small: @fontSize-5; - - --global-border-radius: @global-border-radius; - --input-border-radius: @input-border-radius; - --popup-border-radius: @popup-border-radius; - - --left-area-width: 48px; - --right-area-width: 280px; - --top-area-height: 48px; - --toolbar-height: 36px; - --dock-pane-width: 280px; - --dock-fixed-pane-width: 280px; -} - -@media (min-width: 1860px) { - :root { - --right-area-width: 400px; - --dock-pane-width: 452px; - --dock-fixed-pane-width: 350px; - } -} - -html, -body { - height: 100%; - overflow: hidden; - padding: 0; - margin: 0; - position: relative; - font-family: var(--font-family); - font-size: var(--font-size-text); - color: var(--color-text); - background-color:#EDEFF3; -} - -* { - box-sizing: border-box; -} - - -.lc-titled-panel { - width: 100%; - height: 100%; - position: relative; - .pane-title { - // height: var(--pane-title-height); - background-color: var(--pane-title-bg-color); - display: flex; - align-items: center; - padding: 0 15px; - .my-help-tip { - margin-left: 4px; - } - } - - .pane-body { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - overflow: auto; - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } - } - - &.titled > .pane-body { - top: var(--pane-title-height); - } -} -.lc-panel { - height: 100%; - width: 100%; - overflow: auto; - &.hidden { - display: none; - } - .pane-title { - height: var(--pane-title-height); - background-color: var(--pane-title-bg-color); - display: flex; - align-items: center; - padding: 0 15px; - .my-help-tip { - margin-left: 4px; - } - } - .my-tabs { - width: 100%; - height: 100%; - position: relative; - .tabs-title { - display: flex; - height: var(--pane-title-height); - margin-right: 30px; - > .tab-title { - cursor: pointer; - padding: 0; - flex: 1; - min-width: 0; - justify-content: center; - border-bottom: 2px solid transparent; - &.actived { - cursor: default; - color: var(--color-text-avtived); - border-bottom-color: #3896ee; - } - } - } - .tabs-content { - position: absolute; - top: var(--pane-title-height); - bottom: 0; - left: 0; - right: 0; - height: calc(100% - var(--pane-title-height)); - overflow: hidden; - } - } -} - -.my-dock { - padding: 0px 10px; - cursor: pointer; - align-self: stretch; - display: flex; - align-items: center; - .my-title-label { - user-select: none; - } - &.actived, &:hover { - background-color: var(--pane-title-bg-color); - .my-title { - color: var(--color-actived); - } - } -} - - -.lc-workbench { - height: 100%; - display: flex; - flex-direction: column; - background-color: #EDEFF3; - .lc-top-area { - height: var(--top-area-height); - background-color: var(--color-pane-background); - width: 100%; - display: flex; - margin-bottom: 2px; - padding: 8px; - .lc-top-area-left{} - .lc-top-area-center{ - flex: 1; - display: flex; - justify-content: flex-end; - margin-right: 8px; - } - .lc-top-area-right{ - display: flex; - align-items: center; - >* { - margin-left: 4px; - margin-right: 4px; - } - } - } - .lc-workbench-body { - flex: 1; - display: flex; - min-height: 0; - position: relative; - .lc-left-float-pane { - position: absolute; - top: 0; - bottom: 0; - width: var(--dock-pane-width); - left: calc(var(--left-area-width) + 1px); - background-color: var(--color-pane-background); - box-shadow: 4px 0 16px 0 rgba(31,50,88,0.08); - z-index: 820; - display: none; - // padding-top: 36px; - &.lc-area-visible { - display: block; - } - .lc-pane-close{ - position: absolute; - right: 10px; - top: 6px; - z-index: 2; - .next-icon{ - line-height: 1; - } - } - .lc-tabs-title { - width: 100%; - height: 36px; - position: relative; - display: center; - display: flex; - justify-content: center; - align-items: center; - background: rgba(31,56,88,0.04); - } - .lc-tabs-content { - position: absolute; - top: 36px; - bottom: 0; - left: 0; - right: 0; - } - } - .lc-left-area { - height: 100%; - width: var(--left-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - flex-direction: column; - justify-content: space-between; - &.lc-area-visible { - display: flex; - } - .lc-left-area-top, - .lc-left-area-bottom{ - width: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - .lc-title{ - padding: 12px; - flex-direction: column; - &.has-tip{ - cursor: pointer; - } - &.actived{ - color: #0079F2; - } - .lc-title-icon{ - margin: 0; - .next-icon:before { - line-height: 1 !important; - } - } - } - } - .lc-left-area-top{ - padding-top: 12px; - } - .lc-left-area-bottom{ - padding-bottom: 12px; - } - } - .lc-left-fixed-pane { - width: var(--dock-fixed-pane-width); - background-color: var(--color-pane-background); - height: 100%; - display: none; - flex-shrink: 0; - position: relative; - &.lc-area-visible { - display: block; - } - .lc-pane-close { - position: absolute; - right: 10px; - top: 6px; - z-index: 2; - .next-icon { - line-height: 1; - } - } - } - .lc-left-area.lc-area-visible ~ .lc-left-fixed-pane { - margin-left: 1px; - } - .lc-left-area.lc-area-visible ~ .lc-workbench-center { - margin-left: 2px; - } - .lc-outline-pane{ - .lc-outline-tree .tree-node .tree-node-title{ - border-bottom: none; - } - } - .lc-workbench-center { - flex: 1; - display: flex; - flex-direction: column; - .lc-toolbar { - height: var(--toolbar-height); - background-color: var(--color-pane-background); - padding: 8px 16px; - } - .lc-main-area { - flex: 1; - } - .lc-bottom-area { - height: var(--bottom-area-height); - background-color: var(--color-pane-background); - display: none; - &.lc-area-visible { - display: block; - } - } - } - .lc-right-area { - height: 100%; - width: var(--right-area-width); - background-color: var(--color-pane-background); - display: none; - flex-shrink: 0; - margin-left: 2px; - &.lc-area-visible { - display: block; - } - .lc-settings-tabs{ - > .next-tabs-nav-extra{ - top: 36px !important; - } - .lc-settings-tab-item{ - .next-tabs-tab-inner{ - font-size: 12px; - line-height: 12px; - } - } - .lc-title{ - color: inherit; - line-height: inherit !important; - } - } - .lc-settings-tabs-content{ - top: 66px; - } - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/layouts/workbench.tsx b/packages/vision-polyfill/src/skeleton/layouts/workbench.tsx deleted file mode 100644 index c55633f39..000000000 --- a/packages/vision-polyfill/src/skeleton/layouts/workbench.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Component } from 'react'; -import { TipContainer, observer } from '@ali/lowcode-globals'; -import { Skeleton } from '../skeleton'; -import TopArea from './top-area'; -import LeftArea from './left-area'; -import LeftFixedPane from './left-fixed-pane'; -import LeftFloatPane from './left-float-pane'; -import Toolbar from './toolbar'; -import MainArea from './main-area'; -import BottomArea from './bottom-area'; -import RightArea from './right-area'; -import './workbench.less'; - -@observer -export class VisionWorkbench extends Component<{ skeleton: Skeleton}> { - shouldComponentUpdate() { - return false; - } - - render() { - const { skeleton } = this.props; - return ( - <div className="lc-workbench"> - <TopArea area={skeleton.topArea} /> - <div className="lc-workbench-body"> - <LeftArea area={skeleton.leftArea} /> - <LeftFloatPane area={skeleton.leftFloatArea} /> - <LeftFixedPane area={skeleton.leftFixedArea} /> - <div className="lc-workbench-center"> - <Toolbar area={skeleton.toolbar} /> - <MainArea area={skeleton.mainArea} /> - <BottomArea area={skeleton.bottomArea} /> - </div> - <RightArea area={skeleton.rightArea} /> - </div> - <TipContainer /> - </div> - ); - } -} diff --git a/packages/vision-polyfill/src/skeleton/panel.ts b/packages/vision-polyfill/src/skeleton/panel.ts deleted file mode 100644 index c9e2e890d..000000000 --- a/packages/vision-polyfill/src/skeleton/panel.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { createElement, ReactNode } from 'react'; -import { obx, uniqueId, createContent, TitleContent } from '@ali/lowcode-globals'; -import WidgetContainer from './widget-container'; -import { PanelConfig, HelpTipConfig } from './types'; -import { TitledPanelView, TabsPanelView, PanelView } from './components/widget-views'; -import { Skeleton } from './skeleton'; -import { composeTitle } from './widget/utils'; -import { IWidget } from './widget'; - -export default class Panel implements IWidget { - readonly isWidget = true; - readonly name: string; - readonly id: string; - @obx.ref inited: boolean = false; - @obx.ref private _actived: boolean = false; - get actived(): boolean { - return this._actived; - } - - get visible(): boolean { - if (this.parent?.visible) { - return this._actived; - } - return false; - } - - readonly isPanel = true; - - private _body?: ReactNode; - get body() { - this.initBody(); - return this._body; - } - - get content(): ReactNode { - if (this.plain) { - return createElement(PanelView, { - panel: this, - key: this.id, - }); - } - return createElement(TitledPanelView, { panel: this, key: this.id }); - } - - readonly title: TitleContent; - readonly help?: HelpTipConfig; - private plain: boolean = false; - - private container?: WidgetContainer<Panel, PanelConfig>; - private parent?: WidgetContainer; - - constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { - const { name, content, props = {} } = config; - const { hideTitleBar, title, icon, description, help, shortcut } = props; - this.name = name; - this.id = uniqueId(`pane:${name}$`); - this.title = composeTitle(title || name, icon, description); - this.plain = hideTitleBar || !title; - this.help = help; - if (Array.isArray(content)) { - this.container = this.skeleton.createContainer( - name, - (item) => { - if (isPanel(item)) { - return item; - } - return this.skeleton.createPanel(item); - }, - true, - () => this.visible, - true, - ); - content.forEach((item) => this.add(item)); - } - // todo: process shortcut - } - - private initBody() { - if (this.inited) { - return; - } - this.inited = true; - if (this.container) { - this._body = createElement(TabsPanelView, { - container: this.container, - }); - } else { - const { content, contentProps } = this.config; - this._body = createContent(content, { - ...contentProps, - editor: this.skeleton.editor, - config: this.config, - panel: this, - }); - } - } - - setParent(parent: WidgetContainer) { - if (parent === this.parent) { - return; - } - if (this.parent) { - this.parent.remove(this); - } - this.parent = parent; - } - - add(item: Panel | PanelConfig) { - return this.container?.add(item); - } - - getPane(name: string): Panel | null { - return this.container?.get(name) || null; - } - - remove(item: Panel | string) { - return this.container?.remove(item); - } - - active(item?: Panel | string | null) { - this.container?.active(item); - } - - getName() { - return this.name; - } - - getContent() { - return this.content; - } - - setActive(flag: boolean) { - if (flag === this._actived) { - // TODO: 如果移动到另外一个 container,会有问题 - return; - } - if (flag) { - if (!this.inited) { - this.initBody(); - } - this._actived = true; - this.parent?.active(this); - } else if (this.inited) { - this._actived = false; - this.parent?.unactive(this); - } - } - - toggle() { - this.setActive(!this._actived); - } - - hide() { - this.setActive(false); - } - - show() { - this.setActive(true); - } -} - -export function isPanel(obj: any): obj is Panel { - return obj && obj.isPanel; -} diff --git a/packages/vision-polyfill/src/skeleton/skeleton.ts b/packages/vision-polyfill/src/skeleton/skeleton.ts deleted file mode 100644 index 2ed0c7b39..000000000 --- a/packages/vision-polyfill/src/skeleton/skeleton.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { Editor } from '@ali/lowcode-editor-core'; -import { - DockConfig, - PanelConfig, - WidgetConfig, - IWidgetBaseConfig, - PanelDockConfig, - DialogDockConfig, - isDockConfig, - isPanelDockConfig, - isPanelConfig, - DividerConfig, - isDividerConfig -} from './types'; -import Panel, { isPanel } from './widget/panel'; -import WidgetContainer from './widget/widget-container'; -import Area from './area'; -import Widget, { isWidget, IWidget } from './widget/widget'; -import PanelDock from './widget/panel-dock'; -import Dock from './widget/dock'; -import { Stage, StageConfig } from './widget/stage'; -import { isValidElement } from 'react'; -import { isPlainObject } from 'globals/src/utils'; -import { Divider } from '@alifd/next'; - -export enum SkeletonEvents { - PANEL_DOCK_ACTIVE = 'skeleton.panel-dock.active', - PANEL_DOCK_UNACTIVE = 'skeleton.panel-dock.unactive', - PANEL_SHOW = 'skeleton.panel.show', - PANEL_HIDE = 'skeleton.panel.hide', - WIDGET_SHOW = 'skeleton.widget.show', - WIDGET_HIDE = 'skeleton.widget.hide', -} - -export class Skeleton { - private panels = new Map<string, Panel>(); - private containers = new Map<string, WidgetContainer<any>>(); - readonly leftArea: Area<DockConfig | PanelDockConfig | DialogDockConfig>; - readonly topArea: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - readonly toolbar: Area<DockConfig | DividerConfig | PanelDockConfig | DialogDockConfig>; - readonly leftFixedArea: Area<PanelConfig, Panel>; - readonly leftFloatArea: Area<PanelConfig, Panel>; - readonly rightArea: Area<PanelConfig, Panel>; - readonly mainArea: Area<WidgetConfig | PanelConfig, Widget | Panel>; - readonly bottomArea: Area<PanelConfig, Panel>; - readonly stages: Area<StageConfig, Stage>; - - constructor(readonly editor: Editor) { - this.leftArea = new Area( - this, - 'leftArea', - (config) => { - if (isWidget(config)) { - return config; - } - return this.createWidget(config); - }, - false, - ); - this.topArea = new Area( - this, - 'topArea', - (config) => { - if (isWidget(config)) { - return config; - } - return this.createWidget(config); - }, - false, - ); - this.toolbar = new Area( - this, - 'toolbar', - (config) => { - if (isWidget(config)) { - return config; - } - return this.createWidget(config); - }, - false, - ); - this.leftFixedArea = new Area( - this, - 'leftFixedArea', - (config) => { - if (isPanel(config)) { - return config; - } - return this.createPanel(config); - }, - true, - ); - this.leftFloatArea = new Area( - this, - 'leftFloatArea', - (config) => { - if (isPanel(config)) { - return config; - } - return this.createPanel(config); - }, - true, - ); - this.rightArea = new Area( - this, - 'rightArea', - (config) => { - if (isPanel(config)) { - return config; - } - return this.createPanel(config); - }, - true, - true, - ); - this.mainArea = new Area( - this, - 'mainArea', - (config) => { - if (isWidget(config)) { - return config as Widget; - } - return this.createWidget(config) as Widget; - }, - true, - true, - ); - this.bottomArea = new Area( - this, - 'bottomArea', - (config) => { - if (isPanel(config)) { - return config; - } - return this.createPanel(config); - }, - true, - ); - this.stages = new Area(this, 'stages', (config) => { - if (isWidget(config)) { - return config; - } - return new Stage(this, config); - }); - - this.setupPlugins(); - } - - private setupPlugins() { - const { config, components: componentsMap } = this.editor; - const { plugins } = config; - if (!plugins) { - return; - } - Object.keys(plugins).forEach((area) => { - plugins[area].forEach((item) => { - const { pluginKey, type, props = {}, pluginProps } = item; - const config: any = { - area, - type: 'Widget', - name: pluginKey, - contentProps: pluginProps, - }; - const { dialogProps, balloonProps, panelProps, linkProps, ...restProps } = props; - config.props = restProps; - if (dialogProps) { - config.dialogProps = dialogProps; - } - if (balloonProps) { - config.balloonProps = balloonProps; - } - if (panelProps) { - config.panelProps = panelProps; - } - if (linkProps) { - config.linkProps = linkProps; - } - if (type === 'TabPanel') { - config.type = 'Panel'; - } else if (/Icon$/.test(type)) { - config.type = type.replace('Icon', 'Dock'); - } - if (pluginKey in componentsMap) { - config.content = componentsMap[pluginKey]; - } - this.add(config); - }); - }); - } - - postEvent(event: SkeletonEvents, ...args: any[]) { - this.editor.emit(event, ...args); - } - - createWidget(config: IWidgetBaseConfig | IWidget) { - if (isWidget(config)) { - return config; - } - - config = this.parseConfig(config); - let widget: IWidget; - if (isDockConfig(config)) { - if (isPanelDockConfig(config)) { - widget = new PanelDock(this, config); - } else if (false) { - // DialogDock - // others... - } else { - - widget = new Dock(this, config); - } - } else if (isDividerConfig(config)) { - widget = new Widget(this, { - ...config, - type: 'Widget', - content: Divider, - }); - } else if (isPanelConfig(config)) { - widget = this.createPanel(config); - } else { - widget = new Widget(this, config as WidgetConfig); - } - return widget; - } - - createPanel(config: PanelConfig) { - config = this.parseConfig(config); - const panel = new Panel(this, config); - this.panels.set(panel.name, panel); - return panel; - } - - getPanel(name: string): Panel | undefined { - return this.panels.get(name); - } - - createContainer( - name: string, - handle: (item: any) => any, - exclusive = false, - checkVisible: () => boolean = () => true, - defaultSetCurrent = false, - ) { - const container = new WidgetContainer(name, handle, exclusive, checkVisible, defaultSetCurrent); - this.containers.set(name, container); - return container; - } - - private parseConfig(config: IWidgetBaseConfig): any { - if ((config as any).parsed) { - return config; - } - const { content, ...restConfig } = config; - if (content) { - if (isPlainObject(content) && !isValidElement(content)) { - Object.keys(content).forEach((key) => { - if (/props$/i.test(key) && restConfig[key]) { - restConfig[key] = { - ...restConfig[key], - ...content[key], - }; - } else { - restConfig[key] = content[key]; - } - }); - } else { - restConfig.content = content; - } - } - restConfig.pluginKey = restConfig.name; - restConfig.parsed = true; - return restConfig; - } - - add(config: IWidgetBaseConfig & { area?: string }, extraConfig?: object) { - const parsedConfig: any = { - ...this.parseConfig(config), - ...extraConfig, - }; - let { area } = parsedConfig; - if (!area) { - if (parsedConfig.type === 'Panel') { - area = 'leftFloatArea' - } else if (parsedConfig.type === 'Widget') { - area = 'mainArea'; - } else { - area = 'leftArea'; - } - } - switch (area) { - case 'leftArea': - case 'left': - return this.leftArea.add(parsedConfig); - case 'rightArea': - case 'right': - return this.rightArea.add(parsedConfig); - case 'topArea': - case 'top': - return this.topArea.add(parsedConfig); - case 'toolbar': - return this.toolbar.add(parsedConfig); - case 'mainArea': - case 'main': - case 'center': - case 'centerArea': - return this.mainArea.add(parsedConfig); - case 'bottomArea': - case 'bottom': - return this.bottomArea.add(parsedConfig); - case 'leftFixedArea': - return this.leftFixedArea.add(parsedConfig); - case 'leftFloatArea': - return this.leftFloatArea.add(parsedConfig); - case 'stages': - return this.stages.add(parsedConfig); - } - } -} diff --git a/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts b/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts deleted file mode 100644 index 80ad16cc1..000000000 --- a/packages/vision-polyfill/src/skeleton/transducers/addon-combine.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { TransformedComponentMetadata, FieldConfig } from '@ali/lowcode-globals'; - -export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { - const { componentName, configure = {} } = metadata; - if (componentName === 'Leaf') { - return { - ...metadata, - configure: { - ...configure, - combined: [ - { - name: 'children', - title: { type: 'i18n', 'zh-CN': '内容设置', 'en-US': 'Content' }, - setter: { - componentName: 'MixinSetter', - props: { - // TODO: - setters: [ - { - componentName: 'StringSetter', - props: { - // TODO: textarea mode - multiline: true, - }, - initialValue: '', - }, - { - componentName: 'ExpressionSetter', - initialValue: { - type: 'JSExpression', - value: '', - }, - }, - ], - }, - }, - }, - ], - }, - }; - } - - const { props, events = {}, styles } = configure as any; - const isRoot: boolean = componentName === 'Page' || componentName === 'Component'; - const eventsDefinition: any[] = []; - const supportedLifecycles = - events.supportedLifecycles || - (isRoot - ? [ - { - description: '初始化时', - name: 'constructor', - }, - { - description: '装载后', - name: 'componentDidMount', - }, - { - description: '更新时', - name: 'componentDidMount', - }, - { - description: '卸载时', - name: 'componentWillUnmount', - }, - ] - : null); - if (supportedLifecycles) { - eventsDefinition.push({ - type: 'lifeCycleEvent', - title: '生命周期', - list: supportedLifecycles.map((event: any) => (typeof event === 'string' ? { name: event } : event)), - }); - } - if (events.supportedEvents) { - eventsDefinition.push({ - type: 'events', - title: '事件', - list: (events.supportedEvents || []).map((event: any) => (typeof event === 'string' ? { name: event } : event)), - }); - } - // 通用设置 - const propsGroup = props || []; - propsGroup.push({ - name: '#generals', - title: { type: 'i18n', 'zh-CN': '通用', 'en-US': 'General' }, - items: [ - { - name: 'id', - title: 'ID', - setter: 'StringSetter', - }, - { - name: 'key', - title: 'Key', - // todo: use Mixin - setter: 'StringSetter', - }, - { - name: 'ref', - title: 'Ref', - setter: 'StringSetter', - }, - /* - { - name: '!more', - title: '更多', - setter: 'PropertiesSetter', - },*/ - ], - }); - const combined: FieldConfig[] = [ - { - title: { type: 'i18n', 'zh-CN': '属性', 'en-US': 'Props' }, - name: '#props', - items: propsGroup, - }, - ]; - const stylesGroup: FieldConfig[] = []; - if (styles?.supportClassName) { - stylesGroup.push({ - name: 'className', - title: { type: 'i18n', 'zh-CN': '类名绑定', 'en-US': 'ClassName' }, - setter: 'ClassNameSetter', - }); - } - if (styles?.supportInlineStyle) { - stylesGroup.push({ - name: 'style', - title: { type: 'i18n', 'zh-CN': '行内样式', 'en-US': 'Style' }, - setter: 'StyleSetter', - }); - } - if (stylesGroup.length > 0) { - combined.push({ - name: '#styles', - title: { type: 'i18n', 'zh-CN': '样式', 'en-US': 'Styles' }, - items: stylesGroup, - }); - } - - if (eventsDefinition.length > 0) { - combined.push({ - name: '#events', - title: { type: 'i18n', 'zh-CN': '事件', 'en-US': 'Events' }, - items: [ - { - name: '!events', - title: { type: 'i18n', 'zh-CN': '事件设置', 'en-US': 'Events' }, - setter: { - componentName: 'EventsSetter', - props: { - definition: eventsDefinition, - }, - }, - getValue(field: SettingField, val?: any[]) { - // todo: - return val; - }, - - setValue(field: SettingField, eventDataList: any[]) { - // todo: - return; - }, - }, - ], - }); - } - - if (isRoot) { - /* - combined.push({ - name: '#advanced', - title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, - items: [], - }); - */ - } else { - combined.push({ - name: '#advanced', - title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advance' }, - items: [ - { - name: '__condition', - title: { type: 'i18n', 'zh-CN': '条件显示', 'en-US': 'Condition' }, - setter: 'ExpressionSetter', - }, - { - name: '#loop', - title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' }, - items: [ - { - name: '__loop', - title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, - setter: { - componentName: 'MixinSetter', - props: { - // TODO: - setters: [ - { - componentName: 'JSONSetter', - props: { - mode: 'popup', - placeholder: { type: 'i18n', 'zh-CN': '编辑数据', 'en-US': 'Edit Data' }, - }, - }, - { - componentName: 'ExpressionSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '绑定数据', 'en-US': 'Bind Data' }, - }, - }, - ], - }, - }, - }, - { - name: '__loopArgs.0', - title: { type: 'i18n', 'zh-CN': '迭代变量名', 'en-US': 'Loop Item' }, - setter: { - componentName: 'StringSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '默认为: item', 'en-US': 'Defaults: item' }, - } - }, - }, - { - name: '__loopArgs.1', - title: { type: 'i18n', 'zh-CN': '索引变量名', 'en-US': 'Loop Index' }, - setter: { - componentName: 'StringSetter', - props: { - placeholder: { type: 'i18n', 'zh-CN': '默认为: index', 'en-US': 'Defaults: index' }, - } - }, - }, - { - name: 'key', - title: 'Key', - setter: 'ExpressionSetter', - }, - ], - }, - ], - }); - } - - return { - ...metadata, - configure: { - ...configure, - combined, - }, - }; -} diff --git a/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts b/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts deleted file mode 100644 index 43bd44221..000000000 --- a/packages/vision-polyfill/src/skeleton/transducers/parse-props.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { - FieldConfig, - PropConfig, - PropType, - SetterType, - OneOf, - Shape, - ObjectOf, - ArrayOf, - TransformedComponentMetadata, -} from '@ali/lowcode-globals'; - -function propConfigToFieldConfig(propConfig: PropConfig): FieldConfig { - const { name, description } = propConfig; - const title = { - label: { - type: 'i18n', - 'en-US': name, - 'zh-CN': description?.slice(0, 10) || name, - }, - tip: description ? `${name} | ${description}` : undefined, - }; - return { - title, - ...propConfig, - setter: propTypeToSetter(propConfig.propType), - }; -} - -function propTypeToSetter(propType: PropType): SetterType { - let typeName: string; - let isRequired: boolean | undefined = false; - if (typeof propType === 'string') { - typeName = propType; - } else { - typeName = propType.type; - isRequired = propType.isRequired; - } - // TODO: use mixinSetter wrapper - switch (typeName) { - case 'string': - return { - componentName: 'StringSetter', - isRequired, - initialValue: '', - }; - - case 'number': - return { - componentName: 'NumberSetter', - isRequired, - initialValue: 0, - }; - case 'bool': - return { - componentName: 'NumberSetter', - isRequired, - initialValue: false, - }; - case 'oneOf': - const dataSource = ((propType as OneOf).value || []).map((value, index) => { - const t = typeof value; - return { - label: t === 'string' || t === 'number' || t === 'boolean' ? String(value) : `value ${index}`, - value, - }; - }); - const componentName = dataSource.length > 4 ? 'SelectSetter' : 'RadioGroupSetter'; - return { - componentName, - props: { dataSource }, - isRequired, - initialValue: dataSource[0] ? dataSource[0].value : null, - }; - - case 'element': - case 'node': // TODO: use Mixin - return { - // slotSetter - componentName: 'NodeSetter', - props: { - mode: typeName, - }, - isRequired, - initialValue: { - type: 'JSSlot', - value: '', - }, - }; - case 'shape': - case 'exact': - const items = (propType as Shape).value.map((item) => propConfigToFieldConfig(item)); - return { - componentName: 'ObjectSetter', - props: { - config: { - items, - extraSetter: typeName === 'shape' ? propTypeToSetter('any') : null, - }, - }, - isRequired, - initialValue: (field: any) => { - const data: any = {}; - items.forEach((item) => { - let initial = item.defaultValue; - if (initial == null && item.setter && typeof item.setter === 'object') { - initial = (item.setter as any).initialValue; - } - data[item.name] = initial ? (typeof initial === 'function' ? initial(field) : initial) : null; - }); - return data; - }, - }; - case 'object': - case 'objectOf': - return { - componentName: 'ObjectSetter', - props: { - config: { - extraSetter: propTypeToSetter(typeName === 'objectOf' ? (propType as ObjectOf).value : 'any'), - }, - }, - isRequired, - }; - case 'array': - case 'arrayOf': - return { - componentName: 'ArraySetter', - props: { - itemSetter: propTypeToSetter(typeName === 'arrayOf' ? (propType as ArrayOf).value : 'any'), - }, - isRequired, - initialValue: [], - }; - case 'func': - return { - componentName: 'FunctionSetter', - isRequired, - initialValue: { - type: 'JSFunction', - value: 'function(){}', - }, - }; - case 'oneOfType': - return { - componentName: 'MixinSetter', - props: { - // TODO: - // setters: (propType as OneOfType).value.map(item => propTypeToSetter(item)), - }, - isRequired, - }; - } - - return { - componentName: 'MixinSetter', - isRequired, - }; -} - -const EVENT_RE = /^on[A-Z][\w]*$/; - -export default function(metadata: TransformedComponentMetadata): TransformedComponentMetadata { - const { configure } = metadata; - if (configure.props) { - return metadata; - } - - if (!metadata.props) { - return { - ...metadata, - configure: { - ...configure, - props: [], - }, - }; - } - const { component = {}, events = {}, styles = {} } = configure; - const supportedEvents: any[] | null = (events as any).supportedEvents ? null : []; - const props: FieldConfig[] = []; - - metadata.props.forEach((prop) => { - const { name, propType, description } = prop; - if ( - name === 'children' && - (component.isContainer || propType === 'node' || propType === 'element' || propType === 'any') - ) { - if (component.isContainer !== false) { - component.isContainer = true; - return; - } - } - - if (EVENT_RE.test(name) && (propType === 'func' || propType === 'any')) { - if (supportedEvents) { - supportedEvents.push({ - name, - description, - }); - (events as any).supportedEvents = supportedEvents; - } - return; - } - - if (name === 'className' && (propType === 'string' || propType === 'any')) { - if ((styles as any).supportClassName == null) { - (styles as any).supportClassName = true; - } - return; - } - - if (name === 'style' && (propType === 'object' || propType === 'any')) { - if ((styles as any).supportInlineStyle == null) { - (styles as any).supportInlineStyle = true; - } - return; - } - - props.push(propConfigToFieldConfig(prop)); - }); - - return { - ...metadata, - configure: { - ...configure, - props, - events, - styles, - component, - }, - }; -} diff --git a/packages/vision-polyfill/src/skeleton/transducers/register.ts b/packages/vision-polyfill/src/skeleton/transducers/register.ts deleted file mode 100644 index a09e685ed..000000000 --- a/packages/vision-polyfill/src/skeleton/transducers/register.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { registerMetadataTransducer } from '@ali/lowcode-globals'; -import parseProps from './parse-props'; -import addonCombine from './addon-combine'; - -// parseProps -registerMetadataTransducer(parseProps, 10, 'parse-props'); - -// addon/platform custom -registerMetadataTransducer(addonCombine, 11, 'combine-props'); diff --git a/packages/vision-polyfill/src/skeleton/types.ts b/packages/vision-polyfill/src/skeleton/types.ts deleted file mode 100644 index b44b7b165..000000000 --- a/packages/vision-polyfill/src/skeleton/types.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { ReactElement, ComponentType } from 'react'; -import { TitleContent, IconType, I18nData, TipContent } from '@ali/lowcode-globals'; - -export interface IWidgetBaseConfig { - type: string; - name: string; - area?: string; // 停靠位置, 默认 float, 如果添加非固定区, - props?: object; - content?: any; - contentProps?: object; - // index?: number; - [extra: string]: any; -} - -export interface WidgetConfig extends IWidgetBaseConfig { - type: "Widget"; - props?: { - align?: "left" | "right" | "bottom" | "center" | "top"; - }; - content?: string | ReactElement | ComponentType<any>; // children -} - -export function isWidgetConfig(obj: any): obj is WidgetConfig { - return obj && obj.type === "Widget"; -} - -export interface DockProps { - title?: TitleContent; - icon?: IconType; - size?: 'small' | 'medium' | 'large'; - className?: string; - description?: TipContent; - onClick?: () => void; -} - -export interface DividerConfig extends IWidgetBaseConfig { - type: "Divider"; - props?: { - align?: "left" | "right" | "center"; - }; -} - -export function isDividerConfig(obj: any): obj is DividerConfig { - return obj && obj.type === "Divider"; -} - -export interface IDockBaseConfig extends IWidgetBaseConfig { - props?: DockProps & { - align?: "left" | "right" | "bottom" | "center" | "top"; - }; -} - -export interface DockConfig extends IDockBaseConfig { - type: "Dock"; - content?: string | ReactElement | ComponentType<any>; -} - -export function isDockConfig(obj: any): obj is DockConfig { - return obj && /Dock$/.test(obj.type); -} - -// 按钮弹窗扩展 -export interface DialogDockConfig extends IDockBaseConfig { - type: "DialogDock"; - dialogProps?: { - title?: TitleContent; - [key: string]: any; - }; -} - -export function isDialogDockConfig(obj: any): obj is DialogDockConfig { - return obj && obj.type === 'DialogDock'; -} - -// 窗格扩展 -export interface PanelConfig extends IWidgetBaseConfig { - type: "Panel"; - content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // as children - props?: PanelProps; -} - -export function isPanelConfig(obj: any): obj is PanelConfig { - return obj && obj.type === 'Panel'; -} - -export type HelpTipConfig = string | { url?: string; content?: string | ReactElement }; - -export interface PanelProps { - title?: TitleContent; - icon?: any; // 冗余字段 - description?: string | I18nData; - hideTitleBar?: boolean; // panel.props 兼容,不暴露 - help?: HelpTipConfig; // 显示问号帮助 - width?: number; // panel.props - height?: number; // panel.props - maxWidth?: number; // panel.props - maxHeight?: number; // panel.props - onInit?: () => any; - onDestroy?: () => any; - shortcut?: string; // 只有在特定位置,可触发 toggle show -} - -export interface PanelDockConfig extends IDockBaseConfig { - type: "PanelDock"; - panelName?: string; - panelProps?: PanelProps & { - area?: string; - }; - content?: string | ReactElement | ComponentType<any> | PanelConfig[]; // content for pane -} - -export function isPanelDockConfig(obj: any): obj is PanelDockConfig { - return obj && obj.type === 'PanelDock'; -} diff --git a/packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts b/packages/vision-polyfill/src/skeleton/widget/dialog-dock.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/vision-polyfill/src/skeleton/widget/dock.ts b/packages/vision-polyfill/src/skeleton/widget/dock.ts deleted file mode 100644 index 019b2e321..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/dock.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { uniqueId, createContent, obx } from '@ali/lowcode-globals'; -import { DockConfig } from "../types"; -import { Skeleton } from '../skeleton'; -import { DockView, WidgetView } from '../components/widget-views'; -import { IWidget } from './widget'; - -/** - * 带图标(主要)/标题(次要)的扩展 - */ -export default class Dock implements IWidget { - readonly isWidget = true; - readonly id = uniqueId('dock'); - readonly name: string; - readonly align?: string; - - @obx.ref private _visible: boolean = true; - get visible(): boolean { - return this._visible; - } - - get content(): ReactNode { - return createElement(WidgetView, { - widget: this, - key: this.id, - }); - } - - private inited: boolean = false; - private _body: ReactNode; - get body() { - if (this.inited) { - return this._body; - } - - const { props, content, contentProps } = this.config; - - if (content) { - this._body = createContent(content, { - ...contentProps, - config: this.config, - editor: this.skeleton.editor, - }); - } else { - this._body = createElement(DockView, props); - } - return this._body; - } - - constructor(readonly skeleton: Skeleton, readonly config: DockConfig) { - const { props = {}, name } = config; - this.name = name; - this.align = props.align; - } - - setVisible(flag: boolean) { - if (flag === this._visible) { - return; - } - if (flag) { - this._visible = true; - } else if (this.inited) { - this._visible = false; - } - } - - getContent() { - return this.content; - } - - getName() { - return this.name; - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } - - toggle() { - this.setVisible(!this._visible); - } -} diff --git a/packages/vision-polyfill/src/skeleton/widget/panel-dock.ts b/packages/vision-polyfill/src/skeleton/widget/panel-dock.ts deleted file mode 100644 index c47d3290a..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/panel-dock.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { uniqueId, obx, computed } from '@ali/lowcode-globals'; -import { createElement, ReactNode } from 'react'; -import { Skeleton } from '../skeleton'; -import { PanelDockConfig } from '../types'; -import Panel from './panel'; -import { PanelDockView, WidgetView } from '../components/widget-views'; -import { IWidget } from './widget'; - -export default class PanelDock implements IWidget { - readonly isWidget = true; - readonly id: string; - readonly name: string; - readonly align?: string; - - private inited: boolean = false; - private _body: ReactNode; - get body() { - if (this.inited) { - return this._body; - } - this.inited = true; - const { props } = this.config; - - this._body = createElement(PanelDockView, { - ...props, - dock: this, - }); - - return this._body; - } - - get content(): ReactNode { - return createElement(WidgetView, { - widget: this, - key: this.id, - }); - } - - @obx.ref private _visible: boolean = true; - get visible() { - return this._visible; - } - - @computed get actived(): boolean { - return this.panel?.visible || false; - } - - readonly panelName: string; - private _panel?: Panel; - @computed get panel() { - return this._panel || this.skeleton.getPanel(this.panelName); - } - - constructor(readonly skeleton: Skeleton, readonly config: PanelDockConfig) { - const { content, contentProps, panelProps, name, props } = config; - this.name = name; - this.id = uniqueId(`dock:${name}$`); - this.panelName = config.panelName || name; - if (content) { - this._panel = this.skeleton.add({ - type: "Panel", - name: this.panelName, - props: { - // FIXME! give default title for panel - // title: props ? composeTitle(props?.title, props?.icon, props?.description, true) : '', - ...panelProps, - }, - contentProps, - content, - area: panelProps?.area - }) as Panel; - } - } - - setVisible(flag: boolean) { - if (flag === this._visible) { - return; - } - if (flag) { - this._visible = true; - } else if (this.inited) { - this._visible = false; - } - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } - - toggle() { - this.setVisible(!this._visible); - } - - togglePanel() { - this.panel?.toggle(); - } - - getName() { - return this.name; - } - - getContent() { - return this.content; - } - - hidePanel() { - this.panel?.setActive(false); - } - - showPanel() { - this.panel?.setActive(true); - } -} diff --git a/packages/vision-polyfill/src/skeleton/widget/panel.ts b/packages/vision-polyfill/src/skeleton/widget/panel.ts deleted file mode 100644 index 9a33c3e44..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/panel.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { createElement, ReactNode } from 'react'; -import { obx, uniqueId, createContent, TitleContent } from '@ali/lowcode-globals'; -import WidgetContainer from './widget-container'; -import { PanelConfig, HelpTipConfig } from '../types'; -import { TitledPanelView, TabsPanelView, PanelView } from '../components/widget-views'; -import { Skeleton } from '../skeleton'; -import { composeTitle } from './utils'; -import { IWidget } from './widget'; - -export default class Panel implements IWidget { - readonly isWidget = true; - readonly name: string; - readonly id: string; - @obx.ref inited: boolean = false; - @obx.ref private _actived: boolean = false; - get actived(): boolean { - return this._actived; - } - - get visible(): boolean { - if (this.parent?.visible) { - return this._actived; - } - return false; - } - - readonly isPanel = true; - - private _body?: ReactNode; - get body() { - this.initBody(); - return this._body; - } - - get content(): ReactNode { - if (this.plain) { - return createElement(PanelView, { - panel: this, - key: this.id, - }); - } - return createElement(TitledPanelView, { panel: this, key: this.id }); - } - - readonly title: TitleContent; - readonly help?: HelpTipConfig; - private plain: boolean = false; - - private container?: WidgetContainer<Panel, PanelConfig>; - private parent?: WidgetContainer; - - constructor(readonly skeleton: Skeleton, readonly config: PanelConfig) { - const { name, content, props = {} } = config; - const { hideTitleBar, title, icon, description, help, shortcut } = props; - this.name = name; - this.id = uniqueId(`pane:${name}$`); - this.title = composeTitle(title || name, icon, description); - this.plain = hideTitleBar || !title; - this.help = help; - if (Array.isArray(content)) { - this.container = this.skeleton.createContainer( - name, - (item) => { - if (isPanel(item)) { - return item; - } - return this.skeleton.createPanel(item); - }, - true, - () => this.visible, - true, - ); - content.forEach((item) => this.add(item)); - } - // todo: process shortcut - } - - private initBody() { - if (this.inited) { - return; - } - this.inited = true; - if (this.container) { - this._body = createElement(TabsPanelView, { - container: this.container, - }); - } else { - const { content, contentProps } = this.config; - this._body = createContent(content, { - ...contentProps, - editor: this.skeleton.editor, - config: this.config, - panel: this, - }); - } - } - - setParent(parent: WidgetContainer) { - if (parent === this.parent) { - return; - } - if (this.parent) { - this.parent.remove(this); - } - this.parent = parent; - } - - add(item: Panel | PanelConfig) { - return this.container?.add(item); - } - - getPane(name: string): Panel | null { - return this.container?.get(name) || null; - } - - remove(item: Panel | string) { - return this.container?.remove(item); - } - - active(item?: Panel | string | null) { - this.container?.active(item); - } - - getName() { - return this.name; - } - - getContent() { - return this.content; - } - - setActive(flag: boolean) { - if (flag === this._actived) { - // TODO: 如果移动到另外一个 container,会有问题 - return; - } - if (flag) { - if (!this.inited) { - this.initBody(); - } - this._actived = true; - this.parent?.active(this); - } else if (this.inited) { - this._actived = false; - this.parent?.unactive(this); - } - } - - toggle() { - this.setActive(!this._actived); - } - - hide() { - this.setActive(false); - } - - show() { - this.setActive(true); - } -} - -export function isPanel(obj: any): obj is Panel { - return obj && obj.isPanel; -} diff --git a/packages/vision-polyfill/src/skeleton/widget/stage.ts b/packages/vision-polyfill/src/skeleton/widget/stage.ts deleted file mode 100644 index a4bf483f2..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/stage.ts +++ /dev/null @@ -1,51 +0,0 @@ -import Widget from './widget'; -import { Skeleton } from '../skeleton'; -import { WidgetConfig } from '../types'; - -export interface StageConfig extends WidgetConfig { - isRoot?: boolean; -} - -export class Stage extends Widget { - readonly isRoot: boolean; - private previous?: Stage; - private refer?: { - stage?: Stage; - direction?: 'right' | 'left'; - }; - - constructor(skeleton: Skeleton, config: StageConfig) { - super(skeleton, config); - this.isRoot = config.isRoot || false; - } - - setPrevious(stage: Stage) { - this.previous = stage; - } - - getPrevious() { - return this.previous; - } - - hasBack(): boolean { - return this.previous && !this.isRoot ? true : false; - } - - setRefer(stage: Stage, direction: 'right' | 'left') { - this.refer = { stage, direction }; - } - - setReferRight(stage: Stage) { - this.setRefer(stage, 'right'); - } - - setReferLeft(stage: Stage) { - this.setRefer(stage, 'left'); - } - - getRefer() { - const refer = this.refer; - this.refer = undefined; - return refer; - } -} diff --git a/packages/vision-polyfill/src/skeleton/widget/utils.ts b/packages/vision-polyfill/src/skeleton/widget/utils.ts deleted file mode 100644 index 301426a87..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { IconType, TitleContent, isI18nData, TipContent } from '@ali/lowcode-globals'; -import { isValidElement } from 'react'; - -export function composeTitle(title?: TitleContent, icon?: IconType, tip?: TipContent, tipAsTitle?: boolean) { - if (!title) { - title = {}; - if (!icon || tipAsTitle) { - title.label = tip; - tip = undefined; - } - } - if (icon || tip) { - if (typeof title !== 'object' || isValidElement(title) || isI18nData(title)) { - title = { - label: title, - icon, - tip, - }; - } else { - title = { - ...title, - icon, - tip - }; - } - } - return title; -} diff --git a/packages/vision-polyfill/src/skeleton/widget/widget-container.ts b/packages/vision-polyfill/src/skeleton/widget/widget-container.ts deleted file mode 100644 index b34827ae7..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/widget-container.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { obx, hasOwnProperty, computed } from '@ali/lowcode-globals'; -import { isPanel } from './panel'; -export interface WidgetItem { - name: string; -} - -export interface Activeable { - setActive(flag: boolean): void; -} - -function isActiveable(obj: any): obj is Activeable { - return obj && obj.setActive; -} - -export default class WidgetContainer<T extends WidgetItem = any, G extends WidgetItem = any> { - @obx.val items: T[] = []; - private maps: { [name: string]: T } = {}; - @obx.ref private _current: T & Activeable | null = null; - - get current() { - return this._current; - } - - constructor( - readonly name: string, - private handle: (item: T | G) => T, - private exclusive: boolean = false, - private checkVisible: () => boolean = () => true, - private defaultSetCurrent: boolean = false, - ) {} - - @computed get visible() { - return this.checkVisible(); - } - - active(nameOrItem?: T | string | null) { - let item: any = nameOrItem; - if (nameOrItem && typeof nameOrItem === 'string') { - item = this.get(nameOrItem); - } - if (!isActiveable(nameOrItem)) { - item = null; - } - - if (this.exclusive) { - if (this._current === item) { - return; - } - if (this._current) { - this._current.setActive(false); - } - this._current = item; - } - - if (item) { - item.setActive(true); - } - } - - unactive(nameOrItem?: T | string | null) { - let item: any = nameOrItem; - if (nameOrItem && typeof nameOrItem === 'string') { - item = this.get(nameOrItem); - } - if (!isActiveable(nameOrItem)) { - item = null; - } - if (this._current === item) { - this._current = null; - } - if (item) { - item.setActive(false); - } - } - - add(item: T | G): T { - item = this.handle(item); - const origin = this.get(item.name); - if (origin === item) { - return origin; - } - const i = origin ? this.items.indexOf(origin) : -1; - if (i > -1) { - this.items[i] = item; - } else { - this.items.push(item); - } - this.maps[item.name] = item; - if (isPanel(item)) { - item.setParent(this); - } - if (this.defaultSetCurrent) { - if (!this._current) { - this.active(item); - } - } - return item; - } - - get(name: string): T | null { - return this.maps[name] || null; - } - - getAt(index: number): T | null { - return this.items[index] || null; - } - - has(name: string): boolean { - return hasOwnProperty(this.maps, name); - } - - indexOf(item: T): number { - return this.items.indexOf(item); - } - - /** - * return indexOf the deletion - */ - remove(item: string | T): number { - const thing = typeof item === 'string' ? this.get(item) : item; - if (!thing) { - return -1; - } - const i = this.items.indexOf(thing); - if (i > -1) { - this.items.splice(i, 1); - } - delete this.maps[thing.name]; - if (thing === this.current) { - this._current = null; - } - return i; - } -} diff --git a/packages/vision-polyfill/src/skeleton/widget/widget.ts b/packages/vision-polyfill/src/skeleton/widget/widget.ts deleted file mode 100644 index 1f7a7d84a..000000000 --- a/packages/vision-polyfill/src/skeleton/widget/widget.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { ReactNode, createElement } from 'react'; -import { createContent, uniqueId, obx } from '@ali/lowcode-globals'; -import { WidgetConfig, IWidgetBaseConfig } from '../types'; -import { Skeleton } from '../skeleton'; -import { WidgetView } from '../components/widget-views'; - -export interface IWidget { - readonly name: string; - readonly content: ReactNode; - readonly align?: string; - readonly isWidget: true; - readonly visible: boolean; - readonly body: ReactNode; - readonly skeleton: Skeleton; - readonly config: IWidgetBaseConfig; - - getName(): string; - getContent(): any; - show(): void; - hide(): void; - toggle(): void; -} - -export default class Widget implements IWidget { - readonly isWidget = true; - readonly id = uniqueId('widget'); - readonly name: string; - readonly align?: string; - - @obx.ref private _visible: boolean = true; - get visible(): boolean { - return this._visible; - } - - @obx.ref inited: boolean = false; - private _body: ReactNode; - get body() { - if (this.inited) { - return this._body; - } - this.inited = true; - const { content, contentProps } = this.config; - this._body = createContent(content, { - ...contentProps, - config: this.config, - editor: this.skeleton.editor, - }); - return this._body; - } - - get content(): ReactNode { - return createElement(WidgetView, { - widget: this, - key: this.id, - }); - } - - constructor(readonly skeleton: Skeleton, readonly config: WidgetConfig) { - const { props = {}, name } = config; - this.name = name; - this.align = props.align; - } - - getName() { - return this.name; - } - - getContent() { - return this.content; - } - - hide() { - this.setVisible(false); - } - - show() { - this.setVisible(true); - } - - setVisible(flag: boolean) { - if (flag === this._visible) { - return; - } - if (flag) { - this._visible = true; - } else if (this.inited) { - this._visible = false; - } - } - - toggle() { - this.setVisible(!this._visible); - } -} - -export function isWidget(obj: any): obj is IWidget { - return obj && obj.isWidget; -} - - diff --git a/packages/vision-polyfill/src/symbols.ts b/packages/vision-polyfill/src/symbols.ts deleted file mode 100644 index 4b8493292..000000000 --- a/packages/vision-polyfill/src/symbols.ts +++ /dev/null @@ -1,17 +0,0 @@ -export class SymbolManager { - private symbolMap: { [symbolName: string]: symbol } = {}; - - create(name: string): symbol { - if (this.symbolMap[name]) { - return this.symbolMap[name]; - } - this.symbolMap[name] = Symbol(name); - return this.symbolMap[name]; - } - - get(name: string) { - return this.symbolMap[name]; - } -} - -export default new SymbolManager(); diff --git a/packages/vision-polyfill/src/vision.ts b/packages/vision-polyfill/src/vision.ts index 7bca93882..969228f67 100644 --- a/packages/vision-polyfill/src/vision.ts +++ b/packages/vision-polyfill/src/vision.ts @@ -3,13 +3,12 @@ import Popup from '@ali/ve-popups'; import Icons from '@ali/ve-icons'; import { render } from 'react-dom'; import I18nUtil from '@ali/ve-i18n-util'; -import { hotkey as Hotkey } from '@ali/lowcode-globals'; +import { hotkey as Hotkey } from '@ali/lowcode-editor-core'; import { createElement } from 'react'; import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS } from './const'; import Bus from './bus'; -import Symbols from './symbols'; import { skeleton, editor } from './editor'; -import { VisionWorkbench } from './skeleton/layouts/workbench'; +import { Workbench } from '@ali/lowcode-editor-skeleton'; import Panes from './panes'; import Exchange from './exchange'; import VisualEngineContext from './context'; @@ -23,6 +22,8 @@ import Prop from './prop'; import Env from './env'; import './vision.less'; import DragEngine from './drag-engine'; +import * as EditorCore from '@ali/lowcode-editor-core'; +import * as Designer from '@ali/lowcode-designer'; function init(container?: Element) { if (!container) { @@ -32,7 +33,7 @@ function init(container?: Element) { container.id = 'engine'; render( - createElement(VisionWorkbench, { + createElement(Workbench, { skeleton, }), container, @@ -60,6 +61,8 @@ const modules = { const context = new VisualEngineContext(); const VisualEngine = { + EditorCore, + Designer, editor, skeleton, /** @@ -79,8 +82,6 @@ const VisualEngine = { EVENTS, /* 修饰方法 */ HOOKS, - /* Symbol 管理类 */ - Symbols, Exchange, context, /** @@ -103,6 +104,7 @@ export default VisualEngine; (window as any).VisualEngine = VisualEngine; + /* console.log( `%cLowcodeEngine %cv${VERSION}`, From 33b21f0af44c6a3f7c4aa731b1e2021f2b07c998 Mon Sep 17 00:00:00 2001 From: kangwei <bingbing.yb@alibaba-inc.com> Date: Mon, 27 Apr 2020 11:45:42 +0800 Subject: [PATCH 03/12] ready for build --- deploy-space/html/index.html | 29 - .../public => deploy-space/static}/index.html | 18 +- deploy-space/{html => static}/preview.html | 0 packages/demo/cloud-build.json | 7 +- packages/demo/package.json | 1 + packages/demo/public/index.html | 65 +- .../public/legao-assets.json | 0 packages/demo/public/schema.json | 96 +- .../src/demo => demo/src/vision}/index.ts | 1 - .../src/demo => demo/src/vision}/loader.js | 0 .../src => demo/src/vision}/module.d.ts | 0 .../src/vision}/upgrade-assets.js | 0 packages/editor-core/build.json | 13 +- .../build.plugin.js | 0 packages/editor-core/package.json | 18 +- packages/editor/src/editor.ts | 30 - packages/vision-polyfill/build.json | 40 - packages/vision-polyfill/public/assets.json | 1594 ----------------- packages/vision-polyfill/public/favicon.png | Bin 3612 -> 0 bytes .../public/legao-assets-1.json | 584 ------ packages/vision-polyfill/public/schema.json | 18 - .../CHANGELOG.md | 0 .../README.md | 0 packages/vision-preset/build.json | 23 + packages/vision-preset/build.plugin.js | 22 + .../package.json | 16 +- .../src/bak/vision copy.ts.bak} | 0 .../src/base/base.ts | 0 .../src/base/const.ts | 0 .../src/base/schemaManager.ts | 0 .../src/base/visualDesigner.ts | 0 .../src/base/visualManager.ts | 0 .../src/base/visualRender.ts | 0 .../src/bundle/bundle.ts | 0 .../src/bundle/prototype.ts | 0 .../src/bundle/trunk.ts | 0 .../src/bundle/upgrade-metadata.ts | 0 .../src/bus.ts | 0 .../src/const.ts | 0 .../src/context.ts | 0 .../src/drag-engine.ts | 0 .../src/editor.ts | 4 +- .../src/env.ts | 0 .../src/exchange.ts | 0 .../src/field.tsx | 0 .../src/flags.ts | 5 +- .../src/i18n-reducer.ts | 0 .../vision.ts => vision-preset/src/index.ts} | 12 +- .../src/pages.ts | 0 .../src/panes.ts | 0 .../src/prop.ts | 0 .../src/vision.less | 0 .../tsconfig.json | 0 scripts/deploy.sh | 12 +- 54 files changed, 161 insertions(+), 2447 deletions(-) delete mode 100644 deploy-space/html/index.html rename {packages/vision-polyfill/public => deploy-space/static}/index.html (88%) rename deploy-space/{html => static}/preview.html (100%) rename packages/{vision-polyfill => demo}/public/legao-assets.json (100%) rename packages/{vision-polyfill/src/demo => demo/src/vision}/index.ts (99%) rename packages/{vision-polyfill/src/demo => demo/src/vision}/loader.js (100%) rename packages/{vision-polyfill/src => demo/src/vision}/module.d.ts (100%) rename packages/{vision-polyfill/src/demo => demo/src/vision}/upgrade-assets.js (100%) rename packages/{vision-polyfill => editor-core}/build.plugin.js (100%) delete mode 100644 packages/editor/src/editor.ts delete mode 100644 packages/vision-polyfill/build.json delete mode 100644 packages/vision-polyfill/public/assets.json delete mode 100644 packages/vision-polyfill/public/favicon.png delete mode 100644 packages/vision-polyfill/public/legao-assets-1.json delete mode 100644 packages/vision-polyfill/public/schema.json rename packages/{vision-polyfill => vision-preset}/CHANGELOG.md (100%) rename packages/{vision-polyfill => vision-preset}/README.md (100%) create mode 100644 packages/vision-preset/build.json create mode 100644 packages/vision-preset/build.plugin.js rename packages/{vision-polyfill => vision-preset}/package.json (80%) rename packages/{vision-polyfill/src/bak/vision copy.ts => vision-preset/src/bak/vision copy.ts.bak} (100%) rename packages/{vision-polyfill => vision-preset}/src/base/base.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/base/const.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/base/schemaManager.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/base/visualDesigner.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/base/visualManager.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/base/visualRender.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/bundle/bundle.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/bundle/prototype.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/bundle/trunk.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/bundle/upgrade-metadata.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/bus.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/const.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/context.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/drag-engine.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/editor.ts (97%) rename packages/{vision-polyfill => vision-preset}/src/env.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/exchange.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/field.tsx (100%) rename packages/{vision-polyfill => vision-preset}/src/flags.ts (97%) rename packages/{vision-polyfill => vision-preset}/src/i18n-reducer.ts (100%) rename packages/{vision-polyfill/src/vision.ts => vision-preset/src/index.ts} (90%) rename packages/{vision-polyfill => vision-preset}/src/pages.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/panes.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/prop.ts (100%) rename packages/{vision-polyfill => vision-preset}/src/vision.less (100%) rename packages/{vision-polyfill => vision-preset}/tsconfig.json (100%) diff --git a/deploy-space/html/index.html b/deploy-space/html/index.html deleted file mode 100644 index 450c984b7..000000000 --- a/deploy-space/html/index.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8" /> - <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1" /> - <meta name="viewport" content="width=device-width" /> - <title>LowCodeEngine Editor DEMO - - - - - - - - - - - - - - - -
- - - - - - diff --git a/packages/vision-polyfill/public/index.html b/deploy-space/static/index.html similarity index 88% rename from packages/vision-polyfill/public/index.html rename to deploy-space/static/index.html index 95ebbe0d2..64031e0b8 100644 --- a/packages/vision-polyfill/public/index.html +++ b/deploy-space/static/index.html @@ -9,15 +9,17 @@ - + - + + + + + - + + + + + diff --git a/deploy-space/html/preview.html b/deploy-space/static/preview.html similarity index 100% rename from deploy-space/html/preview.html rename to deploy-space/static/preview.html diff --git a/packages/demo/cloud-build.json b/packages/demo/cloud-build.json index 7b4fcd1d9..1333ee8de 100644 --- a/packages/demo/cloud-build.json +++ b/packages/demo/cloud-build.json @@ -1,14 +1,15 @@ { "entry": { - "lowcode-editor": "src/index.ts", - "lowcode-preview": "src/preview.ts" + "lowcode-editor": "src/vision/index.ts" }, "vendor": false, "externals": { "react": "window.React", "react-dom": "window.ReactDOM", "prop-types": "window.PropTypes", - "@ali/lowcode-globals": "window.LCEGlobals" + "@ali/lowcode-editor-core": "window.LCECore", + "@ali/visualengine": "window.VisualEngine", + "@ali/visualengine-utils": "window.VisualEngineUtils" }, "minify": false, "sourcemap": true, diff --git a/packages/demo/package.json b/packages/demo/package.json index fa20554b7..820480e39 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -13,6 +13,7 @@ "dependencies": { "@ali/lowcode-editor-core": "^0.8.4", "@ali/lowcode-editor-skeleton": "^0.8.0", + "@ali/lowcode-utils": "^0.8.0", "@ali/lowcode-plugin-components-pane": "^0.8.0", "@ali/lowcode-plugin-designer": "^0.9.1", "@ali/lowcode-plugin-event-bind-dialog": "^0.8.0", diff --git a/packages/demo/public/index.html b/packages/demo/public/index.html index c8f2cfdcb..95ebbe0d2 100644 --- a/packages/demo/public/index.html +++ b/packages/demo/public/index.html @@ -4,18 +4,73 @@ - LowCodeEngine DEMO + LowCodeEngine Editor DEMO + - + + - - + + + + -
+ + + + diff --git a/packages/vision-polyfill/public/legao-assets.json b/packages/demo/public/legao-assets.json similarity index 100% rename from packages/vision-polyfill/public/legao-assets.json rename to packages/demo/public/legao-assets.json diff --git a/packages/demo/public/schema.json b/packages/demo/public/schema.json index 424628106..1c7d2a300 100644 --- a/packages/demo/public/schema.json +++ b/packages/demo/public/schema.json @@ -14,97 +14,5 @@ "padding": 20 } }, - "children": [{ - "componentName": "Form", - "props": { - "labelCol": 3, - "style": {}, - "ref": "testForm" - }, - "children": [{ - "componentName": "Form.Item", - "props": { - "label": "姓名:", - "name": "name", - "initValue": "李雷" - }, - "children": [{ - "componentName": "Input", - "props": { - "placeholder": "请输入", - "size": "medium", - "style": { - "width": 320 - } - } - }] - }, { - "componentName": "Form.Item", - "props": { - "label": "年龄:", - "name": "age", - "initValue": "22" - }, - "children": [{ - "componentName": "NumberPicker", - "props": { - "size": "medium", - "type": "normal" - } - }] - }, { - "componentName": "Form.Item", - "props": { - "label": "职业:", - "name": "profession" - }, - "children": [{ - "componentName": "Select", - "props": { - "dataSource": [{ - "label": "教师", - "value": "t" - }, { - "label": "医生", - "value": "d" - }, { - "label": "歌手", - "value": "s" - }] - } - }] - }, { - "componentName": "Div", - "props": { - "style": { - "textAlign": "center" - } - }, - "children": [{ - "componentName": "Button.Group", - "props": {}, - "children": [{ - "componentName": "Button", - "props": { - "type": "primary", - "style": { - "margin": "0 5px 0 5px" - }, - "htmlType": "submit" - }, - "children": "提交" - }, { - "componentName": "Button", - "props": { - "type": "normal", - "style": { - "margin": "0 5px 0 5px" - }, - "htmlType": "reset" - }, - "children": "重置" - }] - }] - }] - }] -} \ No newline at end of file + "children": [] +} diff --git a/packages/vision-polyfill/src/demo/index.ts b/packages/demo/src/vision/index.ts similarity index 99% rename from packages/vision-polyfill/src/demo/index.ts rename to packages/demo/src/vision/index.ts index 93bf90a09..4d159a006 100644 --- a/packages/vision-polyfill/src/demo/index.ts +++ b/packages/demo/src/vision/index.ts @@ -1,4 +1,3 @@ -// @ts-ignore import { createElement } from 'react'; import { Button } from '@alifd/next'; import Engine, { Panes } from '@ali/visualengine'; diff --git a/packages/vision-polyfill/src/demo/loader.js b/packages/demo/src/vision/loader.js similarity index 100% rename from packages/vision-polyfill/src/demo/loader.js rename to packages/demo/src/vision/loader.js diff --git a/packages/vision-polyfill/src/module.d.ts b/packages/demo/src/vision/module.d.ts similarity index 100% rename from packages/vision-polyfill/src/module.d.ts rename to packages/demo/src/vision/module.d.ts diff --git a/packages/vision-polyfill/src/demo/upgrade-assets.js b/packages/demo/src/vision/upgrade-assets.js similarity index 100% rename from packages/vision-polyfill/src/demo/upgrade-assets.js rename to packages/demo/src/vision/upgrade-assets.js diff --git a/packages/editor-core/build.json b/packages/editor-core/build.json index e791d5b6b..1f8fb7bb5 100644 --- a/packages/editor-core/build.json +++ b/packages/editor-core/build.json @@ -1,9 +1,14 @@ { "plugins": [ - "build-plugin-component", + [ + "build-plugin-component", + { + "filename": "core", + "library": "LCECore", + "libraryTarget": "umd" + } + ], "build-plugin-fusion", - ["build-plugin-moment-locales", { - "locales": ["zh-cn"] - }] + "./build.plugin.js" ] } diff --git a/packages/vision-polyfill/build.plugin.js b/packages/editor-core/build.plugin.js similarity index 100% rename from packages/vision-polyfill/build.plugin.js rename to packages/editor-core/build.plugin.js diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 0e9ac0349..41f5810ba 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,7 +1,7 @@ { - "name": "@ali/lowcode-globals", + "name": "@ali/lowcode-editor-core", "version": "0.8.6", - "description": "Globals api for Ali lowCode engine", + "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", "module": "es/index.js", @@ -11,19 +11,7 @@ ], "scripts": { "build": "build-scripts build --skip-demo", - "cloud-build": "build-scripts build --skip-demo --config cloud-build.json", - "test": "ava", - "test:snapshot": "ava --update-snapshots" - }, - "ava": { - "compileEnhancements": false, - "extensions": [ - "ts" - ], - "require": [ - "ts-node/register" - ], - "snapshotDir": "test/fixtures/__snapshots__" + "cloud-build": "build-scripts build --skip-demo --config cloud-build.json" }, "dependencies": { "@alifd/next": "^1.19.16", diff --git a/packages/editor/src/editor.ts b/packages/editor/src/editor.ts deleted file mode 100644 index 1cc9a8040..000000000 --- a/packages/editor/src/editor.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { globalContext, Editor } from '@ali/lowcode-editor-core'; -import { Designer } from '@ali/lowcode-designer'; -import DesignerPlugin from '@ali/lowcode-plugin-designer'; -import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton'; - -export const editor = new Editor(); -globalContext.register(editor, Editor); - -export const skeleton = new Skeleton(editor); -editor.set(Skeleton, skeleton); - -export const designer = new Designer({ editor: editor }); -editor.set(Designer, designer); - -skeleton.add({ - area: 'mainArea', - name: 'designer', - type: 'Widget', - content: DesignerPlugin, -}); -skeleton.add({ - area: 'rightArea', - name: 'settingsPane', - type: 'Panel', - content: SettingsPrimaryPane, -}); - -export * from '@ali/lowcode-types'; -export * from '@ali/lowcode-designer'; -export * from '@ali/lowcode-editor-skeleton' diff --git a/packages/vision-polyfill/build.json b/packages/vision-polyfill/build.json deleted file mode 100644 index 27e93581d..000000000 --- a/packages/vision-polyfill/build.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "entry": { - "index": "src/demo/index.ts", - "react-simulator-renderer": "../react-simulator-renderer/src/index.ts", - "vision": "src/vision.ts" - }, - "vendor": false, - "devServer": { - "hot": false - }, - "publicPath": "/", - "externals": { - "react": "window.React", - "react-dom": "window.ReactDOM", - "prop-types": "window.PropTypes", - "@alifd/next": "window.Next", - "@ali/visualengine": "window.VisualEngine", - "@ali/visualengine-utils": "window.VisualEngineUtils" - }, - "plugins": [ - [ - "build-plugin-react-app" - ], - [ - "build-plugin-fusion", - { - "themePackage": "@alife/theme-lowcode-light" - } - ], - [ - "build-plugin-moment-locales", - { - "locales": [ - "zh-cn" - ] - } - ], - "./build.plugin.js" - ] -} diff --git a/packages/vision-polyfill/public/assets.json b/packages/vision-polyfill/public/assets.json deleted file mode 100644 index e1c39f88c..000000000 --- a/packages/vision-polyfill/public/assets.json +++ /dev/null @@ -1,1594 +0,0 @@ -{ - "version": "1.0.0", - "packages": [ - { - "package": "moment", - "urls": ["https://g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"], - "library": "moment" - }, - { - "title": "fusion组件库", - "package": "@alifd/next", - "version": "1.19.18", - "urls": ["https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.js", "https://unpkg.antfin-inc.com/@alife/next@1.19.18/dist/next.css"], - "library": "Next" - } - ], - "components": [ - { - "componentName": "Page", - "title": "页面", - "configure": { - "events": { - "supportedLifecycles": [{ - "description": "初始化时", - "name": "constructor" - }, { - "description": "装载后", - "name": "componentDidMount" - }, { - "description": "更新时", - "name": "componentDidMount" - }, { - "description": "卸载时", - "name": "componentWillUnmount" - }] - }, - "component": { - "isContainer": true - } - } - }, - { - "componentName": "Div", - "title": "容器", - "configure": { - "component": { - "isContainer": true - } - } - }, - { - "componentName": "Button", - "title": "按钮", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Button" - }, - "props": [{ - "name": "prefix", - "propType": "string", - "defaultValue": "next-" - }, { - "name": "rtl", - "propType": "bool" - }, { - "name": "type", - "propType": { - "type": "oneOf", - "value": ["primary", "secondary", "normal"] - }, - "description": "按钮的类型", - "defaultValue": "normal" - }, { - "name": "size", - "propType": { - "type": "oneOf", - "value": ["small", "medium", "large"] - }, - "description": "按钮的尺寸", - "defaultValue": "medium" - }, { - "name": "iconSize", - "propType": { - "type": "oneOf", - "value": ["xxs", "xs", "small", "medium", "large", "xl", "xxl", "xxxl"] - }, - "description": "按钮中 Icon 的尺寸,用于替代 Icon 的默认大小" - }, { - "name": "htmlType", - "propType": { - "type": "oneOf", - "value": ["submit", "reset", "button"] - }, - "description": "当 component = 'button' 时,设置 button 标签的 type 值", - "defaultValue": "button" - }, { - "name": "component", - "propType": { - "type": "oneOf", - "value": ["button", "a", "div", "span"] - }, - "description": "设置标签类型", - "defaultValue": "button" - }, { - "name": "loading", - "propType": "bool", - "description": "设置按钮的载入状态", - "defaultValue": false - }, { - "name": "ghost", - "propType": { - "type": "oneOf", - "value": [true, false, "light", "dark"] - }, - "description": "是否为幽灵按钮", - "defaultValue": false - }, { - "name": "text", - "propType": "bool", - "description": "是否为文本按钮", - "defaultValue": false - }, { - "name": "warning", - "propType": "bool", - "description": "是否为警告按钮", - "defaultValue": false - }, { - "name": "disabled", - "propType": "bool", - "description": "是否禁用", - "defaultValue": false - }, { - "name": "onClick", - "propType": "func", - "description": "点击按钮的回调\n@param {Object} e Event Object" - }, { - "name": "className", - "propType": "string" - }, { - "name": "onMouseUp", - "propType": "func" - }, { - "name": "children", - "propType": "node" - }] - }, - { - "componentName": "Button.Group", - "title": "按钮组", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Button", - "subName": "Group" - }, - "props": [{ - "name": "rtl", - "propType": "bool" - }, { - "name": "prefix", - "propType": "string", - "defaultValue": "next-" - }, { - "name": "size", - "propType": "string", - "description": "统一设置 Button 组件的按钮大小", - "defaultValue": "medium" - }, { - "name": "className", - "propType": "string" - }, { - "name": "children", - "propType": "node" - }], - "configure": { - "component": { - "isContainer": true, - "nestingRule": { - "childWhitelist": "Button" - } - } - } - }, - { - "componentName": "Input", - "title": "输入框", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Input" - }, - "props": [{ - "name": "label", - "propType": "node", - "description": "label" - }, { - "name": "hasClear", - "propType": "bool", - "description": "是否出现clear按钮" - }, { - "name": "hasBorder", - "propType": "bool", - "description": "是否有边框", - "defaultValue": "true" - }, { - "name": "state", - "propType": { - "type": "oneOf", - "value": ["error", "loading", "success", "warning"] - }, - "description": "状态\n@enumdesc 错误, 校验中, 成功, 警告" - }, { - "name": "size", - "propType": { - "type": "oneOf", - "value": ["small", "medium", "large"] - }, - "description": "尺寸\n@enumdesc 小, 中, 大", - "defaultValue": "medium" - }, { - "name": "onPressEnter", - "propType": "func", - "description": "按下回车的回调", - "defaultValue": "func.noop" - }, { - "name": "onClear", - "propType": "func" - }, { - "name": "htmlType", - "propType": "string", - "description": "原生type" - }, { - "name": "htmlSize", - "propType": "string" - }, { - "name": "hint", - "propType": "string", - "description": "水印 (Icon的type类型,和hasClear占用一个地方)" - }, { - "name": "innerBefore", - "propType": "node", - "description": "文字前附加内容" - }, { - "name": "innerAfter", - "propType": "node", - "description": "文字后附加内容" - }, { - "name": "addonBefore", - "propType": "node", - "description": "输入框前附加内容" - }, { - "name": "addonAfter", - "propType": "node", - "description": "输入框后附加内容" - }, { - "name": "addonTextBefore", - "propType": "node", - "description": "输入框前附加文字" - }, { - "name": "addonTextAfter", - "propType": "node", - "description": "输入框后附加文字" - }, { - "name": "autoComplete", - "propType": "string", - "description": "(原生input支持)", - "defaultValue": "off" - }, { - "name": "autoFocus", - "propType": "bool", - "description": "自动聚焦(原生input支持)" - }, { - "name": "inputRender", - "propType": "func", - "defaultValue": "el => el" - }, { - "name": "extra", - "propType": "node" - }, { - "name": "innerBeforeClassName", - "propType": "string" - }, { - "name": "innerAfterClassName", - "propType": "string" - }, { - "name": "isPreview", - "propType": "bool", - "description": "是否为预览态", - "defaultValue": "false" - }, { - "name": "renderPreview", - "propType": "func", - "description": "预览态模式下渲染的内容\n@param {number} value 评分值" - }] - }, - { - "componentName": "Form", - "title": "表单容器", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Form" - }, - "props": [{ - "name": "prefix", - "propType": "string", - "description": "样式前缀", - "defaultValue": "next-" - }, { - "name": "inline", - "propType": "bool", - "description": "内联表单" - }, { - "name": "size", - "propType": { - "type": "oneOf", - "value": ["large", "medium", "small"] - }, - "description": "单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。\n@enumdesc 大, 中, 小", - "defaultValue": "medium" - }, { - "name": "fullWidth", - "propType": "bool", - "description": "单个 Item 中表单类组件宽度是否是100%" - }, { - "name": "labelAlign", - "propType": { - "type": "oneOf", - "value": ["top", "left", "inset"] - }, - "description": "标签的位置\n@enumdesc 上, 左, 内", - "defaultValue": "left" - }, { - "name": "labelTextAlign", - "propType": { - "type": "oneOf", - "value": ["left", "right"] - }, - "description": "标签的左右对齐方式\n@enumdesc 左, 右" - }, { - "name": "field", - "propType": "any", - "description": "field 实例, 传 false 会禁用 field" - }, { - "name": "saveField", - "propType": "func", - "description": "保存 Form 自动生成的 field 对象" - }, { - "name": "labelCol", - "propType": "object", - "description": "控制第一级 Item 的 labelCol" - }, { - "name": "wrapperCol", - "propType": "object", - "description": "控制第一级 Item 的 wrapperCol" - }, { - "name": "onSubmit", - "propType": "func", - "description": "form内有 `htmlType=\"submit\"` 的元素的时候会触发" - }, { - "name": "children", - "propType": "any", - "description": "子元素" - }, { - "name": "className", - "propType": "string", - "description": "扩展class" - }, { - "name": "style", - "propType": "object", - "description": "自定义内联样式" - }, { - "name": "value", - "propType": "object", - "description": "表单数值" - }, { - "name": "onChange", - "propType": "func", - "description": "表单变化回调\n@param {Object} values 表单数据\n@param {Object} item 详细\n@param {String} item.name 变化的组件名\n@param {String} item.value 变化的数据\n@param {Object} item.field field 实例" - }, { - "name": "component", - "propType": { - "type": "oneOfType", - "value": ["string", "func"] - }, - "description": "设置标签类型", - "defaultValue": "form" - }, { - "name": "fieldOptions", - "propType": "object" - }, { - "name": "rtl", - "propType": "bool" - }, { - "name": "device", - "propType": { - "type": "oneOf", - "value": ["phone", "tablet", "desktop"] - }, - "description": "预设屏幕宽度", - "defaultValue": "desktop" - }, { - "name": "responsive", - "propType": "bool", - "description": "是否开启内置的响应式布局 (使用ResponsiveGrid)" - }, { - "name": "isPreview", - "propType": "bool", - "description": "是否开启预览态" - }], - "configure": { - "component": { - "isContainer": true - } - } - }, - { - "componentName": "Form.Item", - "title": "表单项", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Form", - "subName": "Item" - }, - "props": [{ - "name": "prefix", - "propType": "string", - "description": "样式前缀", - "defaultValue": "next-" - }, { - "name": "rtl", - "propType": "bool" - }, { - "name": "label", - "propType": "node", - "description": "label 标签的文本" - }, { - "name": "labelCol", - "propType": "object", - "description": "label 标签布局,通 `` 组件,设置 span offset 值,如 {span: 8, offset: 16},该项仅在垂直表单有效" - }, { - "name": "wrapperCol", - "propType": "object", - "description": "需要为输入控件设置布局样式时,使用该属性,用法同 labelCol" - }, { - "name": "help", - "propType": "node", - "description": "自定义提示信息,如不设置,则会根据校验规则自动生成." - }, { - "name": "extra", - "propType": "node", - "description": "额外的提示信息,和 help 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 位于错误信息后面" - }, { - "name": "validateState", - "propType": { - "type": "oneOf", - "value": ["error", "success", "loading", "warning"] - }, - "description": "校验状态,如不设置,则会根据校验规则自动生成\n@enumdesc 失败, 成功, 校验中, 警告" - }, { - "name": "hasFeedback", - "propType": "bool", - "description": "配合 validateState 属性使用,是否展示 success/loading 的校验状态图标, 目前只有Input支持", - "defaultValue": false - }, { - "name": "style", - "propType": "object", - "description": "自定义内联样式" - }, { - "name": "id", - "propType": "string" - }, { - "name": "children", - "propType": { - "type": "oneOfType", - "value": ["node", "func"] - }, - "description": "node 或者 function(values)" - }, { - "name": "size", - "propType": { - "type": "oneOf", - "value": ["large", "small", "medium"] - }, - "description": "单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。" - }, { - "name": "fullWidth", - "propType": "bool", - "description": "单个 Item 中表单类组件宽度是否是100%" - }, { - "name": "labelAlign", - "propType": { - "type": "oneOf", - "value": ["top", "left", "inset"] - }, - "description": "标签的位置\n@enumdesc 上, 左, 内" - }, { - "name": "labelTextAlign", - "propType": { - "type": "oneOf", - "value": ["left", "right"] - }, - "description": "标签的左右对齐方式\n@enumdesc 左, 右" - }, { - "name": "className", - "propType": "string", - "description": "扩展class" - }, { - "name": "required", - "propType": "bool", - "description": "[表单校验] 不能为空" - }, { - "name": "asterisk", - "propType": "bool", - "description": "required 的星号是否显示" - }, { - "name": "requiredMessage", - "propType": "string", - "description": "required 自定义错误信息" - }, { - "name": "requiredTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "required 自定义触发方式" - }, { - "name": "min", - "propType": "number", - "description": "[表单校验] 最小值" - }, { - "name": "max", - "propType": "number", - "description": "[表单校验] 最大值" - }, { - "name": "minmaxMessage", - "propType": "string", - "description": "min/max 自定义错误信息" - }, { - "name": "minmaxTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "min/max 自定义触发方式" - }, { - "name": "minLength", - "propType": "number", - "description": "[表单校验] 字符串最小长度 / 数组最小个数" - }, { - "name": "maxLength", - "propType": "number", - "description": "[表单校验] 字符串最大长度 / 数组最大个数" - }, { - "name": "minmaxLengthMessage", - "propType": "string", - "description": "minLength/maxLength 自定义错误信息" - }, { - "name": "minmaxLengthTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "minLength/maxLength 自定义触发方式" - }, { - "name": "length", - "propType": "number", - "description": "[表单校验] 字符串精确长度 / 数组精确个数" - }, { - "name": "lengthMessage", - "propType": "string", - "description": "length 自定义错误信息" - }, { - "name": "lengthTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "length 自定义触发方式" - }, { - "name": "pattern", - "propType": "any", - "description": "正则校验" - }, { - "name": "patternMessage", - "propType": "string", - "description": "pattern 自定义错误信息" - }, { - "name": "patternTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "pattern 自定义触发方式" - }, { - "name": "format", - "propType": { - "type": "oneOf", - "value": ["number", "email", "url", "tel"] - }, - "description": "[表单校验] 四种常用的 pattern" - }, { - "name": "formatMessage", - "propType": "string", - "description": "format 自定义错误信息" - }, { - "name": "formatTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "format 自定义触发方式" - }, { - "name": "validator", - "propType": "func", - "description": "[表单校验] 自定义校验函数" - }, { - "name": "validatorTrigger", - "propType": { - "type": "oneOfType", - "value": ["string", "array"] - }, - "description": "validator 自定义触发方式" - }, { - "name": "autoValidate", - "propType": "bool", - "description": "是否修改数据时自动触发校验" - }, { - "name": "device", - "propType": { - "type": "oneOf", - "value": ["phone", "tablet", "desktop"] - }, - "description": "预设屏幕宽度" - }, { - "name": "responsive", - "propType": "bool" - }, { - "name": "colSpan", - "propType": "number", - "description": "在响应式布局模式下,表单项占多少列" - }, { - "name": "labelWidth", - "propType": { - "type": "oneOfType", - "value": ["string", "number"] - }, - "description": "在响应式布局下,且label在左边时,label的宽度是多少", - "defaultValue": 100 - }, { - "name": "isPreview", - "propType": "bool", - "description": "是否开启预览态" - }, { - "name": "renderPreview", - "propType": "func", - "description": "预览态模式下渲染的内容\n@param {any} value 根据包裹的组件的 value 类型而决定" - }], - "configure": { - "component": { - "isContainer": true, - "nestingRule": { - "parentWhitelist": "Form" - } - } - } - }, - { - "componentName": "NumberPicker", - "title": "数字输入", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "NumberPicker" - }, - "props": [{ - "name": "prefix", - "propType": "string", - "description": "样式前缀", - "defaultValue": "next-" - }, { - "name": "type", - "propType": { - "type": "oneOf", - "value": ["normal", "inline"] - }, - "description": "设置类型\n@enumdesc 普通, 内联", - "defaultValue": "normal" - }, { - "name": "size", - "propType": { - "type": "oneOf", - "value": ["large", "medium"] - }, - "description": "大小", - "defaultValue": "medium" - }, { - "name": "value", - "propType": "number", - "description": "当前值" - }, { - "name": "defaultValue", - "propType": "number", - "description": "默认值" - }, { - "name": "disabled", - "propType": "bool", - "description": "是否禁用" - }, { - "name": "step", - "propType": { - "type": "oneOfType", - "value": ["number", "string"] - }, - "description": "步长", - "defaultValue": 1 - }, { - "name": "precision", - "propType": "number", - "description": "保留小数点后位数", - "defaultValue": 0 - }, { - "name": "editable", - "propType": "bool", - "description": "用户是否可以输入", - "defaultValue": true - }, { - "name": "autoFocus", - "propType": "bool", - "description": "自动焦点" - }, { - "name": "onChange", - "propType": "func", - "description": "数值被改变的事件\n@param {Number} value 数据\n@param {Event} e DOM事件对象" - }, { - "name": "onKeyDown", - "propType": "func", - "description": "键盘按下" - }, { - "name": "onFocus", - "propType": "func", - "description": "焦点获得" - }, { - "name": "onBlur", - "propType": "func", - "description": "焦点失去" - }, { - "name": "onCorrect", - "propType": "func", - "description": "数值订正后的回调\n@param {Object} obj {currentValue,oldValue:String}" - }, { - "name": "onDisabled", - "propType": "func" - }, { - "name": "max", - "propType": "number", - "description": "最大值", - "defaultValue": null - }, { - "name": "min", - "propType": "number", - "description": "最小值", - "defaultValue": null - }, { - "name": "className", - "propType": "string", - "description": "自定义class" - }, { - "name": "style", - "propType": "object", - "description": "自定义内联样式" - }, { - "name": "state", - "propType": { - "type": "oneOf", - "value": ["error"] - } - }, { - "name": "format", - "propType": "func", - "description": "格式化当前值\n@param {Number} value\n@return {String|Number}" - }, { - "name": "upBtnProps", - "propType": "object", - "description": "增加按钮的props" - }, { - "name": "downBtnProps", - "propType": "object", - "description": "减少按钮的props" - }, { - "name": "label", - "propType": "node", - "description": "内联 label" - }, { - "name": "innerAfter", - "propType": "node", - "description": "inner after" - }, { - "name": "rtl", - "propType": "bool" - }, { - "name": "isPreview", - "propType": "bool", - "description": "是否为预览态" - }, { - "name": "renderPreview", - "propType": "func", - "description": "预览态模式下渲染的内容\n@param {number} value 评分值" - }, { - "name": "device", - "propType": { - "type": "oneOf", - "value": ["phone", "tablet", "desktop"] - }, - "description": "预设屏幕宽度" - }] - }, - { - "componentName": "Select", - "title": "下拉", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Select" - }, - "props": [{ - "name": "mode", - "propType": { - "type": "oneOf", - "value": ["single", "multiple", "tag"] - }, - "description": "选择器模式", - "defaultValue": "single" - }, { - "name": "value", - "propType": "any", - "description": "当前值,用于受控模式" - }, { - "name": "defaultValue", - "propType": "any", - "description": "初始的默认值" - }, { - "name": "onChange", - "propType": "func", - "description": "Select发生改变时触发的回调\n@param {*} value 选中的值\n@param {String} actionType 触发的方式, 'itemClick', 'enter', 'tag'\n@param {*} item 选中的值的对象数据 (useDetailValue=false有效)" - }, { - "name": "dataSource", - "propType": { - "type": "arrayOf", - "value": { - "type": "oneOfType", - "value": [{ - "type": "shape", - "value": [{ - "name": "value", - "propType": "any" - }, { - "name": "label", - "propType": "any" - }, { - "name": "disabled", - "propType": "bool" - }, { - "name": "children", - "propType": "array" - }] - }, "bool", "number", "string"] - } - }, - "description": "传入的数据源,可以动态渲染子项,详见 [dataSource的使用](#dataSource的使用)" - }, { - "name": "hasBorder", - "propType": "bool", - "description": "是否有边框" - }, { - "name": "hasArrow", - "propType": "bool", - "description": "是否有下拉箭头", - "defaultValue": true - }, { - "name": "showSearch", - "propType": "bool", - "description": "展开后是否能搜索(tag 模式下固定为true)", - "defaultValue": false - }, { - "name": "onSearch", - "propType": "func", - "description": "当搜索框值变化时回调\n@param {String} value 数据" - }, { - "name": "onSearchClear", - "propType": "func", - "description": "当搜索框值被清空时候的回调\n@param {String} actionType 触发的方式, 'select'(选择清空), 'popupClose'(弹窗关闭清空)" - }, { - "name": "hasSelectAll", - "propType": { - "type": "oneOfType", - "value": ["bool", "string"] - }, - "description": "多选模式下是否有全选功能" - }, { - "name": "fillProps", - "propType": "string", - "description": "填充到选择框里的值的 key\b\b" - }, { - "name": "useDetailValue", - "propType": "bool", - "description": "onChange 返回的 value 使用 dataSource 的对象" - }, { - "name": "cacheValue", - "propType": "bool", - "description": "dataSource 变化的时是否保留已选的内容", - "defaultValue": true - }, { - "name": "valueRender", - "propType": "func", - "description": "渲染 Select 展现内容的方法\n@param {Object} item 渲染节点的item\n@return {ReactNode} 展现内容\n@default item => item.label \\|\\| item.value" - }, { - "name": "itemRender", - "propType": "func", - "description": "渲染 MenuItem 内容的方法\n@param {Object} item 渲染节点的item\n@param {String} searchValue 搜索关键字(如果开启搜索)\n@return {ReactNode} item node" - }, { - "name": "notFoundContent", - "propType": "node", - "description": "弹层内容为空的文案" - }, { - "name": "style", - "propType": "object" - }, { - "name": "searchValue", - "propType": "string", - "description": "受控搜索值,一般不需要设置\n@type {[type]}" - }, { - "name": "tagInline", - "propType": "bool", - "description": "是否一行显示,仅在 mode 为 multiple 的时候生效", - "defaultValue": false - }, { - "name": "maxTagCount", - "propType": "number", - "description": "最多显示多少个 tag" - }, { - "name": "maxTagPlaceholder", - "propType": "func", - "description": "隐藏多余 tag 时显示的内容,在 maxTagCount 生效时起作用\n@param {number} selectedValues 当前已选中的元素\n@param {number} totalValues 总待选元素" - }, { - "name": "hiddenSelected", - "propType": "bool", - "description": "选择后是否立即隐藏菜单 (mode=multiple/tag 模式生效)" - }, { - "name": "onRemove", - "propType": "func", - "description": "tag 删除回调\n@param {object} item 渲染节点的item" - }, { - "name": "onFocus", - "propType": "func", - "description": "焦点事件" - }, { - "name": "onBlur", - "propType": "func", - "description": "失去焦点事件" - }, { - "name": "onMouseEnter", - "propType": "func" - }, { - "name": "onMouseLeave", - "propType": "func" - }, { - "name": "onKeyDown", - "propType": "func" - }, { - "name": "locale", - "propType": "object" - }], - "configure": { - "component": { - "isContainer": true, - "nestingRule": { - "childWhitelist": "Select.Option" - } - }, - "props": [{ - "name": "mode", - "title": "选择器模式", - "setter": { - "componentName": "RadioGroupSetter", - "props": { - "defaultValue": "single", - "dataSource": [{ - "value": "single", - "label": "single" - }, { - "value": "multiple", - "label": "multiple" - }, { - "value": "tag", - "label": "tag" - }] - } - } - }, { - "name": "mode", - "title": "选择器模式", - "setter": { - "componentName": "SelectSetter", - "props": { - "defaultValue": "single", - "dataSource": [{ - "value": "single", - "label": "single" - }, { - "value": "multiple", - "label": "multiple" - }, { - "value": "tag", - "label": "tag" - }] - } - } - }, { - "name": "value", - "title": "受控值", - "setter": "StringSetter" - }, { - "name": "hasBorder", - "title": "是否有边框", - "setter": { - "componentName": "BoolSetter", - "props": { - "defaultValue": true - } - } - }, { - "name": "maxTagCount", - "title": "最多显示多少个 tag", - "setter": "NumberSetter" - }, { - "name": "maxTagCount", - "title": "最多显示多少个 tag", - "setter": "ExpressionSetter" - }, { - "name": "MixinSetter", - "placeholder": "混合", - "setter": { - "componentName": "MixinSetter", - "props": { - "types": [{ - "name": "StringSetter", - "props": {} - }, { - "name": "TextAreaSetter", - "props": {} - }, { - "name": "SelectSetter", - "props": { - "hasClear": true, - "dataSource": [{ - "label": "上", - "value": "t" - }, { - "label": "右", - "value": "r" - }, { - "label": "下", - "value": "b" - }, { - "label": "左", - "value": "l" - }] - } - }, { - "name": "NumberSetter", - "props": {} - }, { - "name": "BoolSetter", - "props": {} - }], - "defaultType": "SelectSetter" - } - } - }, { - "type": "group", - "name": "扩展 Setter", - "items": [{ - "name": "TextAreaSetter", - "setter": "TextAreaSetter" - }, { - "name": "date", - "title": "测试日期", - "setter": "DateSetter" - }, { - "name": "date", - "title": "测试日期-年", - "setter": "DateYearSetter" - }, { - "name": "date", - "title": "测试日期-月", - "setter": "DateMonthSetter" - }, { - "name": "date", - "title": "测试日期-区间", - "setter": "DateRangeSetter" - }] - }, { - "type": "group", - "name": "ArraySetter", - "items": [{ - "name": "arrayValue1", - "title": "字符数组", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": { - "componentName": "StringSetter", - "initialValue": "" - } - } - } - }, { - "name": "arrayValue2", - "title": "数字数组", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": { - "componentName": "NumberSetter", - "initialValue": 0 - } - } - } - }, { - "name": "arrayValue3", - "title": "混合数组", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": { - "componentName": "MixinSetter", - "props": { - "types": [{ - "name": "StringSetter", - "props": {} - }, { - "name": "ExpressionSetter", - "props": {} - }, { - "name": "RadioGroupSetter", - "props": { - "hasClear": true, - "dataSource": [{ - "label": "上", - "value": "t" - }, { - "label": "右", - "value": "r" - }, { - "label": "下", - "value": "b" - }, { - "label": "左", - "value": "l" - }] - } - }], - "defaultType": "SelectSetter" - } - } - } - } - }, { - "name": "arrayValue4", - "title": "对象数组", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": { - "componentName": "ObjectSetter", - "props": { - "config": { - "items": [{ - "name": "username", - "title": "姓名", - "setter": "StringSetter", - "important": true - }, { - "name": "phone", - "title": "电话", - "setter": "StringSetter", - "important": true - }, { - "name": "age", - "title": "年龄", - "setter": "NumberSetter" - }, { - "name": "married", - "title": "婚否", - "setter": "BoolSetter" - }, { - "type": "group", - "title": "work", - "items": [{ - "name": "job", - "title": "工作岗位", - "setter": { - "componentName": "SelectSetter", - "props": { - "dataSource": [{ - "label": "工程师", - "value": 1 - }, { - "label": "高级工程师", - "value": 2 - }, { - "label": "资深工程师", - "value": 3 - }] - } - } - }, { - "name": "address", - "title": "工作地点", - "setter": "TextAreaSetter" - }] - }] - } - }, - "initialValue": {} - } - } - } - }, { - "name": "arrayValue5", - "title": "对象数组", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": { - "componentName": "ObjectSetter", - "props": { - "config": { - "items": [{ - "name": "username", - "title": "姓名", - "setter": "StringSetter", - "important": true - }, { - "name": "age", - "title": "年龄", - "setter": "NumberSetter", - "important": true - }, { - "name": "married", - "title": "婚否", - "setter": "BoolSetter", - "important": true - }, { - "name": "log", - "title": "到访记录", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": "StringSetter" - } - }, - "important": true - }, { - "type": "group", - "title": "work", - "items": [{ - "name": "job", - "title": "工作岗位", - "setter": { - "componentName": "SelectSetter", - "props": { - "dataSource": [{ - "label": "工程师", - "value": 1 - }, { - "label": "高级工程师", - "value": 2 - }, { - "label": "资深工程师", - "value": 3 - }] - } - } - }, { - "name": "address", - "title": "工作地点", - "setter": "TextAreaSetter" - }] - }] - } - }, - "initialValue": {} - }, - "mode": "popup" - } - } - }], - "extraProps": { - "defaultCollapsed": false - } - }, { - "type": "group", - "name": "ObjectSetter", - "items": [{ - "name": "objectValue1", - "title": "对象数据1", - "setter": { - "componentName": "ObjectSetter", - "props": { - "config": { - "items": [{ - "name": "username", - "title": "姓名", - "setter": "StringSetter", - "important": true - }, { - "name": "age", - "title": "年龄", - "setter": "NumberSetter", - "important": true - }, { - "name": "married", - "title": "婚否", - "setter": "BoolSetter", - "important": true - }, { - "name": "log", - "title": "到访记录", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": "StringSetter" - } - }, - "important": true - }, { - "type": "group", - "title": "work", - "items": [{ - "name": "job", - "title": "工作岗位", - "setter": { - "componentName": "SelectSetter", - "props": { - "dataSource": [{ - "label": "工程师", - "value": 1 - }, { - "label": "高级工程师", - "value": 2 - }, { - "label": "资深工程师", - "value": 3 - }] - } - } - }, { - "name": "address", - "title": "工作地点", - "setter": "TextAreaSetter" - }] - }] - } - }, - "initialValue": {} - } - }, { - "name": "objectValue2", - "title": "对象数据2", - "setter": { - "componentName": "ObjectSetter", - "props": { - "mode": "popup", - "config": { - "items": [{ - "name": "username", - "title": "姓名", - "setter": "StringSetter", - "important": true - }, { - "name": "age", - "title": "年龄", - "setter": "NumberSetter", - "important": true - }, { - "name": "married", - "title": "婚否", - "setter": "BoolSetter", - "important": true - }, { - "name": "log", - "title": "到访记录", - "setter": { - "componentName": "ArraySetter", - "props": { - "itemSetter": "StringSetter" - } - }, - "important": true - }, { - "type": "group", - "title": "work", - "items": [{ - "name": "job", - "title": "工作岗位", - "setter": { - "componentName": "SelectSetter", - "props": { - "dataSource": [{ - "label": "工程师", - "value": 1 - }, { - "label": "高级工程师", - "value": 2 - }, { - "label": "资深工程师", - "value": 3 - }] - } - } - }, { - "name": "address", - "title": "工作地点", - "setter": "TextAreaSetter" - }] - }] - } - }, - "initialValue": {} - } - }] - }] - } - }, - { - "componentName": "Select.Option", - "title": "选择项", - "devMode": "proCode", - "npm": { - "package": "@alifd/next", - "version": "1.19.18", - "destructuring": true, - "exportName": "Select", - "subName": "Option" - }, - "props": [{ - "name": "value", - "propType": { - "type": "any", - "isRequired": true - }, - "description": "选项值" - }, { - "name": "disabled", - "propType": "bool", - "description": "是否禁用" - }, { - "name": "children", - "propType": "any" - }], - "configure": { - "component": { - "isContainer": true, - "nestingRule": { - "parentWhitelist": "Select" - } - } - } - } - ], - "componentList": [{ - "title": "基础", - "icon": "", - "children": [{ - "componentName": "Button", - "title": "按钮", - "icon": "", - "package": "@alife/next", - "library": "Next", - "snippets": [{ - "title": "private", - "screenshot": "https://img.alicdn.com/tfs/TB16gZhi.H1gK0jSZSyXXXtlpXa-192-144.png", - "schema": { - "componentName": "Button", - "props": { - "type": "primary" - }, - "children": "Primary" - } - }, { - "title": "secondary", - "screenshot": "https://img.alicdn.com/tfs/TB11Hkji1H2gK0jSZFEXXcqMpXa-192-144.png", - "schema": { - "componentName": "Button", - "props": { - "type": "secondary" - }, - "children": "secondary" - } - }, { - "title": "normal", - "screenshot": "", - "schema": { - "componentName": "Button", - "props": { - "type": "normal" - }, - "children": "normal" - } - }] - }] - }, { - "title": "表单", - "icon": "", - "children": [{ - "componentName": "Input", - "library": "Next", - "title": "输入框", - "icon": "", - "package": "@alife/next", - "snippets": [{ - "title": "普通", - "screenshot": "", - "schema": { - "componentName": "Input", - "props": {} - } - }] - }, { - "componentName": "Select", - "library": "Next", - "title": "选择框", - "icon": "", - "package": "@alife/next", - "snippets": [{ - "title": "默认", - "screenshot": "", - "schema": { - "componentName": "Select", - "props": {} - } - }] - }, { - "componentName": "NumberPicker", - "library": "Next", - "title": "数字", - "icon": "", - "package": "@alife/next", - "snippets": [{ - "title": "默认", - "screenshot": "", - "schema": { - "componentName": "NumberPicker", - "props": {} - } - }] - }] - }, { - "title": "其他", - "icon": "", - "children": [{ - "componentName": "Div", - "library": "Next", - "title": "容器", - "icon": "", - "snippets": [{ - "title": "默认", - "screenshot": "", - "schema": { - "componentName": "Div", - "props": {} - } - }] - }] - }] -} diff --git a/packages/vision-polyfill/public/favicon.png b/packages/vision-polyfill/public/favicon.png deleted file mode 100644 index 307ffbd82dba398d6db6459102bff331eef7df6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3612 zcmV+%4&(8OP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91TA%{}1ONa40RR91S^xk507-m{w*UYQhDk(0RCodHT?>#D#Towp*}H|i z+dTn!mde8i1wu-BR8XSvS)#mzvO>hDgg^x>qli)9_Kq+LcPJ3Bu+SK-ynID85>dgJ zf)ItMP%%POG)f4F%3HbJz2lbM?R>q<9(%hpvoo`^$1F!z?agfW|Ns5>H@$y%|NT!N z)9I8O0kys}9V_WeB7QCjaV`-)%ss()2JZ3U%EY}OCKh25^exJF;@jsa+eD=m&vNcs z+8Bi@I#8tHdjNF^fEtX}4+gmB!oBs2;z-h|Ic09)=5q&i}FecJ(A2&TE=5fm5G(0gxyZEdH6iu2h_ zJ5PO}Rndte;mJhtI{@%`&ZB5b;y0%*&~w8>C>pyHqyEk4y=A80C>Rkpo_d2}APn0Z z`vpM$ZW1@AMzs8%!l?uF-0&cZ#+Q(YU7a5!1>j~nT>L<*4QEp%S__bGgNbmbDHL?D zc!5q%(PmRq>|XRi*kE^<2+iLE7c0;;;j#2>=t+RvRkLC4%RE$EJ$gCjzI#K9DHglS zeOMZ5R79pjJ=zx_zkpTT#fD9CW1*mZ$u+$jl}p#DIy8xzBJUR^$g&*@ZFlD=odQ`E zK8ge%$2fOuDyulJJixs`2f{tzOEWnqjtV>cMgWq9ydk)0#$pb)OGC2 zyd5S;I^_@Jm(l@C^gfV%VZr9$OrMgxyy6}LKnkatcPA59cwD{W7OGqAKlB1Ib~J_y8w|V z(BsGFq%}`aO$#gQ+ynI7-~fuz1~k&So~-aRs`dZcJSL!&e(UPcGF)d^;?pO-3_x#k z&U92aoJAbJ4vzIcP_j3Es=aY-kL$P40h^Wh2!VU$OZ3`ZRN~o1W#zjmz=tRh9t>Z_ z>u9BOATvK;8Dt3-vw)s60d`MZ^Xu76A?oGdoDeJj*iI_;)*=lf;8d5p7NY@_$GR+x z$|Opy^BHmQR*dw6F$l$ts0_#@IJscGzkIqrLKORm9_ zztJAZQU#|$hDhewd4Vj|Qn?=J)XH1ii4{5CB$7R#tLn#5{1{ehG&Cj1HCN`ZskY)x zNAxN6{RU61$+j$o*QI!^104v>1oNuo95f}yRoB%CJL`l>Du*EE@3urSA0SWp))cQb zpaUV;W3eQ~?9yvu-s+fcEdFg%)=TN;%RJEP(ep7|cpmoHJdaHc^I{X?i@f-=n3a85 zS!ObXcs`xX9B8WWV&(KQ7(1pjyYk-Su|Lz$YLKuK|G|5x&c88ToH?K)p(>b+@1!%j z_FlxhJE|Mg*_P$8cp-C~$PIK&us+@u)9l)7QFbbQk(&@iM-USUU$Y~z z(@$d;<#r>8PM8k)(u@$+wtb8wySYs6ehcd55XeDd&+J^yJpuH=@H`NopNrvic?JTk z%%{4FuQPJ9z9#3<~?2N zQD&F{Spucd2jL%~HxD_DnneVdUZn+?!I(_2(c-5jX-|`-5MaW_ZRw2ES2I@$^hIU} zPt&9!Ab1KbDBGEqlk--=G$*Ga&ncx%5%6+a=zqy-ljZbolU1fROV6|!fjRfvX}^Nu z@L{+EUHnRuon{q;=NsbE3E0_=*pZG{oXU-`)6=llkJ=H?Hh9nx70)E9E!$9Bm&2;z=LrvB2-VO*34&C5jyZdzE$Q1+DZ*F{8q%WHYTlza1|{p z3#rcMNCdzMr;-yb^p<}J(-U(-)Jd1Yw9F}xWm}vDT8_vpcAs>R@>M{-j!{=>V+UNn zVrPL))WiSMudWD6n4hCs-_M-Zv;aWkJ(QwNa!bm0M`k#e6V0&4E`?wy@F}co(!2pRl&bu%6DZ}elcXU z^H%`u2B%du)uRQi#7jV-XHofakfj=lqa){QDx`?zn)$_$8ExuO2sLv8odkKy)2Muc zh61+;3S=u*Te%7gns+tm-Jc~Q+3j&aYeS%6E>OPZcj&znwd;~mrcoSurjb0#beNV# zjS_cf#o5{T>f^1|1v&|G__qN0R%2wubU{nYvS{Y}wjy8!zLO$LOs&_W@#-iBNjdNd z!=R8PgyKx1y^}TJto1#OsgewqES|*FIz2iG@+=uhqYa)GWL@?y6rHA?tyM(5eDZa< z)tY5)%#4e|_vqswBO+2vHHATkZ-{QjI63hTl{9Gc22CCr^HAp>2Q%_uQOvKIr6P=(QnL6x-x1jUm>r*5A3!InnSvDC$&IC3sHSD&_svj zDiL7kND|}`YvA{bXA_n;Fb)03O40qti8uPQ36P`m;e;c-lfM@>4ekNxZ@Ft4h+{1Z zkR-UxNzkkXI1-||IV1Dtyw7lcIL0+t0>iZDoEWVeGm?)y_NF0Ss_+S%aImLwFm`W- zvlo+-HX+xPp1~GY%sTSVjPcA0FY%XasxeJ z+g%C3?6$dG6VY{R+ta|UnEHkH2)ciBY>OL-nU?~%Wok1G@Miq5B zX!tM;xRXV3u)lsIQP7`8D&!!057B-MzI1n5!HHWOZjB(G)=BcT#g0BK)(V%5f$q6; zN?uhU&G{i*9dOdD*b1ju;#cE<$< z0&o(5UJ~32rh|9mS92|??LXI3!>N2-psAr`9xBN>{nJ$BSSisfSc&gAU$gjlCVU?4 z^nb1jOh-WzZ-Drrg|y4*>g$`1PKQRN6PmscV+Qx?c$nXA1}q$ejlP~~!A@NwdCFEn z5>6gaxCa0FZYkUW8h(U=RH{7~iaSfbPo4%KW-;xD&-^tEe4+G#FH1%UIX5sZc_*tR zJtJNK)4}{cdFXbU@6$I~={h)guWdTQzH2Sj!4xH-JVGx{jO73sD=r?%w0Kia`Dd0n zXF6o;xAb9neZy$JztusOZPfZV8PepGabK+9{gy0CdE9B`g}50qGU8c zep{a=tt5F2F&<2wNgmA2%B2ZM5f04GQ<`mdZ5!P=@-pr7?xNC2uNIPV!V&#`cUPJHzcr5%K8(PTA^(8r%Hd@r^OOPu)!m&GEUkz-rMJJ8ESi2>fK*KG6 zRLqJD$JrH+K=37)0&Pd%UrnU|cQL`MrkCJrPI~*&2xKGqMnp8NOUpEOo0#H>mJizu zC-Wz8NKKXJHk%=D4H`|LWyQRRzQSdKMJ3jP{?0TWI67!NK>ll5p7~oAU*RDSG0l*$ z#k7dJ`5x3ea>ukRhY59owpUNZ985VX!Fvln*d zf&lGk3j)CjFdxqWOzD7XnV2`?o$RT!p#7&U3*7h3{Xk31 { + onGetWebpackConfig((config) => { + config.resolve + .plugin('tsconfigpaths') + .use(TsconfigPathsPlugin, [{ + configFile: "./tsconfig.json" + }]); + + config + // 定义插件名称 + .plugin('MonacoWebpackPlugin') + // 第一项为具体插件,第二项为插件参数 + .use(new MonacoWebpackPlugin({ + languages:["javascript","css","json"] + }), []); + config.plugins.delete('hot'); + config.devServer.hot(false); + }); +}; diff --git a/packages/vision-polyfill/package.json b/packages/vision-preset/package.json similarity index 80% rename from packages/vision-polyfill/package.json rename to packages/vision-preset/package.json index 569c60e6d..37483f394 100644 --- a/packages/vision-polyfill/package.json +++ b/packages/vision-preset/package.json @@ -1,23 +1,21 @@ { - "name": "@ali/lowcode-vision-polyfill", - "private": true, - "version": "0.8.2", + "name": "@ali/lowcode-vision-preset", + "version": "0.8.0", "description": "Vision Polyfill for Ali lowCode engine", "main": "lib/index.js", "files": [ "dist" ], "scripts": { - "start": "build-scripts start" + "build": "build-scripts build --skip-demo", + "cloud-build": "build-scripts build --skip-demo" }, "license": "MIT", "dependencies": { "@ali/lowcode-editor-core": "^0.8.6", "@ali/lowcode-editor-skeleton": "^0.8.7", - "@ali/lowcode-plugin-components-pane": "^0.8.5", "@ali/lowcode-plugin-designer": "^0.9.3", "@ali/lowcode-plugin-outline-pane": "^0.8.9", - "@ali/lowcode-plugin-settings-pane": "^0.8.10", "@ali/lowcode-plugin-undo-redo": "^0.8.6", "@ali/lowcode-plugin-zh-en": "^0.8.8", "@ali/lowcode-setters": "^0.8.8", @@ -33,18 +31,20 @@ "@alifd/next": "^1.19.12", "@alife/theme-lowcode-dark": "^0.1.0", "@alife/theme-lowcode-light": "^0.1.0", + "domready": "^1.0.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", + "@types/domready": "^1.0.0", "@types/events": "^3.0.0", "@types/react": "^16.8.3", "@types/react-dom": "^16.8.2", "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0", "build-plugin-react-app": "^1.1.2", - "tsconfig-paths-webpack-plugin": "^3.2.0", - "monaco-editor-webpack-plugin":"^1.9.0" + "monaco-editor-webpack-plugin": "^1.9.0", + "tsconfig-paths-webpack-plugin": "^3.2.0" } } diff --git a/packages/vision-polyfill/src/bak/vision copy.ts b/packages/vision-preset/src/bak/vision copy.ts.bak similarity index 100% rename from packages/vision-polyfill/src/bak/vision copy.ts rename to packages/vision-preset/src/bak/vision copy.ts.bak diff --git a/packages/vision-polyfill/src/base/base.ts b/packages/vision-preset/src/base/base.ts similarity index 100% rename from packages/vision-polyfill/src/base/base.ts rename to packages/vision-preset/src/base/base.ts diff --git a/packages/vision-polyfill/src/base/const.ts b/packages/vision-preset/src/base/const.ts similarity index 100% rename from packages/vision-polyfill/src/base/const.ts rename to packages/vision-preset/src/base/const.ts diff --git a/packages/vision-polyfill/src/base/schemaManager.ts b/packages/vision-preset/src/base/schemaManager.ts similarity index 100% rename from packages/vision-polyfill/src/base/schemaManager.ts rename to packages/vision-preset/src/base/schemaManager.ts diff --git a/packages/vision-polyfill/src/base/visualDesigner.ts b/packages/vision-preset/src/base/visualDesigner.ts similarity index 100% rename from packages/vision-polyfill/src/base/visualDesigner.ts rename to packages/vision-preset/src/base/visualDesigner.ts diff --git a/packages/vision-polyfill/src/base/visualManager.ts b/packages/vision-preset/src/base/visualManager.ts similarity index 100% rename from packages/vision-polyfill/src/base/visualManager.ts rename to packages/vision-preset/src/base/visualManager.ts diff --git a/packages/vision-polyfill/src/base/visualRender.ts b/packages/vision-preset/src/base/visualRender.ts similarity index 100% rename from packages/vision-polyfill/src/base/visualRender.ts rename to packages/vision-preset/src/base/visualRender.ts diff --git a/packages/vision-polyfill/src/bundle/bundle.ts b/packages/vision-preset/src/bundle/bundle.ts similarity index 100% rename from packages/vision-polyfill/src/bundle/bundle.ts rename to packages/vision-preset/src/bundle/bundle.ts diff --git a/packages/vision-polyfill/src/bundle/prototype.ts b/packages/vision-preset/src/bundle/prototype.ts similarity index 100% rename from packages/vision-polyfill/src/bundle/prototype.ts rename to packages/vision-preset/src/bundle/prototype.ts diff --git a/packages/vision-polyfill/src/bundle/trunk.ts b/packages/vision-preset/src/bundle/trunk.ts similarity index 100% rename from packages/vision-polyfill/src/bundle/trunk.ts rename to packages/vision-preset/src/bundle/trunk.ts diff --git a/packages/vision-polyfill/src/bundle/upgrade-metadata.ts b/packages/vision-preset/src/bundle/upgrade-metadata.ts similarity index 100% rename from packages/vision-polyfill/src/bundle/upgrade-metadata.ts rename to packages/vision-preset/src/bundle/upgrade-metadata.ts diff --git a/packages/vision-polyfill/src/bus.ts b/packages/vision-preset/src/bus.ts similarity index 100% rename from packages/vision-polyfill/src/bus.ts rename to packages/vision-preset/src/bus.ts diff --git a/packages/vision-polyfill/src/const.ts b/packages/vision-preset/src/const.ts similarity index 100% rename from packages/vision-polyfill/src/const.ts rename to packages/vision-preset/src/const.ts diff --git a/packages/vision-polyfill/src/context.ts b/packages/vision-preset/src/context.ts similarity index 100% rename from packages/vision-polyfill/src/context.ts rename to packages/vision-preset/src/context.ts diff --git a/packages/vision-polyfill/src/drag-engine.ts b/packages/vision-preset/src/drag-engine.ts similarity index 100% rename from packages/vision-polyfill/src/drag-engine.ts rename to packages/vision-preset/src/drag-engine.ts diff --git a/packages/vision-polyfill/src/editor.ts b/packages/vision-preset/src/editor.ts similarity index 97% rename from packages/vision-polyfill/src/editor.ts rename to packages/vision-preset/src/editor.ts index c4f8922d2..3c91fed94 100644 --- a/packages/vision-polyfill/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -7,11 +7,13 @@ import Outline from '@ali/lowcode-plugin-outline-pane'; import DesignerPlugin from '@ali/lowcode-plugin-designer'; import { Skeleton, SettingsPrimaryPane } from '@ali/lowcode-editor-skeleton'; - import Preview from '@ali/lowcode-plugin-sample-preview'; import SourceEditor from '@ali/lowcode-plugin-source-editor'; import { i18nReducer } from './i18n-reducer'; +export * from '@ali/lowcode-editor-core'; +export * from '@ali/lowcode-designer'; + registerSetters(); export const editor = new Editor(); diff --git a/packages/vision-polyfill/src/env.ts b/packages/vision-preset/src/env.ts similarity index 100% rename from packages/vision-polyfill/src/env.ts rename to packages/vision-preset/src/env.ts diff --git a/packages/vision-polyfill/src/exchange.ts b/packages/vision-preset/src/exchange.ts similarity index 100% rename from packages/vision-polyfill/src/exchange.ts rename to packages/vision-preset/src/exchange.ts diff --git a/packages/vision-polyfill/src/field.tsx b/packages/vision-preset/src/field.tsx similarity index 100% rename from packages/vision-polyfill/src/field.tsx rename to packages/vision-preset/src/field.tsx diff --git a/packages/vision-polyfill/src/flags.ts b/packages/vision-preset/src/flags.ts similarity index 97% rename from packages/vision-polyfill/src/flags.ts rename to packages/vision-preset/src/flags.ts index b9921ece6..f89478d80 100644 --- a/packages/vision-polyfill/src/flags.ts +++ b/packages/vision-preset/src/flags.ts @@ -1,5 +1,6 @@ -import domReady = require('domready'); -import * as EventEmitter from 'events'; +import domReady from 'domready'; + +import { EventEmitter } from 'events'; const Shells = ['iphone6']; diff --git a/packages/vision-polyfill/src/i18n-reducer.ts b/packages/vision-preset/src/i18n-reducer.ts similarity index 100% rename from packages/vision-polyfill/src/i18n-reducer.ts rename to packages/vision-preset/src/i18n-reducer.ts diff --git a/packages/vision-polyfill/src/vision.ts b/packages/vision-preset/src/index.ts similarity index 90% rename from packages/vision-polyfill/src/vision.ts rename to packages/vision-preset/src/index.ts index 969228f67..639a5a51f 100644 --- a/packages/vision-polyfill/src/vision.ts +++ b/packages/vision-preset/src/index.ts @@ -7,7 +7,7 @@ import { hotkey as Hotkey } from '@ali/lowcode-editor-core'; import { createElement } from 'react'; import { VE_EVENTS as EVENTS, VE_HOOKS as HOOKS } from './const'; import Bus from './bus'; -import { skeleton, editor } from './editor'; +import { skeleton } from './editor'; import { Workbench } from '@ali/lowcode-editor-skeleton'; import Panes from './panes'; import Exchange from './exchange'; @@ -20,10 +20,10 @@ import Pages from './pages'; import Field from './field'; import Prop from './prop'; import Env from './env'; -import './vision.less'; import DragEngine from './drag-engine'; -import * as EditorCore from '@ali/lowcode-editor-core'; -import * as Designer from '@ali/lowcode-designer'; +export * from './editor'; + +import './vision.less'; function init(container?: Element) { if (!container) { @@ -61,10 +61,6 @@ const modules = { const context = new VisualEngineContext(); const VisualEngine = { - EditorCore, - Designer, - editor, - skeleton, /** * VE.Popup */ diff --git a/packages/vision-polyfill/src/pages.ts b/packages/vision-preset/src/pages.ts similarity index 100% rename from packages/vision-polyfill/src/pages.ts rename to packages/vision-preset/src/pages.ts diff --git a/packages/vision-polyfill/src/panes.ts b/packages/vision-preset/src/panes.ts similarity index 100% rename from packages/vision-polyfill/src/panes.ts rename to packages/vision-preset/src/panes.ts diff --git a/packages/vision-polyfill/src/prop.ts b/packages/vision-preset/src/prop.ts similarity index 100% rename from packages/vision-polyfill/src/prop.ts rename to packages/vision-preset/src/prop.ts diff --git a/packages/vision-polyfill/src/vision.less b/packages/vision-preset/src/vision.less similarity index 100% rename from packages/vision-polyfill/src/vision.less rename to packages/vision-preset/src/vision.less diff --git a/packages/vision-polyfill/tsconfig.json b/packages/vision-preset/tsconfig.json similarity index 100% rename from packages/vision-polyfill/tsconfig.json rename to packages/vision-preset/tsconfig.json diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 8535e8655..a02f8f6c2 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -21,17 +21,19 @@ echo "" # work mkdir packages -# cp -r $WORK_DIR/packages/demo packages/demo +cp -r $WORK_DIR/packages/demo packages/demo cp -r $WORK_DIR/packages/react-simulator-renderer packages/react-simulator-renderer -cp -r $WORK_DIR/packages/globals packages/globals +cp -r $WORK_DIR/packages/editor-core packages/editor-core +cp -r $WORK_DIR/packages/vision-preset packages/vision-preset lerna bootstrap lerna run cloud-build --stream cd $WORK_DIR -# mv deploy-space/packages/demo/build $BUILD_DEST +mv deploy-space/packages/demo/build $BUILD_DEST # mv deploy-space/packages/react-simulator-renderer/dist/* $BUILD_DEST mv deploy-space/packages/react-simulator-renderer/dist $BUILD_DEST -mv deploy-space/packages/globals/dist/* $BUILD_DEST -cp deploy-space/html/* $BUILD_DEST +mv deploy-space/packages/editor-core/dist/* $BUILD_DEST +mv deploy-space/packages/vision-preset/dist/* $BUILD_DEST +cp deploy-space/static/* $BUILD_DEST echo "complete" From df9ebda08fc2b737a050353a08825678a47803df Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 12:04:48 +0800 Subject: [PATCH 04/12] pub --- packages/editor-core/cloud-build.json | 16 ---------------- packages/editor-core/package.json | 5 +++-- packages/vision-preset/package.json | 6 ++++-- 3 files changed, 7 insertions(+), 20 deletions(-) delete mode 100644 packages/editor-core/cloud-build.json diff --git a/packages/editor-core/cloud-build.json b/packages/editor-core/cloud-build.json deleted file mode 100644 index 15de75b91..000000000 --- a/packages/editor-core/cloud-build.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "plugins": [ - [ - "build-plugin-component", - { - "filename": "core", - "library": "LCECore", - "libraryTarget": "umd" - } - ], - "build-plugin-fusion", - ["build-plugin-moment-locales", { - "locales": ["zh-cn"] - }] - ] -} diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 41f5810ba..82edc713a 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -7,11 +7,12 @@ "module": "es/index.js", "files": [ "lib", - "es" + "es", + "dist" ], "scripts": { "build": "build-scripts build --skip-demo", - "cloud-build": "build-scripts build --skip-demo --config cloud-build.json" + "cloud-build": "build-scripts build --skip-demo" }, "dependencies": { "@alifd/next": "^1.19.16", diff --git a/packages/vision-preset/package.json b/packages/vision-preset/package.json index 37483f394..94d1ed213 100644 --- a/packages/vision-preset/package.json +++ b/packages/vision-preset/package.json @@ -1,13 +1,15 @@ { "name": "@ali/lowcode-vision-preset", + "private": true, "version": "0.8.0", "description": "Vision Polyfill for Ali lowCode engine", "main": "lib/index.js", "files": [ - "dist" + "dist", + "es", + "lib" ], "scripts": { - "build": "build-scripts build --skip-demo", "cloud-build": "build-scripts build --skip-demo" }, "license": "MIT", From a7871183ba9d1a8d252b604bbc32d621ff6bdc64 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 12:05:03 +0800 Subject: [PATCH 05/12] Publish - @ali/lowcode-demo@0.8.11 - @ali/lowcode-designer@0.9.4 - @ali/lowcode-editor-core@0.8.7 - @ali/lowcode-editor-skeleton@0.8.8 - @ali/lowcode-plugin-components-pane@0.8.6 - @ali/lowcode-plugin-designer@0.9.4 - @ali/lowcode-plugin-event-bind-dialog@0.8.7 - @ali/lowcode-plugin-outline-pane@0.8.10 - @ali/lowcode-plugin-sample-logo@0.8.6 - @ali/lowcode-plugin-sample-preview@0.8.9 - @ali/lowcode-plugin-source-editor@0.8.3 - @ali/lowcode-plugin-undo-redo@0.8.7 - @ali/lowcode-plugin-variable-bind-dialog@0.8.5 - @ali/lowcode-plugin-zh-en@0.8.9 - @ali/lowcode-react-renderer@0.8.5 - @ali/lowcode-react-simulator-renderer@0.8.9 - @ali/lowcode-runtime@0.8.13 - @ali/lowcode-setters@0.8.9 - @ali/lowcode-types@0.8.1 - @ali/lowcode-utils@0.8.1 - @ali/lowcode-vision-preset@0.8.1 --- packages/demo/CHANGELOG.md | 8 +++++ packages/demo/package.json | 36 +++++++++---------- packages/designer/CHANGELOG.md | 8 +++++ packages/designer/package.json | 8 ++--- packages/editor-core/CHANGELOG.md | 12 +++++++ packages/editor-core/package.json | 12 +++---- packages/editor-skeleton/CHANGELOG.md | 8 +++++ packages/editor-skeleton/package.json | 10 +++--- packages/plugin-components-pane/CHANGELOG.md | 8 +++++ packages/plugin-components-pane/package.json | 8 ++--- packages/plugin-designer/CHANGELOG.md | 8 +++++ packages/plugin-designer/package.json | 6 ++-- .../plugin-event-bind-dialog/CHANGELOG.md | 8 +++++ .../plugin-event-bind-dialog/package.json | 6 ++-- packages/plugin-outline-pane/CHANGELOG.md | 8 +++++ packages/plugin-outline-pane/package.json | 10 +++--- packages/plugin-sample-logo/CHANGELOG.md | 8 +++++ packages/plugin-sample-logo/package.json | 4 +-- packages/plugin-sample-preview/CHANGELOG.md | 11 ++++++ packages/plugin-sample-preview/package.json | 6 ++-- packages/plugin-source-editor/CHANGELOG.md | 8 +++++ packages/plugin-source-editor/package.json | 8 ++--- packages/plugin-undo-redo/CHANGELOG.md | 8 +++++ packages/plugin-undo-redo/package.json | 12 +++---- .../plugin-variable-bind-dialog/CHANGELOG.md | 8 +++++ .../plugin-variable-bind-dialog/package.json | 4 +-- packages/plugin-zh-en/CHANGELOG.md | 8 +++++ packages/plugin-zh-en/package.json | 8 ++--- packages/react-renderer/CHANGELOG.md | 8 +++++ packages/react-renderer/package.json | 2 +- .../react-simulator-renderer/CHANGELOG.md | 8 +++++ .../react-simulator-renderer/package.json | 10 +++--- packages/runtime/CHANGELOG.md | 14 ++++++++ packages/runtime/package.json | 6 ++-- packages/setters/CHANGELOG.md | 8 +++++ packages/setters/package.json | 2 +- packages/types/CHANGELOG.md | 12 +++++++ packages/types/package.json | 6 ++-- packages/utils/CHANGELOG.md | 12 +++++++ packages/utils/package.json | 6 ++-- packages/vision-preset/CHANGELOG.md | 8 +++++ packages/vision-preset/package.json | 16 ++++----- 42 files changed, 282 insertions(+), 93 deletions(-) create mode 100644 packages/editor-core/CHANGELOG.md create mode 100644 packages/types/CHANGELOG.md create mode 100644 packages/utils/CHANGELOG.md diff --git a/packages/demo/CHANGELOG.md b/packages/demo/CHANGELOG.md index 7552a9f50..4f697d3c1 100644 --- a/packages/demo/CHANGELOG.md +++ b/packages/demo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.10...@ali/lowcode-demo@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-demo + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.9...@ali/lowcode-demo@0.8.10) (2020-04-16) diff --git a/packages/demo/package.json b/packages/demo/package.json index 820480e39..fca7f6f24 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-demo", - "version": "0.8.10", + "version": "0.8.11", "private": true, "description": "低代码引擎 DEMO", "scripts": { @@ -11,23 +11,23 @@ }, "config": {}, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.4", - "@ali/lowcode-editor-skeleton": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", - "@ali/lowcode-plugin-components-pane": "^0.8.0", - "@ali/lowcode-plugin-designer": "^0.9.1", - "@ali/lowcode-plugin-event-bind-dialog": "^0.8.0", - "@ali/lowcode-plugin-outline-pane": "^0.8.7", - "@ali/lowcode-plugin-sample-logo": "^0.8.0", - "@ali/lowcode-plugin-source-editor":"^0.8.2", - "@ali/lowcode-plugin-sample-preview": "^0.8.6", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-skeleton": "^0.8.8", + "@ali/lowcode-plugin-components-pane": "^0.8.6", + "@ali/lowcode-plugin-designer": "^0.9.4", + "@ali/lowcode-plugin-event-bind-dialog": "^0.8.7", + "@ali/lowcode-plugin-outline-pane": "^0.8.10", + "@ali/lowcode-plugin-sample-logo": "^0.8.6", + "@ali/lowcode-plugin-sample-preview": "^0.8.9", "@ali/lowcode-plugin-settings-pane": "^0.8.8", - "@ali/lowcode-plugin-undo-redo": "^0.8.0", - "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.2", - "@ali/lowcode-plugin-zh-en": "^0.8.6", - "@ali/lowcode-react-renderer": "^0.8.4", - "@ali/lowcode-runtime": "^0.8.10", - "@ali/lowcode-setters": "^0.8.8", + "@ali/lowcode-plugin-source-editor": "^0.8.3", + "@ali/lowcode-plugin-undo-redo": "^0.8.7", + "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.5", + "@ali/lowcode-plugin-zh-en": "^0.8.9", + "@ali/lowcode-react-renderer": "^0.8.5", + "@ali/lowcode-runtime": "^0.8.13", + "@ali/lowcode-setters": "^0.8.9", + "@ali/lowcode-utils": "^0.8.1", "@alifd/next": "^1.19.12", "@alife/theme-lowcode-dark": "^0.1.0", "@alife/theme-lowcode-light": "^0.1.0", @@ -43,7 +43,7 @@ "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0", "build-plugin-react-app": "^1.1.2", - "monaco-editor-webpack-plugin":"^1.9.0", + "monaco-editor-webpack-plugin": "^1.9.0", "tsconfig-paths-webpack-plugin": "^3.2.0" } } diff --git a/packages/designer/CHANGELOG.md b/packages/designer/CHANGELOG.md index 0fac7ae44..b12327125 100644 --- a/packages/designer/CHANGELOG.md +++ b/packages/designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.3...@ali/lowcode-designer@0.9.4) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-designer + ## [0.9.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.2...@ali/lowcode-designer@0.9.3) (2020-04-16) diff --git a/packages/designer/package.json b/packages/designer/package.json index e271381bf..722284aa0 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-designer", - "version": "0.9.3", + "version": "0.9.4", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", - "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/editor-core/CHANGELOG.md b/packages/editor-core/CHANGELOG.md new file mode 100644 index 000000000..cb26e52a8 --- /dev/null +++ b/packages/editor-core/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.6...@ali/lowcode-editor-core@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-core diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 82edc713a..486f0f732 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-core", - "version": "0.8.6", + "version": "0.8.7", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -15,18 +15,18 @@ "cloud-build": "build-scripts build --skip-demo" }, "dependencies": { + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "@alifd/next": "^1.19.16", - "@ali/lowcode-types": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", "classnames": "^2.2.6", - "power-di": "^2.2.4", "debug": "^4.1.1", "intl-messageformat": "^8.3.1", - "store": "^2.0.12", + "power-di": "^2.2.4", "react": "^16", - "react-dom": "^16.7.0" + "react-dom": "^16.7.0", + "store": "^2.0.12" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/editor-skeleton/CHANGELOG.md b/packages/editor-skeleton/CHANGELOG.md index a95e20bd8..8f29d1615 100644 --- a/packages/editor-skeleton/CHANGELOG.md +++ b/packages/editor-skeleton/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.7...@ali/lowcode-editor-skeleton@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-skeleton + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.6...@ali/lowcode-editor-skeleton@0.8.7) (2020-04-16) diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 7bc4a6f41..4d31ee28a 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-skeleton", - "version": "0.8.7", + "version": "0.8.8", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -20,11 +20,11 @@ ], "author": "xiayang.xy", "dependencies": { + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "@alifd/next": "^1.x", - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-designer": "^0.9.2", - "@ali/lowcode-types": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-components-pane/CHANGELOG.md b/packages/plugin-components-pane/CHANGELOG.md index e908d47fe..2b88b0b5b 100644 --- a/packages/plugin-components-pane/CHANGELOG.md +++ b/packages/plugin-components-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.5...@ali/lowcode-plugin-components-pane@0.8.6) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-components-pane + ## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.4...@ali/lowcode-plugin-components-pane@0.8.5) (2020-04-16) diff --git a/packages/plugin-components-pane/package.json b/packages/plugin-components-pane/package.json index a00043109..d82425d0b 100644 --- a/packages/plugin-components-pane/package.json +++ b/packages/plugin-components-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-components-pane", - "version": "0.8.5", + "version": "0.8.6", "description": "alibaba lowcode editor component-list plugin", "files": [ "es/", @@ -23,9 +23,9 @@ "@ali/iceluna-addon-component-list": "^1.0.11", "@ali/iceluna-comp-material-show": "^1.0.10", "@ali/iceluna-sdk": "^1.0.6-beta.6", - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.19", "react": "^16.8.1" }, diff --git a/packages/plugin-designer/CHANGELOG.md b/packages/plugin-designer/CHANGELOG.md index 270625db8..24c6c5a2a 100644 --- a/packages/plugin-designer/CHANGELOG.md +++ b/packages/plugin-designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.3...@ali/lowcode-plugin-designer@0.9.4) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-designer + ## [0.9.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.2...@ali/lowcode-plugin-designer@0.9.3) (2020-04-16) diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 95ff4d95c..1b1e91c02 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-designer", - "version": "0.9.3", + "version": "0.9.4", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -20,8 +20,8 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-event-bind-dialog/CHANGELOG.md b/packages/plugin-event-bind-dialog/CHANGELOG.md index 2ef68f6f8..ec64dcf49 100644 --- a/packages/plugin-event-bind-dialog/CHANGELOG.md +++ b/packages/plugin-event-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.6...@ali/lowcode-plugin-event-bind-dialog@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-event-bind-dialog + ## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.5...@ali/lowcode-plugin-event-bind-dialog@0.8.6) (2020-04-16) diff --git a/packages/plugin-event-bind-dialog/package.json b/packages/plugin-event-bind-dialog/package.json index 9a37ec2f7..019763c4c 100644 --- a/packages/plugin-event-bind-dialog/package.json +++ b/packages/plugin-event-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-event-bind-dialog", - "version": "0.8.6", + "version": "0.8.7", "description": "alibaba lowcode editor event bind dialog plugin", "files": [ "es", @@ -19,8 +19,8 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-types": "^0.8.0", - "@ali/lowcode-editor-core": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.16", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-outline-pane/CHANGELOG.md b/packages/plugin-outline-pane/CHANGELOG.md index 55e603f25..c3dbb57a9 100644 --- a/packages/plugin-outline-pane/CHANGELOG.md +++ b/packages/plugin-outline-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.9...@ali/lowcode-plugin-outline-pane@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-outline-pane + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.8...@ali/lowcode-plugin-outline-pane@0.8.9) (2020-04-16) diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 315048104..9c6470dc1 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-outline-pane", - "version": "0.8.9", + "version": "0.8.10", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -14,10 +14,10 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-utils": "^0.8.0", - "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "@alifd/next": "^1.19.16", "classnames": "^2.2.6", "react": "^16", diff --git a/packages/plugin-sample-logo/CHANGELOG.md b/packages/plugin-sample-logo/CHANGELOG.md index 3db933347..2bc32e289 100644 --- a/packages/plugin-sample-logo/CHANGELOG.md +++ b/packages/plugin-sample-logo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.5...@ali/lowcode-plugin-sample-logo@0.8.6) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-sample-logo + ## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.4...@ali/lowcode-plugin-sample-logo@0.8.5) (2020-04-16) diff --git a/packages/plugin-sample-logo/package.json b/packages/plugin-sample-logo/package.json index f9d54c47e..777c8ddc5 100644 --- a/packages/plugin-sample-logo/package.json +++ b/packages/plugin-sample-logo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-logo", - "version": "0.8.5", + "version": "0.8.6", "description": "alibaba lowcode editor logo plugin", "files": [ "es/", @@ -20,7 +20,7 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-editor-core": "^0.8.7", "react": "^16.8.1" }, "devDependencies": { diff --git a/packages/plugin-sample-preview/CHANGELOG.md b/packages/plugin-sample-preview/CHANGELOG.md index 8fe3860f3..782155a10 100644 --- a/packages/plugin-sample-preview/CHANGELOG.md +++ b/packages/plugin-sample-preview/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.8...@ali/lowcode-plugin-sample-preview@0.8.9) (2020-04-27) + + +### Features + +* preview ([abeb2ba](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/abeb2ba)) + + + + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.7...@ali/lowcode-plugin-sample-preview@0.8.8) (2020-04-16) diff --git a/packages/plugin-sample-preview/package.json b/packages/plugin-sample-preview/package.json index 7608bcfa8..314159ec7 100644 --- a/packages/plugin-sample-preview/package.json +++ b/packages/plugin-sample-preview/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-preview", - "version": "0.8.8", + "version": "0.8.9", "description": "alibaba lowcode editor sample preview plugin", "files": [ "es", @@ -18,8 +18,8 @@ "editor" ], "dependencies": { - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", "@alifd/next": "^1.x", "react": "^16.8.1" }, diff --git a/packages/plugin-source-editor/CHANGELOG.md b/packages/plugin-source-editor/CHANGELOG.md index 7c5e8d83c..778f51eb0 100644 --- a/packages/plugin-source-editor/CHANGELOG.md +++ b/packages/plugin-source-editor/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## 0.8.3 (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-source-editor + ## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.1...@ali/lowcode-plugin-variable-bind-dialog@0.8.2) (2020-03-30) diff --git a/packages/plugin-source-editor/package.json b/packages/plugin-source-editor/package.json index 19c1c9178..0877cc509 100644 --- a/packages/plugin-source-editor/package.json +++ b/packages/plugin-source-editor/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-source-editor", - "version": "0.8.2", + "version": "0.8.3", "description": "alibaba lowcode editor source-editor plugin", "files": [ "es", @@ -19,12 +19,12 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.7", "@alifd/next": "^1.19.16", + "js-beautify": "^1.10.1", + "prettier": "^1.18.2", "react": "^16.8.1", "react-dom": "^16.8.1", - "prettier":"^1.18.2", - "js-beautify": "^1.10.1", "react-monaco-editor": "^0.36.0" }, "devDependencies": { diff --git a/packages/plugin-undo-redo/CHANGELOG.md b/packages/plugin-undo-redo/CHANGELOG.md index 9a8fd9165..4855280a6 100644 --- a/packages/plugin-undo-redo/CHANGELOG.md +++ b/packages/plugin-undo-redo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.6...@ali/lowcode-plugin-undo-redo@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-undo-redo + ## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.5...@ali/lowcode-plugin-undo-redo@0.8.6) (2020-04-16) diff --git a/packages/plugin-undo-redo/package.json b/packages/plugin-undo-redo/package.json index a51075418..0052188f9 100644 --- a/packages/plugin-undo-redo/package.json +++ b/packages/plugin-undo-redo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-undo-redo", - "version": "0.8.6", + "version": "0.8.7", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", @@ -19,11 +19,11 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-editor-skeleton": "^0.8.7", - "@ali/lowcode-types": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-skeleton": "^0.8.8", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-variable-bind-dialog/CHANGELOG.md b/packages/plugin-variable-bind-dialog/CHANGELOG.md index a42a63dfd..64a3740fa 100644 --- a/packages/plugin-variable-bind-dialog/CHANGELOG.md +++ b/packages/plugin-variable-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.4...@ali/lowcode-plugin-variable-bind-dialog@0.8.5) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-variable-bind-dialog + ## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.3...@ali/lowcode-plugin-variable-bind-dialog@0.8.4) (2020-04-16) diff --git a/packages/plugin-variable-bind-dialog/package.json b/packages/plugin-variable-bind-dialog/package.json index d35ce1ee2..2cda38c78 100644 --- a/packages/plugin-variable-bind-dialog/package.json +++ b/packages/plugin-variable-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-variable-bind-dialog", - "version": "0.8.4", + "version": "0.8.5", "description": "alibaba lowcode editor variable bind dialog plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", + "@ali/lowcode-editor-core": "^0.8.7", "@alifd/next": "^1.19.16", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-zh-en/CHANGELOG.md b/packages/plugin-zh-en/CHANGELOG.md index 1dbaabd31..9e49bd3e7 100644 --- a/packages/plugin-zh-en/CHANGELOG.md +++ b/packages/plugin-zh-en/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.8...@ali/lowcode-plugin-zh-en@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-zh-en + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.7...@ali/lowcode-plugin-zh-en@0.8.8) (2020-04-16) diff --git a/packages/plugin-zh-en/package.json b/packages/plugin-zh-en/package.json index 220a12831..58bc7bbb5 100644 --- a/packages/plugin-zh-en/package.json +++ b/packages/plugin-zh-en/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-zh-en", - "version": "0.8.8", + "version": "0.8.9", "description": "alibaba lowcode editor zhong english plugin", "files": [ "es", @@ -14,9 +14,9 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-utils": "^0.8.0", - "@ali/lowcode-types": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/react-renderer/CHANGELOG.md b/packages/react-renderer/CHANGELOG.md index 9cb431588..35fe15204 100644 --- a/packages/react-renderer/CHANGELOG.md +++ b/packages/react-renderer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-renderer@0.8.4...@ali/lowcode-react-renderer@0.8.5) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-react-renderer + ## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-renderer@0.8.3...@ali/lowcode-react-renderer@0.8.4) (2020-03-30) diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 28df95c28..f094836bf 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-react-renderer", - "version": "0.8.4", + "version": "0.8.5", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", diff --git a/packages/react-simulator-renderer/CHANGELOG.md b/packages/react-simulator-renderer/CHANGELOG.md index 30ae60812..239013748 100644 --- a/packages/react-simulator-renderer/CHANGELOG.md +++ b/packages/react-simulator-renderer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.8...@ali/lowcode-react-simulator-renderer@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-react-simulator-renderer + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.7...@ali/lowcode-react-simulator-renderer@0.8.8) (2020-04-16) diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index cca8bc1ea..45591b0ab 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@ali/lowcode-react-simulator-renderer", - "version": "0.8.8", + "version": "0.8.9", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.3", - "@ali/lowcode-types": "^0.8.0", - "@ali/lowcode-utils": "^0.8.0", - "@ali/lowcode-react-renderer": "^0.8.4", + "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-react-renderer": "^0.8.5", + "@ali/lowcode-types": "^0.8.1", + "@ali/lowcode-utils": "^0.8.1", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", "classnames": "^2.2.6", diff --git a/packages/runtime/CHANGELOG.md b/packages/runtime/CHANGELOG.md index 6f8510a66..c7af6e751 100644 --- a/packages/runtime/CHANGELOG.md +++ b/packages/runtime/CHANGELOG.md @@ -3,6 +3,20 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-runtime@0.8.10...@ali/lowcode-runtime@0.8.13) (2020-04-27) + + +### Features + +* add init and ready lifecycles ([fd100c9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/fd100c9)) +* 支持编译渲染 ([0a42151](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/0a42151)) +* 支持配置layouts属性 ([8464235](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/8464235)) +* 透出loading ([e96934a](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/e96934a)) + + + + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-runtime@0.8.7...@ali/lowcode-runtime@0.8.10) (2020-04-15) diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 2c667549f..75baac01f 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-runtime", - "version": "0.8.12", + "version": "0.8.13", "description": "Runtime for Ali lowCode engine", "files": [ "es", @@ -25,8 +25,8 @@ }, "license": "MIT", "dependencies": { - "@ali/recore": "^1.6.9", - "@ali/offline-events": "^1.0.0" + "@ali/offline-events": "^1.0.0", + "@ali/recore": "^1.6.9" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/setters/CHANGELOG.md b/packages/setters/CHANGELOG.md index 7b544e90e..8d40c1c76 100644 --- a/packages/setters/CHANGELOG.md +++ b/packages/setters/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.8...@ali/lowcode-setters@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-setters + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.7...@ali/lowcode-setters@0.8.8) (2020-04-16) diff --git a/packages/setters/package.json b/packages/setters/package.json index 4f6441d3d..1957dfff3 100644 --- a/packages/setters/package.json +++ b/packages/setters/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-setters", - "version": "0.8.8", + "version": "0.8.9", "description": "Builtin setters for Ali lowCode engine", "files": [ "es", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md new file mode 100644 index 000000000..bb25364a3 --- /dev/null +++ b/packages/types/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +## 0.8.1 (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-types diff --git a/packages/types/package.json b/packages/types/package.json index 9937c1d98..e7dc08499 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-types", - "version": "0.8.0", + "version": "0.8.1", "description": "Types for Ali lowCode engine", "files": [ "es", @@ -14,8 +14,8 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "react": "^16", - "power-di": "^2.2.4" + "power-di": "^2.2.4", + "react": "^16" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md new file mode 100644 index 000000000..65f01b306 --- /dev/null +++ b/packages/utils/CHANGELOG.md @@ -0,0 +1,12 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +## 0.8.1 (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-utils diff --git a/packages/utils/package.json b/packages/utils/package.json index 18b5b1318..4ca05ff0e 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-utils", - "version": "0.8.0", + "version": "0.8.1", "description": "Utils for Ali lowCode engine", "files": [ "es", @@ -14,9 +14,9 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "react": "^16", + "@ali/lowcode-utils": "^0.8.1", "@alifd/next": "^1.19.16", - "@ali/lowcode-utils": "^0.8.0" + "react": "^16" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/vision-preset/CHANGELOG.md b/packages/vision-preset/CHANGELOG.md index f1359bc3c..5e11c0542 100644 --- a/packages/vision-preset/CHANGELOG.md +++ b/packages/vision-preset/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## 0.8.1 (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-vision-preset + ## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-polyfill@0.8.1...@ali/lowcode-vision-polyfill@0.8.2) (2020-04-16) diff --git a/packages/vision-preset/package.json b/packages/vision-preset/package.json index 94d1ed213..7c2865ef3 100644 --- a/packages/vision-preset/package.json +++ b/packages/vision-preset/package.json @@ -1,7 +1,7 @@ { "name": "@ali/lowcode-vision-preset", "private": true, - "version": "0.8.0", + "version": "0.8.1", "description": "Vision Polyfill for Ali lowCode engine", "main": "lib/index.js", "files": [ @@ -14,13 +14,13 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.6", - "@ali/lowcode-editor-skeleton": "^0.8.7", - "@ali/lowcode-plugin-designer": "^0.9.3", - "@ali/lowcode-plugin-outline-pane": "^0.8.9", - "@ali/lowcode-plugin-undo-redo": "^0.8.6", - "@ali/lowcode-plugin-zh-en": "^0.8.8", - "@ali/lowcode-setters": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-skeleton": "^0.8.8", + "@ali/lowcode-plugin-designer": "^0.9.4", + "@ali/lowcode-plugin-outline-pane": "^0.8.10", + "@ali/lowcode-plugin-undo-redo": "^0.8.7", + "@ali/lowcode-plugin-zh-en": "^0.8.9", + "@ali/lowcode-setters": "^0.8.9", "@ali/ve-i18n-util": "^2.0.2", "@ali/ve-icons": "^4.1.9", "@ali/ve-less-variables": "2.0.3", From 81f25b304bb125b012691be6b4f89a25f1ddf637 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 12:14:31 +0800 Subject: [PATCH 06/12] fix versions --- packages/editor-skeleton/package.json | 1 - packages/setters/package.json | 2 +- packages/utils/package.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 4d31ee28a..079186db4 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -18,7 +18,6 @@ "lowcode", "editor" ], - "author": "xiayang.xy", "dependencies": { "@ali/lowcode-designer": "^0.9.4", "@ali/lowcode-editor-core": "^0.8.7", diff --git a/packages/setters/package.json b/packages/setters/package.json index 1957dfff3..87bdf68c7 100644 --- a/packages/setters/package.json +++ b/packages/setters/package.json @@ -22,7 +22,7 @@ "@ali/iceluna-comp-react-node": "^1.0.5", "@ali/iceluna-sdk": "^1.0.5-beta.24", "@ali/lc-style-setter": "^0.0.1", - "@ali/lowcode-editor-core": "^0.9.3", + "@ali/lowcode-editor-core": "^0.8.0", "@alifd/next": "^1.19.16", "acorn": "^6.4.1", "classnames": "^2.2.6", diff --git a/packages/utils/package.json b/packages/utils/package.json index 4ca05ff0e..486e3d4bf 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -14,7 +14,7 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.16", "react": "^16" }, From 395f09c08d63a64247326a7f7dcd98504ededb4e Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 12:16:53 +0800 Subject: [PATCH 07/12] Publish - @ali/lowcode-demo@0.8.12 - @ali/lowcode-designer@0.9.5 - @ali/lowcode-editor-core@0.8.8 - @ali/lowcode-editor-skeleton@0.8.9 - @ali/lowcode-plugin-components-pane@0.8.7 - @ali/lowcode-plugin-designer@0.9.5 - @ali/lowcode-plugin-event-bind-dialog@0.8.8 - @ali/lowcode-plugin-outline-pane@0.8.11 - @ali/lowcode-plugin-sample-logo@0.8.7 - @ali/lowcode-plugin-sample-preview@0.8.10 - @ali/lowcode-plugin-source-editor@0.8.4 - @ali/lowcode-plugin-undo-redo@0.8.8 - @ali/lowcode-plugin-variable-bind-dialog@0.8.6 - @ali/lowcode-plugin-zh-en@0.8.10 - @ali/lowcode-react-simulator-renderer@0.8.10 - @ali/lowcode-setters@0.8.10 - @ali/lowcode-utils@0.8.2 - @ali/lowcode-vision-preset@0.8.2 --- packages/demo/CHANGELOG.md | 8 +++++ packages/demo/package.json | 30 +++++++++---------- packages/designer/CHANGELOG.md | 8 +++++ packages/designer/package.json | 6 ++-- packages/editor-core/CHANGELOG.md | 8 +++++ packages/editor-core/package.json | 4 +-- packages/editor-skeleton/CHANGELOG.md | 8 +++++ packages/editor-skeleton/package.json | 8 ++--- packages/plugin-components-pane/CHANGELOG.md | 8 +++++ packages/plugin-components-pane/package.json | 6 ++-- packages/plugin-designer/CHANGELOG.md | 8 +++++ packages/plugin-designer/package.json | 6 ++-- .../plugin-event-bind-dialog/CHANGELOG.md | 8 +++++ .../plugin-event-bind-dialog/package.json | 4 +-- packages/plugin-outline-pane/CHANGELOG.md | 8 +++++ packages/plugin-outline-pane/package.json | 8 ++--- packages/plugin-sample-logo/CHANGELOG.md | 8 +++++ packages/plugin-sample-logo/package.json | 4 +-- packages/plugin-sample-preview/CHANGELOG.md | 8 +++++ packages/plugin-sample-preview/package.json | 6 ++-- packages/plugin-source-editor/CHANGELOG.md | 8 +++++ packages/plugin-source-editor/package.json | 4 +-- packages/plugin-undo-redo/CHANGELOG.md | 8 +++++ packages/plugin-undo-redo/package.json | 10 +++---- .../plugin-variable-bind-dialog/CHANGELOG.md | 8 +++++ .../plugin-variable-bind-dialog/package.json | 4 +-- packages/plugin-zh-en/CHANGELOG.md | 8 +++++ packages/plugin-zh-en/package.json | 6 ++-- .../react-simulator-renderer/CHANGELOG.md | 8 +++++ .../react-simulator-renderer/package.json | 6 ++-- packages/setters/CHANGELOG.md | 8 +++++ packages/setters/package.json | 4 +-- packages/utils/CHANGELOG.md | 8 +++++ packages/utils/package.json | 2 +- packages/vision-preset/CHANGELOG.md | 8 +++++ packages/vision-preset/package.json | 16 +++++----- 36 files changed, 211 insertions(+), 67 deletions(-) diff --git a/packages/demo/CHANGELOG.md b/packages/demo/CHANGELOG.md index 4f697d3c1..faf802e83 100644 --- a/packages/demo/CHANGELOG.md +++ b/packages/demo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.11...@ali/lowcode-demo@0.8.12) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-demo + ## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.10...@ali/lowcode-demo@0.8.11) (2020-04-27) diff --git a/packages/demo/package.json b/packages/demo/package.json index fca7f6f24..deb334775 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-demo", - "version": "0.8.11", + "version": "0.8.12", "private": true, "description": "低代码引擎 DEMO", "scripts": { @@ -11,23 +11,23 @@ }, "config": {}, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", - "@ali/lowcode-editor-skeleton": "^0.8.8", - "@ali/lowcode-plugin-components-pane": "^0.8.6", - "@ali/lowcode-plugin-designer": "^0.9.4", - "@ali/lowcode-plugin-event-bind-dialog": "^0.8.7", - "@ali/lowcode-plugin-outline-pane": "^0.8.10", - "@ali/lowcode-plugin-sample-logo": "^0.8.6", - "@ali/lowcode-plugin-sample-preview": "^0.8.9", + "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-skeleton": "^0.8.9", + "@ali/lowcode-plugin-components-pane": "^0.8.7", + "@ali/lowcode-plugin-designer": "^0.9.5", + "@ali/lowcode-plugin-event-bind-dialog": "^0.8.8", + "@ali/lowcode-plugin-outline-pane": "^0.8.11", + "@ali/lowcode-plugin-sample-logo": "^0.8.7", + "@ali/lowcode-plugin-sample-preview": "^0.8.10", "@ali/lowcode-plugin-settings-pane": "^0.8.8", - "@ali/lowcode-plugin-source-editor": "^0.8.3", - "@ali/lowcode-plugin-undo-redo": "^0.8.7", - "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.5", - "@ali/lowcode-plugin-zh-en": "^0.8.9", + "@ali/lowcode-plugin-source-editor": "^0.8.4", + "@ali/lowcode-plugin-undo-redo": "^0.8.8", + "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.6", + "@ali/lowcode-plugin-zh-en": "^0.8.10", "@ali/lowcode-react-renderer": "^0.8.5", "@ali/lowcode-runtime": "^0.8.13", - "@ali/lowcode-setters": "^0.8.9", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-setters": "^0.8.10", + "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.19.12", "@alife/theme-lowcode-dark": "^0.1.0", "@alife/theme-lowcode-light": "^0.1.0", diff --git a/packages/designer/CHANGELOG.md b/packages/designer/CHANGELOG.md index b12327125..c3773455b 100644 --- a/packages/designer/CHANGELOG.md +++ b/packages/designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.4...@ali/lowcode-designer@0.9.5) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-designer + ## [0.9.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.3...@ali/lowcode-designer@0.9.4) (2020-04-27) diff --git a/packages/designer/package.json b/packages/designer/package.json index 722284aa0..8692c18cf 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-designer", - "version": "0.9.4", + "version": "0.9.5", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/editor-core/CHANGELOG.md b/packages/editor-core/CHANGELOG.md index cb26e52a8..cf4e6fe78 100644 --- a/packages/editor-core/CHANGELOG.md +++ b/packages/editor-core/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.7...@ali/lowcode-editor-core@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-core + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.6...@ali/lowcode-editor-core@0.8.7) (2020-04-27) diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 486f0f732..aa4f6d8c2 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-core", - "version": "0.8.7", + "version": "0.8.8", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -16,7 +16,7 @@ }, "dependencies": { "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.19.16", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", diff --git a/packages/editor-skeleton/CHANGELOG.md b/packages/editor-skeleton/CHANGELOG.md index 8f29d1615..b2de1a756 100644 --- a/packages/editor-skeleton/CHANGELOG.md +++ b/packages/editor-skeleton/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.8...@ali/lowcode-editor-skeleton@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-skeleton + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.7...@ali/lowcode-editor-skeleton@0.8.8) (2020-04-27) diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 079186db4..6fc1bde7e 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-skeleton", - "version": "0.8.8", + "version": "0.8.9", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,10 +19,10 @@ "editor" ], "dependencies": { - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.x", "classnames": "^2.2.6", "react": "^16.8.1", diff --git a/packages/plugin-components-pane/CHANGELOG.md b/packages/plugin-components-pane/CHANGELOG.md index 2b88b0b5b..7cefb15e3 100644 --- a/packages/plugin-components-pane/CHANGELOG.md +++ b/packages/plugin-components-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.6...@ali/lowcode-plugin-components-pane@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-components-pane + ## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.5...@ali/lowcode-plugin-components-pane@0.8.6) (2020-04-27) diff --git a/packages/plugin-components-pane/package.json b/packages/plugin-components-pane/package.json index d82425d0b..a855e2951 100644 --- a/packages/plugin-components-pane/package.json +++ b/packages/plugin-components-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-components-pane", - "version": "0.8.6", + "version": "0.8.7", "description": "alibaba lowcode editor component-list plugin", "files": [ "es/", @@ -23,8 +23,8 @@ "@ali/iceluna-addon-component-list": "^1.0.11", "@ali/iceluna-comp-material-show": "^1.0.10", "@ali/iceluna-sdk": "^1.0.6-beta.6", - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.19", "react": "^16.8.1" diff --git a/packages/plugin-designer/CHANGELOG.md b/packages/plugin-designer/CHANGELOG.md index 24c6c5a2a..e5f3a193a 100644 --- a/packages/plugin-designer/CHANGELOG.md +++ b/packages/plugin-designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.4...@ali/lowcode-plugin-designer@0.9.5) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-designer + ## [0.9.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.3...@ali/lowcode-plugin-designer@0.9.4) (2020-04-27) diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 1b1e91c02..9839f4513 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-designer", - "version": "0.9.4", + "version": "0.9.5", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -20,8 +20,8 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-event-bind-dialog/CHANGELOG.md b/packages/plugin-event-bind-dialog/CHANGELOG.md index ec64dcf49..1e3e86e42 100644 --- a/packages/plugin-event-bind-dialog/CHANGELOG.md +++ b/packages/plugin-event-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.7...@ali/lowcode-plugin-event-bind-dialog@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-event-bind-dialog + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.6...@ali/lowcode-plugin-event-bind-dialog@0.8.7) (2020-04-27) diff --git a/packages/plugin-event-bind-dialog/package.json b/packages/plugin-event-bind-dialog/package.json index 019763c4c..416eabf3a 100644 --- a/packages/plugin-event-bind-dialog/package.json +++ b/packages/plugin-event-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-event-bind-dialog", - "version": "0.8.7", + "version": "0.8.8", "description": "alibaba lowcode editor event bind dialog plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.16", "react": "^16.8.1", diff --git a/packages/plugin-outline-pane/CHANGELOG.md b/packages/plugin-outline-pane/CHANGELOG.md index c3dbb57a9..72c1d85ce 100644 --- a/packages/plugin-outline-pane/CHANGELOG.md +++ b/packages/plugin-outline-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.10...@ali/lowcode-plugin-outline-pane@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-outline-pane + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.9...@ali/lowcode-plugin-outline-pane@0.8.10) (2020-04-27) diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 9c6470dc1..c7bfad8ec 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-outline-pane", - "version": "0.8.10", + "version": "0.8.11", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -14,10 +14,10 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.19.16", "classnames": "^2.2.6", "react": "^16", diff --git a/packages/plugin-sample-logo/CHANGELOG.md b/packages/plugin-sample-logo/CHANGELOG.md index 2bc32e289..c5e307a73 100644 --- a/packages/plugin-sample-logo/CHANGELOG.md +++ b/packages/plugin-sample-logo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.6...@ali/lowcode-plugin-sample-logo@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-sample-logo + ## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.5...@ali/lowcode-plugin-sample-logo@0.8.6) (2020-04-27) diff --git a/packages/plugin-sample-logo/package.json b/packages/plugin-sample-logo/package.json index 777c8ddc5..8bdeb4d3c 100644 --- a/packages/plugin-sample-logo/package.json +++ b/packages/plugin-sample-logo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-logo", - "version": "0.8.6", + "version": "0.8.7", "description": "alibaba lowcode editor logo plugin", "files": [ "es/", @@ -20,7 +20,7 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "react": "^16.8.1" }, "devDependencies": { diff --git a/packages/plugin-sample-preview/CHANGELOG.md b/packages/plugin-sample-preview/CHANGELOG.md index 782155a10..362e8224b 100644 --- a/packages/plugin-sample-preview/CHANGELOG.md +++ b/packages/plugin-sample-preview/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.9...@ali/lowcode-plugin-sample-preview@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-sample-preview + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.8...@ali/lowcode-plugin-sample-preview@0.8.9) (2020-04-27) diff --git a/packages/plugin-sample-preview/package.json b/packages/plugin-sample-preview/package.json index 314159ec7..4efc8ce20 100644 --- a/packages/plugin-sample-preview/package.json +++ b/packages/plugin-sample-preview/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-preview", - "version": "0.8.9", + "version": "0.8.10", "description": "alibaba lowcode editor sample preview plugin", "files": [ "es", @@ -18,8 +18,8 @@ "editor" ], "dependencies": { - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", "@alifd/next": "^1.x", "react": "^16.8.1" }, diff --git a/packages/plugin-source-editor/CHANGELOG.md b/packages/plugin-source-editor/CHANGELOG.md index 778f51eb0..dafdcd0fa 100644 --- a/packages/plugin-source-editor/CHANGELOG.md +++ b/packages/plugin-source-editor/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-source-editor@0.8.3...@ali/lowcode-plugin-source-editor@0.8.4) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-source-editor + ## 0.8.3 (2020-04-27) diff --git a/packages/plugin-source-editor/package.json b/packages/plugin-source-editor/package.json index 0877cc509..5e6c4ea00 100644 --- a/packages/plugin-source-editor/package.json +++ b/packages/plugin-source-editor/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-source-editor", - "version": "0.8.3", + "version": "0.8.4", "description": "alibaba lowcode editor source-editor plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "@alifd/next": "^1.19.16", "js-beautify": "^1.10.1", "prettier": "^1.18.2", diff --git a/packages/plugin-undo-redo/CHANGELOG.md b/packages/plugin-undo-redo/CHANGELOG.md index 4855280a6..df5a4e1d6 100644 --- a/packages/plugin-undo-redo/CHANGELOG.md +++ b/packages/plugin-undo-redo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.7...@ali/lowcode-plugin-undo-redo@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-undo-redo + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.6...@ali/lowcode-plugin-undo-redo@0.8.7) (2020-04-27) diff --git a/packages/plugin-undo-redo/package.json b/packages/plugin-undo-redo/package.json index 0052188f9..407b3a0e5 100644 --- a/packages/plugin-undo-redo/package.json +++ b/packages/plugin-undo-redo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-undo-redo", - "version": "0.8.7", + "version": "0.8.8", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", @@ -19,11 +19,11 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.4", - "@ali/lowcode-editor-core": "^0.8.7", - "@ali/lowcode-editor-skeleton": "^0.8.8", + "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-skeleton": "^0.8.9", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-variable-bind-dialog/CHANGELOG.md b/packages/plugin-variable-bind-dialog/CHANGELOG.md index 64a3740fa..1cbe708b9 100644 --- a/packages/plugin-variable-bind-dialog/CHANGELOG.md +++ b/packages/plugin-variable-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.5...@ali/lowcode-plugin-variable-bind-dialog@0.8.6) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-variable-bind-dialog + ## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.4...@ali/lowcode-plugin-variable-bind-dialog@0.8.5) (2020-04-27) diff --git a/packages/plugin-variable-bind-dialog/package.json b/packages/plugin-variable-bind-dialog/package.json index 2cda38c78..605e751f2 100644 --- a/packages/plugin-variable-bind-dialog/package.json +++ b/packages/plugin-variable-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-variable-bind-dialog", - "version": "0.8.5", + "version": "0.8.6", "description": "alibaba lowcode editor variable bind dialog plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "@alifd/next": "^1.19.16", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-zh-en/CHANGELOG.md b/packages/plugin-zh-en/CHANGELOG.md index 9e49bd3e7..eacabd6a8 100644 --- a/packages/plugin-zh-en/CHANGELOG.md +++ b/packages/plugin-zh-en/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.9...@ali/lowcode-plugin-zh-en@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-zh-en + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.8...@ali/lowcode-plugin-zh-en@0.8.9) (2020-04-27) diff --git a/packages/plugin-zh-en/package.json b/packages/plugin-zh-en/package.json index 58bc7bbb5..c2c2983e9 100644 --- a/packages/plugin-zh-en/package.json +++ b/packages/plugin-zh-en/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-zh-en", - "version": "0.8.9", + "version": "0.8.10", "description": "alibaba lowcode editor zhong english plugin", "files": [ "es", @@ -14,9 +14,9 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", + "@ali/lowcode-editor-core": "^0.8.8", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/react-simulator-renderer/CHANGELOG.md b/packages/react-simulator-renderer/CHANGELOG.md index 239013748..9d2de3053 100644 --- a/packages/react-simulator-renderer/CHANGELOG.md +++ b/packages/react-simulator-renderer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.9...@ali/lowcode-react-simulator-renderer@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-react-simulator-renderer + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.8...@ali/lowcode-react-simulator-renderer@0.8.9) (2020-04-27) diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 45591b0ab..bfc953026 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@ali/lowcode-react-simulator-renderer", - "version": "0.8.9", + "version": "0.8.10", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.4", + "@ali/lowcode-designer": "^0.9.5", "@ali/lowcode-react-renderer": "^0.8.5", "@ali/lowcode-types": "^0.8.1", - "@ali/lowcode-utils": "^0.8.1", + "@ali/lowcode-utils": "^0.8.2", "@recore/obx": "^1.0.8", "@recore/obx-react": "^1.0.7", "classnames": "^2.2.6", diff --git a/packages/setters/CHANGELOG.md b/packages/setters/CHANGELOG.md index 8d40c1c76..03a46fe7e 100644 --- a/packages/setters/CHANGELOG.md +++ b/packages/setters/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.9...@ali/lowcode-setters@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-setters + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.8...@ali/lowcode-setters@0.8.9) (2020-04-27) diff --git a/packages/setters/package.json b/packages/setters/package.json index 87bdf68c7..619db7c7f 100644 --- a/packages/setters/package.json +++ b/packages/setters/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-setters", - "version": "0.8.9", + "version": "0.8.10", "description": "Builtin setters for Ali lowCode engine", "files": [ "es", @@ -22,7 +22,7 @@ "@ali/iceluna-comp-react-node": "^1.0.5", "@ali/iceluna-sdk": "^1.0.5-beta.24", "@ali/lc-style-setter": "^0.0.1", - "@ali/lowcode-editor-core": "^0.8.0", + "@ali/lowcode-editor-core": "^0.8.8", "@alifd/next": "^1.19.16", "acorn": "^6.4.1", "classnames": "^2.2.6", diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md index 65f01b306..42a3985cc 100644 --- a/packages/utils/CHANGELOG.md +++ b/packages/utils/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-utils@0.8.1...@ali/lowcode-utils@0.8.2) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-utils + ## 0.8.1 (2020-04-27) diff --git a/packages/utils/package.json b/packages/utils/package.json index 486e3d4bf..ea4f05cfc 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-utils", - "version": "0.8.1", + "version": "0.8.2", "description": "Utils for Ali lowCode engine", "files": [ "es", diff --git a/packages/vision-preset/CHANGELOG.md b/packages/vision-preset/CHANGELOG.md index 5e11c0542..814879a1a 100644 --- a/packages/vision-preset/CHANGELOG.md +++ b/packages/vision-preset/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.1...@ali/lowcode-vision-preset@0.8.2) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-vision-preset + ## 0.8.1 (2020-04-27) diff --git a/packages/vision-preset/package.json b/packages/vision-preset/package.json index 7c2865ef3..4f462e5ed 100644 --- a/packages/vision-preset/package.json +++ b/packages/vision-preset/package.json @@ -1,7 +1,7 @@ { "name": "@ali/lowcode-vision-preset", "private": true, - "version": "0.8.1", + "version": "0.8.2", "description": "Vision Polyfill for Ali lowCode engine", "main": "lib/index.js", "files": [ @@ -14,13 +14,13 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.7", - "@ali/lowcode-editor-skeleton": "^0.8.8", - "@ali/lowcode-plugin-designer": "^0.9.4", - "@ali/lowcode-plugin-outline-pane": "^0.8.10", - "@ali/lowcode-plugin-undo-redo": "^0.8.7", - "@ali/lowcode-plugin-zh-en": "^0.8.9", - "@ali/lowcode-setters": "^0.8.9", + "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-skeleton": "^0.8.9", + "@ali/lowcode-plugin-designer": "^0.9.5", + "@ali/lowcode-plugin-outline-pane": "^0.8.11", + "@ali/lowcode-plugin-undo-redo": "^0.8.8", + "@ali/lowcode-plugin-zh-en": "^0.8.10", + "@ali/lowcode-setters": "^0.8.10", "@ali/ve-i18n-util": "^2.0.2", "@ali/ve-icons": "^4.1.9", "@ali/ve-less-variables": "2.0.3", From f7fc729fbcad791268e584d8b83f44447f5df538 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 12:30:24 +0800 Subject: [PATCH 08/12] chore: cloud build --- packages/vision-preset/build.json | 2 +- scripts/deploy.sh | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/vision-preset/build.json b/packages/vision-preset/build.json index 053e76f3f..daa2630de 100644 --- a/packages/vision-preset/build.json +++ b/packages/vision-preset/build.json @@ -3,7 +3,7 @@ [ "build-plugin-component", { - "filename": "vision", + "filename": "vision-preset", "library": "VisualEngine", "libraryTarget": "umd", "externals": { diff --git a/scripts/deploy.sh b/scripts/deploy.sh index a02f8f6c2..e266dcfcf 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -30,8 +30,7 @@ lerna run cloud-build --stream cd $WORK_DIR mv deploy-space/packages/demo/build $BUILD_DEST -# mv deploy-space/packages/react-simulator-renderer/dist/* $BUILD_DEST -mv deploy-space/packages/react-simulator-renderer/dist $BUILD_DEST +mv deploy-space/packages/react-simulator-renderer/dist/* $BUILD_DEST mv deploy-space/packages/editor-core/dist/* $BUILD_DEST mv deploy-space/packages/vision-preset/dist/* $BUILD_DEST cp deploy-space/static/* $BUILD_DEST From ba13002a1e8ad666a6135e80db49dbde698e6bb2 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 14:38:11 +0800 Subject: [PATCH 09/12] read build --- packages/demo/build.json | 17 +++++----- packages/demo/public/index.html | 11 ++++--- packages/editor-core/build.plugin.js | 10 ------ packages/vision-preset/build.json | 8 ++--- packages/vision-preset/src/editor.ts | 3 -- packages/vision-preset/src/index.ts | 46 ++++++++++++++++++++++++++-- scripts/start.sh | 2 +- 7 files changed, 65 insertions(+), 32 deletions(-) diff --git a/packages/demo/build.json b/packages/demo/build.json index d09fc5a56..5a86fb950 100644 --- a/packages/demo/build.json +++ b/packages/demo/build.json @@ -1,8 +1,6 @@ { "entry": { - "index": "src/index.ts", - "react-simulator-renderer": "../react-simulator-renderer/src/index.ts", - "preview": "src/preview.ts" + "index": "src/vision/index.ts" }, "vendor": false, "devServer": { @@ -10,10 +8,13 @@ }, "publicPath": "/", "externals": { - "react": "window.React", - "react-dom": "window.ReactDOM", - "prop-types": "window.PropTypes", - "@alifd/next": "window.Next" + "react": "var window.React", + "react-dom": "var window.ReactDOM", + "prop-types": "var window.PropTypes", + "@alifd/next": "var window.Next", + "@ali/lowcode-editor-core": "var window.LCECore", + "@ali/visualengine": "var window.VisualEngine", + "@ali/visualengine-utils": "var window.VisualEngineUtils" }, "plugins": [ [ @@ -35,4 +36,4 @@ ], "./build.plugin.js" ] -} \ No newline at end of file +} diff --git a/packages/demo/public/index.html b/packages/demo/public/index.html index 95ebbe0d2..353373def 100644 --- a/packages/demo/public/index.html +++ b/packages/demo/public/index.html @@ -16,8 +16,10 @@ - - + + + + - + + + diff --git a/packages/editor-core/build.plugin.js b/packages/editor-core/build.plugin.js index 068928007..980daf4f1 100644 --- a/packages/editor-core/build.plugin.js +++ b/packages/editor-core/build.plugin.js @@ -8,15 +8,5 @@ module.exports = ({ onGetWebpackConfig }) => { .use(TsconfigPathsPlugin, [{ configFile: "./tsconfig.json" }]); - - config - // 定义插件名称 - .plugin('MonacoWebpackPlugin') - // 第一项为具体插件,第二项为插件参数 - .use(new MonacoWebpackPlugin({ - languages:["javascript","css","json"] - }), []); - config.plugins.delete('hot'); - config.devServer.hot(false); }); }; diff --git a/packages/vision-preset/build.json b/packages/vision-preset/build.json index daa2630de..1fa0bc613 100644 --- a/packages/vision-preset/build.json +++ b/packages/vision-preset/build.json @@ -7,10 +7,10 @@ "library": "VisualEngine", "libraryTarget": "umd", "externals": { - "react": "window.React", - "react-dom": "window.ReactDOM", - "prop-types": "window.PropTypes", - "@ali/lowcode-editor-core": "window.LCECore" + "react": "var window.React", + "react-dom": "var window.ReactDOM", + "prop-types": "var window.PropTypes", + "@ali/lowcode-editor-core": "var window.LCECore" } } ], diff --git a/packages/vision-preset/src/editor.ts b/packages/vision-preset/src/editor.ts index 3c91fed94..8d1d5fc03 100644 --- a/packages/vision-preset/src/editor.ts +++ b/packages/vision-preset/src/editor.ts @@ -11,9 +11,6 @@ import Preview from '@ali/lowcode-plugin-sample-preview'; import SourceEditor from '@ali/lowcode-plugin-source-editor'; import { i18nReducer } from './i18n-reducer'; -export * from '@ali/lowcode-editor-core'; -export * from '@ali/lowcode-designer'; - registerSetters(); export const editor = new Editor(); diff --git a/packages/vision-preset/src/index.ts b/packages/vision-preset/src/index.ts index 639a5a51f..51e39de0e 100644 --- a/packages/vision-preset/src/index.ts +++ b/packages/vision-preset/src/index.ts @@ -21,7 +21,7 @@ import Field from './field'; import Prop from './prop'; import Env from './env'; import DragEngine from './drag-engine'; -export * from './editor'; +import { designer, editor } from './editor'; import './vision.less'; @@ -61,6 +61,9 @@ const modules = { const context = new VisualEngineContext(); const VisualEngine = { + designer, + editor, + skeleton, /** * VE.Popup */ @@ -96,9 +99,48 @@ const VisualEngine = { DragEngine, }; +(window as any).VisualEngine = VisualEngine; + export default VisualEngine; -(window as any).VisualEngine = VisualEngine; +export { + designer, + editor, + skeleton, + /** + * VE.Popup + */ + Popup, + /** + * VE Utils + */ + utils, + I18nUtil, + Hotkey, + Env, + /* pub/sub 集线器 */ + Bus, + /* 事件 */ + EVENTS, + /* 修饰方法 */ + HOOKS, + Exchange, + context, + /** + * VE.init + * + * Initialized the whole VisualEngine UI + */ + init, + ui, + Panes, + modules, + Trunk, + Prototype, + Bundle, + Pages, + DragEngine, +}; /* diff --git a/scripts/start.sh b/scripts/start.sh index ad46187eb..388716ab7 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -2,4 +2,4 @@ # FIXME! do not run build lerna exec --scope @ali/lowcode-react-renderer -- npm run build -lerna exec --scope @ali/lowcode-vision-polyfill -- npm start +lerna exec --scope @ali/lowcode-demo -- npm start From 10271b83163115cfa52844cc86217f0d01072507 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 14:48:00 +0800 Subject: [PATCH 10/12] read build --- packages/designer/src/builtin-simulator/host.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 5ac616dc2..ffd2cbfe2 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -53,7 +53,7 @@ const defaultSimulatorUrl = (() => { if (dev) { urls = [`${prefix}/css/react-simulator-renderer.css`, `${prefix}/js/react-simulator-renderer.js`]; } else if (process.env.NODE_ENV === 'production') { - urls = [`${prefix}/react-simulator-renderer.min.css`, `${prefix}/react-simulator-renderer.min.js`]; + urls = [`${prefix}/react-simulator-renderer.css`, `${prefix}/react-simulator-renderer.js`]; } else { urls = [`${prefix}/react-simulator-renderer.css`, `${prefix}/react-simulator-renderer.js`]; } From 88dad87c5c827a6442bcf43e75383e7a5cba3908 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 15:17:34 +0800 Subject: [PATCH 11/12] Publish - @ali/lowcode-demo@0.8.13 - @ali/lowcode-designer@0.9.6 - @ali/lowcode-editor-core@0.8.9 - @ali/lowcode-editor-skeleton@0.8.10 - @ali/lowcode-plugin-components-pane@0.8.8 - @ali/lowcode-plugin-designer@0.9.6 - @ali/lowcode-plugin-event-bind-dialog@0.8.9 - @ali/lowcode-plugin-outline-pane@0.8.12 - @ali/lowcode-plugin-sample-logo@0.8.8 - @ali/lowcode-plugin-sample-preview@0.8.11 - @ali/lowcode-plugin-source-editor@0.8.5 - @ali/lowcode-plugin-undo-redo@0.8.9 - @ali/lowcode-plugin-variable-bind-dialog@0.8.7 - @ali/lowcode-plugin-zh-en@0.8.11 - @ali/lowcode-react-simulator-renderer@0.8.11 - @ali/lowcode-setters@0.8.11 - @ali/lowcode-vision-preset@0.8.3 --- packages/demo/CHANGELOG.md | 8 ++++++ packages/demo/package.json | 28 +++++++++---------- packages/designer/CHANGELOG.md | 8 ++++++ packages/designer/package.json | 4 +-- packages/editor-core/CHANGELOG.md | 8 ++++++ packages/editor-core/package.json | 2 +- packages/editor-skeleton/CHANGELOG.md | 8 ++++++ packages/editor-skeleton/package.json | 6 ++-- packages/plugin-components-pane/CHANGELOG.md | 8 ++++++ packages/plugin-components-pane/package.json | 6 ++-- packages/plugin-designer/CHANGELOG.md | 8 ++++++ packages/plugin-designer/package.json | 6 ++-- .../plugin-event-bind-dialog/CHANGELOG.md | 8 ++++++ .../plugin-event-bind-dialog/package.json | 4 +-- packages/plugin-outline-pane/CHANGELOG.md | 8 ++++++ packages/plugin-outline-pane/package.json | 6 ++-- packages/plugin-sample-logo/CHANGELOG.md | 8 ++++++ packages/plugin-sample-logo/package.json | 4 +-- packages/plugin-sample-preview/CHANGELOG.md | 8 ++++++ packages/plugin-sample-preview/package.json | 6 ++-- packages/plugin-source-editor/CHANGELOG.md | 8 ++++++ packages/plugin-source-editor/package.json | 4 +-- packages/plugin-undo-redo/CHANGELOG.md | 8 ++++++ packages/plugin-undo-redo/package.json | 8 +++--- .../plugin-variable-bind-dialog/CHANGELOG.md | 8 ++++++ .../plugin-variable-bind-dialog/package.json | 4 +-- packages/plugin-zh-en/CHANGELOG.md | 8 ++++++ packages/plugin-zh-en/package.json | 4 +-- .../react-simulator-renderer/CHANGELOG.md | 8 ++++++ .../react-simulator-renderer/package.json | 4 +-- packages/setters/CHANGELOG.md | 8 ++++++ packages/setters/package.json | 4 +-- packages/vision-preset/CHANGELOG.md | 8 ++++++ packages/vision-preset/package.json | 16 +++++------ 34 files changed, 194 insertions(+), 58 deletions(-) diff --git a/packages/demo/CHANGELOG.md b/packages/demo/CHANGELOG.md index faf802e83..b77cd8eae 100644 --- a/packages/demo/CHANGELOG.md +++ b/packages/demo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.12...@ali/lowcode-demo@0.8.13) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-demo + ## [0.8.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-demo@0.8.11...@ali/lowcode-demo@0.8.12) (2020-04-27) diff --git a/packages/demo/package.json b/packages/demo/package.json index deb334775..6b89db2ae 100644 --- a/packages/demo/package.json +++ b/packages/demo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-demo", - "version": "0.8.12", + "version": "0.8.13", "private": true, "description": "低代码引擎 DEMO", "scripts": { @@ -11,22 +11,22 @@ }, "config": {}, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", - "@ali/lowcode-editor-skeleton": "^0.8.9", - "@ali/lowcode-plugin-components-pane": "^0.8.7", - "@ali/lowcode-plugin-designer": "^0.9.5", - "@ali/lowcode-plugin-event-bind-dialog": "^0.8.8", - "@ali/lowcode-plugin-outline-pane": "^0.8.11", - "@ali/lowcode-plugin-sample-logo": "^0.8.7", - "@ali/lowcode-plugin-sample-preview": "^0.8.10", + "@ali/lowcode-editor-core": "^0.8.9", + "@ali/lowcode-editor-skeleton": "^0.8.10", + "@ali/lowcode-plugin-components-pane": "^0.8.8", + "@ali/lowcode-plugin-designer": "^0.9.6", + "@ali/lowcode-plugin-event-bind-dialog": "^0.8.9", + "@ali/lowcode-plugin-outline-pane": "^0.8.12", + "@ali/lowcode-plugin-sample-logo": "^0.8.8", + "@ali/lowcode-plugin-sample-preview": "^0.8.11", "@ali/lowcode-plugin-settings-pane": "^0.8.8", - "@ali/lowcode-plugin-source-editor": "^0.8.4", - "@ali/lowcode-plugin-undo-redo": "^0.8.8", - "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.6", - "@ali/lowcode-plugin-zh-en": "^0.8.10", + "@ali/lowcode-plugin-source-editor": "^0.8.5", + "@ali/lowcode-plugin-undo-redo": "^0.8.9", + "@ali/lowcode-plugin-variable-bind-dialog": "^0.8.7", + "@ali/lowcode-plugin-zh-en": "^0.8.11", "@ali/lowcode-react-renderer": "^0.8.5", "@ali/lowcode-runtime": "^0.8.13", - "@ali/lowcode-setters": "^0.8.10", + "@ali/lowcode-setters": "^0.8.11", "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.19.12", "@alife/theme-lowcode-dark": "^0.1.0", diff --git a/packages/designer/CHANGELOG.md b/packages/designer/CHANGELOG.md index c3773455b..4096633c8 100644 --- a/packages/designer/CHANGELOG.md +++ b/packages/designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.5...@ali/lowcode-designer@0.9.6) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-designer + ## [0.9.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-designer@0.9.4...@ali/lowcode-designer@0.9.5) (2020-04-27) diff --git a/packages/designer/package.json b/packages/designer/package.json index 8692c18cf..2e466f02f 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-designer", - "version": "0.9.5", + "version": "0.9.6", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,7 +15,7 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", "classnames": "^2.2.6", diff --git a/packages/editor-core/CHANGELOG.md b/packages/editor-core/CHANGELOG.md index cf4e6fe78..972a96de8 100644 --- a/packages/editor-core/CHANGELOG.md +++ b/packages/editor-core/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.8...@ali/lowcode-editor-core@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-core + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-core@0.8.7...@ali/lowcode-editor-core@0.8.8) (2020-04-27) diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index aa4f6d8c2..87b9fff55 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-core", - "version": "0.8.8", + "version": "0.8.9", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", diff --git a/packages/editor-skeleton/CHANGELOG.md b/packages/editor-skeleton/CHANGELOG.md index b2de1a756..03f6e822c 100644 --- a/packages/editor-skeleton/CHANGELOG.md +++ b/packages/editor-skeleton/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.9...@ali/lowcode-editor-skeleton@0.8.10) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-editor-skeleton + ## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-editor-skeleton@0.8.8...@ali/lowcode-editor-skeleton@0.8.9) (2020-04-27) diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 6fc1bde7e..8f2e58ab6 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-editor-skeleton", - "version": "0.8.9", + "version": "0.8.10", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -19,8 +19,8 @@ "editor" ], "dependencies": { - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.x", diff --git a/packages/plugin-components-pane/CHANGELOG.md b/packages/plugin-components-pane/CHANGELOG.md index 7cefb15e3..a274c3d3e 100644 --- a/packages/plugin-components-pane/CHANGELOG.md +++ b/packages/plugin-components-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.7...@ali/lowcode-plugin-components-pane@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-components-pane + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-components-pane@0.8.6...@ali/lowcode-plugin-components-pane@0.8.7) (2020-04-27) diff --git a/packages/plugin-components-pane/package.json b/packages/plugin-components-pane/package.json index a855e2951..e0ed896eb 100644 --- a/packages/plugin-components-pane/package.json +++ b/packages/plugin-components-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-components-pane", - "version": "0.8.7", + "version": "0.8.8", "description": "alibaba lowcode editor component-list plugin", "files": [ "es/", @@ -23,8 +23,8 @@ "@ali/iceluna-addon-component-list": "^1.0.11", "@ali/iceluna-comp-material-show": "^1.0.10", "@ali/iceluna-sdk": "^1.0.6-beta.6", - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.19", "react": "^16.8.1" diff --git a/packages/plugin-designer/CHANGELOG.md b/packages/plugin-designer/CHANGELOG.md index e5f3a193a..5a3db0794 100644 --- a/packages/plugin-designer/CHANGELOG.md +++ b/packages/plugin-designer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.9.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.5...@ali/lowcode-plugin-designer@0.9.6) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-designer + ## [0.9.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-designer@0.9.4...@ali/lowcode-plugin-designer@0.9.5) (2020-04-27) diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 9839f4513..1a1182855 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-designer", - "version": "0.9.5", + "version": "0.9.6", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -20,8 +20,8 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-event-bind-dialog/CHANGELOG.md b/packages/plugin-event-bind-dialog/CHANGELOG.md index 1e3e86e42..1fc667fa8 100644 --- a/packages/plugin-event-bind-dialog/CHANGELOG.md +++ b/packages/plugin-event-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.8...@ali/lowcode-plugin-event-bind-dialog@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-event-bind-dialog + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-event-bind-dialog@0.8.7...@ali/lowcode-plugin-event-bind-dialog@0.8.8) (2020-04-27) diff --git a/packages/plugin-event-bind-dialog/package.json b/packages/plugin-event-bind-dialog/package.json index 416eabf3a..86107950b 100644 --- a/packages/plugin-event-bind-dialog/package.json +++ b/packages/plugin-event-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-event-bind-dialog", - "version": "0.8.8", + "version": "0.8.9", "description": "alibaba lowcode editor event bind dialog plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@alifd/next": "^1.19.16", "react": "^16.8.1", diff --git a/packages/plugin-outline-pane/CHANGELOG.md b/packages/plugin-outline-pane/CHANGELOG.md index 72c1d85ce..2abdd56a1 100644 --- a/packages/plugin-outline-pane/CHANGELOG.md +++ b/packages/plugin-outline-pane/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.12](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.11...@ali/lowcode-plugin-outline-pane@0.8.12) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-outline-pane + ## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-outline-pane@0.8.10...@ali/lowcode-plugin-outline-pane@0.8.11) (2020-04-27) diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index c7bfad8ec..e204ae7e7 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-outline-pane", - "version": "0.8.11", + "version": "0.8.12", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -14,8 +14,8 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", "@alifd/next": "^1.19.16", diff --git a/packages/plugin-sample-logo/CHANGELOG.md b/packages/plugin-sample-logo/CHANGELOG.md index c5e307a73..a61ceb981 100644 --- a/packages/plugin-sample-logo/CHANGELOG.md +++ b/packages/plugin-sample-logo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.7...@ali/lowcode-plugin-sample-logo@0.8.8) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-sample-logo + ## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-logo@0.8.6...@ali/lowcode-plugin-sample-logo@0.8.7) (2020-04-27) diff --git a/packages/plugin-sample-logo/package.json b/packages/plugin-sample-logo/package.json index 8bdeb4d3c..b9af99478 100644 --- a/packages/plugin-sample-logo/package.json +++ b/packages/plugin-sample-logo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-logo", - "version": "0.8.7", + "version": "0.8.8", "description": "alibaba lowcode editor logo plugin", "files": [ "es/", @@ -20,7 +20,7 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "react": "^16.8.1" }, "devDependencies": { diff --git a/packages/plugin-sample-preview/CHANGELOG.md b/packages/plugin-sample-preview/CHANGELOG.md index 362e8224b..e8c6b030a 100644 --- a/packages/plugin-sample-preview/CHANGELOG.md +++ b/packages/plugin-sample-preview/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.10...@ali/lowcode-plugin-sample-preview@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-sample-preview + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-sample-preview@0.8.9...@ali/lowcode-plugin-sample-preview@0.8.10) (2020-04-27) diff --git a/packages/plugin-sample-preview/package.json b/packages/plugin-sample-preview/package.json index 4efc8ce20..82904c751 100644 --- a/packages/plugin-sample-preview/package.json +++ b/packages/plugin-sample-preview/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-sample-preview", - "version": "0.8.10", + "version": "0.8.11", "description": "alibaba lowcode editor sample preview plugin", "files": [ "es", @@ -18,8 +18,8 @@ "editor" ], "dependencies": { - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", "@alifd/next": "^1.x", "react": "^16.8.1" }, diff --git a/packages/plugin-source-editor/CHANGELOG.md b/packages/plugin-source-editor/CHANGELOG.md index dafdcd0fa..7c60a9274 100644 --- a/packages/plugin-source-editor/CHANGELOG.md +++ b/packages/plugin-source-editor/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.5](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-source-editor@0.8.4...@ali/lowcode-plugin-source-editor@0.8.5) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-source-editor + ## [0.8.4](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-source-editor@0.8.3...@ali/lowcode-plugin-source-editor@0.8.4) (2020-04-27) diff --git a/packages/plugin-source-editor/package.json b/packages/plugin-source-editor/package.json index 5e6c4ea00..23bf0f012 100644 --- a/packages/plugin-source-editor/package.json +++ b/packages/plugin-source-editor/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-source-editor", - "version": "0.8.4", + "version": "0.8.5", "description": "alibaba lowcode editor source-editor plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@alifd/next": "^1.19.16", "js-beautify": "^1.10.1", "prettier": "^1.18.2", diff --git a/packages/plugin-undo-redo/CHANGELOG.md b/packages/plugin-undo-redo/CHANGELOG.md index df5a4e1d6..7024d5606 100644 --- a/packages/plugin-undo-redo/CHANGELOG.md +++ b/packages/plugin-undo-redo/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.9](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.8...@ali/lowcode-plugin-undo-redo@0.8.9) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-undo-redo + ## [0.8.8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-undo-redo@0.8.7...@ali/lowcode-plugin-undo-redo@0.8.8) (2020-04-27) diff --git a/packages/plugin-undo-redo/package.json b/packages/plugin-undo-redo/package.json index 407b3a0e5..ef58b7cc6 100644 --- a/packages/plugin-undo-redo/package.json +++ b/packages/plugin-undo-redo/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-undo-redo", - "version": "0.8.8", + "version": "0.8.9", "description": "alibaba lowcode editor undo redo plugin", "files": [ "es", @@ -19,9 +19,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@ali/lowcode-designer": "^0.9.5", - "@ali/lowcode-editor-core": "^0.8.8", - "@ali/lowcode-editor-skeleton": "^0.8.9", + "@ali/lowcode-designer": "^0.9.6", + "@ali/lowcode-editor-core": "^0.8.9", + "@ali/lowcode-editor-skeleton": "^0.8.10", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", "react": "^16.8.1", diff --git a/packages/plugin-variable-bind-dialog/CHANGELOG.md b/packages/plugin-variable-bind-dialog/CHANGELOG.md index 1cbe708b9..7ca75d382 100644 --- a/packages/plugin-variable-bind-dialog/CHANGELOG.md +++ b/packages/plugin-variable-bind-dialog/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.7](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.6...@ali/lowcode-plugin-variable-bind-dialog@0.8.7) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-variable-bind-dialog + ## [0.8.6](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-variable-bind-dialog@0.8.5...@ali/lowcode-plugin-variable-bind-dialog@0.8.6) (2020-04-27) diff --git a/packages/plugin-variable-bind-dialog/package.json b/packages/plugin-variable-bind-dialog/package.json index 605e751f2..e986d6aa7 100644 --- a/packages/plugin-variable-bind-dialog/package.json +++ b/packages/plugin-variable-bind-dialog/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-variable-bind-dialog", - "version": "0.8.6", + "version": "0.8.7", "description": "alibaba lowcode editor variable bind dialog plugin", "files": [ "es", @@ -19,7 +19,7 @@ ], "author": "zude.hzd", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@alifd/next": "^1.19.16", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/plugin-zh-en/CHANGELOG.md b/packages/plugin-zh-en/CHANGELOG.md index eacabd6a8..e0cdfeaec 100644 --- a/packages/plugin-zh-en/CHANGELOG.md +++ b/packages/plugin-zh-en/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.10...@ali/lowcode-plugin-zh-en@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-plugin-zh-en + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-plugin-zh-en@0.8.9...@ali/lowcode-plugin-zh-en@0.8.10) (2020-04-27) diff --git a/packages/plugin-zh-en/package.json b/packages/plugin-zh-en/package.json index c2c2983e9..efa68e179 100644 --- a/packages/plugin-zh-en/package.json +++ b/packages/plugin-zh-en/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-plugin-zh-en", - "version": "0.8.10", + "version": "0.8.11", "description": "alibaba lowcode editor zhong english plugin", "files": [ "es", @@ -14,7 +14,7 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", "react": "^16.8.1", diff --git a/packages/react-simulator-renderer/CHANGELOG.md b/packages/react-simulator-renderer/CHANGELOG.md index 9d2de3053..79cfa0e71 100644 --- a/packages/react-simulator-renderer/CHANGELOG.md +++ b/packages/react-simulator-renderer/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.10...@ali/lowcode-react-simulator-renderer@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-react-simulator-renderer + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-react-simulator-renderer@0.8.9...@ali/lowcode-react-simulator-renderer@0.8.10) (2020-04-27) diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index bfc953026..d031eb62c 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "@ali/lowcode-react-simulator-renderer", - "version": "0.8.10", + "version": "0.8.11", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,7 +13,7 @@ "test:snapshot": "ava --update-snapshots" }, "dependencies": { - "@ali/lowcode-designer": "^0.9.5", + "@ali/lowcode-designer": "^0.9.6", "@ali/lowcode-react-renderer": "^0.8.5", "@ali/lowcode-types": "^0.8.1", "@ali/lowcode-utils": "^0.8.2", diff --git a/packages/setters/CHANGELOG.md b/packages/setters/CHANGELOG.md index 03a46fe7e..a978f6056 100644 --- a/packages/setters/CHANGELOG.md +++ b/packages/setters/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.11](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.10...@ali/lowcode-setters@0.8.11) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-setters + ## [0.8.10](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-setters@0.8.9...@ali/lowcode-setters@0.8.10) (2020-04-27) diff --git a/packages/setters/package.json b/packages/setters/package.json index 619db7c7f..9a9d5ebe4 100644 --- a/packages/setters/package.json +++ b/packages/setters/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-setters", - "version": "0.8.10", + "version": "0.8.11", "description": "Builtin setters for Ali lowCode engine", "files": [ "es", @@ -22,7 +22,7 @@ "@ali/iceluna-comp-react-node": "^1.0.5", "@ali/iceluna-sdk": "^1.0.5-beta.24", "@ali/lc-style-setter": "^0.0.1", - "@ali/lowcode-editor-core": "^0.8.8", + "@ali/lowcode-editor-core": "^0.8.9", "@alifd/next": "^1.19.16", "acorn": "^6.4.1", "classnames": "^2.2.6", diff --git a/packages/vision-preset/CHANGELOG.md b/packages/vision-preset/CHANGELOG.md index 814879a1a..ee7e55f7b 100644 --- a/packages/vision-preset/CHANGELOG.md +++ b/packages/vision-preset/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [0.8.3](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.2...@ali/lowcode-vision-preset@0.8.3) (2020-04-27) + + + + +**Note:** Version bump only for package @ali/lowcode-vision-preset + ## [0.8.2](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-vision-preset@0.8.1...@ali/lowcode-vision-preset@0.8.2) (2020-04-27) diff --git a/packages/vision-preset/package.json b/packages/vision-preset/package.json index 4f462e5ed..550154aef 100644 --- a/packages/vision-preset/package.json +++ b/packages/vision-preset/package.json @@ -1,7 +1,7 @@ { "name": "@ali/lowcode-vision-preset", "private": true, - "version": "0.8.2", + "version": "0.8.3", "description": "Vision Polyfill for Ali lowCode engine", "main": "lib/index.js", "files": [ @@ -14,13 +14,13 @@ }, "license": "MIT", "dependencies": { - "@ali/lowcode-editor-core": "^0.8.8", - "@ali/lowcode-editor-skeleton": "^0.8.9", - "@ali/lowcode-plugin-designer": "^0.9.5", - "@ali/lowcode-plugin-outline-pane": "^0.8.11", - "@ali/lowcode-plugin-undo-redo": "^0.8.8", - "@ali/lowcode-plugin-zh-en": "^0.8.10", - "@ali/lowcode-setters": "^0.8.10", + "@ali/lowcode-editor-core": "^0.8.9", + "@ali/lowcode-editor-skeleton": "^0.8.10", + "@ali/lowcode-plugin-designer": "^0.9.6", + "@ali/lowcode-plugin-outline-pane": "^0.8.12", + "@ali/lowcode-plugin-undo-redo": "^0.8.9", + "@ali/lowcode-plugin-zh-en": "^0.8.11", + "@ali/lowcode-setters": "^0.8.11", "@ali/ve-i18n-util": "^2.0.2", "@ali/ve-icons": "^4.1.9", "@ali/ve-less-variables": "2.0.3", From 45cb76871e3808c8e53aab9a432ef98dec4ed160 Mon Sep 17 00:00:00 2001 From: kangwei Date: Mon, 27 Apr 2020 19:55:06 +0800 Subject: [PATCH 12/12] fix demo --- packages/demo/build.json | 5 ++--- tsconfig.json | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/demo/build.json b/packages/demo/build.json index 5a86fb950..38868b6b0 100644 --- a/packages/demo/build.json +++ b/packages/demo/build.json @@ -1,6 +1,7 @@ { "entry": { - "index": "src/vision/index.ts" + "index": "src/vision/index.ts", + "react-simulator-renderer": "../react-simulator-renderer/src/index.ts" }, "vendor": false, "devServer": { @@ -12,8 +13,6 @@ "react-dom": "var window.ReactDOM", "prop-types": "var window.PropTypes", "@alifd/next": "var window.Next", - "@ali/lowcode-editor-core": "var window.LCECore", - "@ali/visualengine": "var window.VisualEngine", "@ali/visualengine-utils": "var window.VisualEngineUtils" }, "plugins": [ diff --git a/tsconfig.json b/tsconfig.json index 339280c91..46a462b3b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -38,7 +38,8 @@ "skipLibCheck": true, "baseUrl": "./packages", "paths": { - "@ali/lowcode-*": ["./*/src"] + "@ali/lowcode-*": ["./*/src"], + "@ali/visualengine": ["./vision-preset/src"] }, "outDir": "lib" },