From 7f90b0baa58e99a1d727ca187efa5deb0308f3f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=8B=E7=BE=8A?= Date: Sun, 15 Mar 2020 19:13:39 +0800 Subject: [PATCH] daily tag --- packages/editor/.eslintrc.js | 6 +- packages/editor/src/config/assets.js | 186 ++++++++++-------- packages/editor/src/config/setters.ts | 12 +- packages/editor/src/config/skeleton.js | 118 +++++------ packages/editor/src/framework/areaManager.ts | 4 +- packages/editor/src/framework/definitions.ts | 24 +-- packages/editor/src/framework/editor.ts | 33 ++-- packages/editor/src/framework/index.d.ts | 4 - .../editor/src/framework/pluginFactory.tsx | 22 +-- packages/editor/src/framework/utils.ts | 18 +- packages/editor/src/index.tsx | 5 +- .../editor/src/plugins/designer/index.tsx | 12 +- packages/editor/src/plugins/logo/index.tsx | 13 +- .../editor/src/plugins/undoRedo/index.tsx | 60 +++--- .../skeleton/components/LeftPlugin/index.scss | 2 +- .../skeleton/components/LeftPlugin/index.tsx | 45 +++-- .../src/skeleton/components/Panel/index.tsx | 2 +- .../src/skeleton/components/TopIcon/index.tsx | 25 +-- .../skeleton/components/TopPlugin/index.tsx | 44 ++--- packages/editor/src/skeleton/global.scss | 1 - packages/editor/src/skeleton/index.tsx | 38 ++-- .../src/skeleton/layouts/CenterArea/index.tsx | 18 +- .../src/skeleton/layouts/LeftArea/nav.tsx | 73 ++++--- .../src/skeleton/layouts/LeftArea/panel.tsx | 30 +-- .../src/skeleton/layouts/RightArea/index.scss | 2 +- .../src/skeleton/layouts/RightArea/index.tsx | 81 ++++---- .../src/skeleton/layouts/TopArea/index.scss | 2 +- .../src/skeleton/layouts/TopArea/index.tsx | 44 +++-- 28 files changed, 497 insertions(+), 427 deletions(-) delete mode 100644 packages/editor/src/framework/index.d.ts diff --git a/packages/editor/.eslintrc.js b/packages/editor/.eslintrc.js index aa36c050d..4d6be3c66 100644 --- a/packages/editor/.eslintrc.js +++ b/packages/editor/.eslintrc.js @@ -4,9 +4,13 @@ module.exports = deepmerge(tslint, { rules: { "global-require": 0, "comma-dangle": 0, + "no-unused-expressions": 0, + "object-shorthand": 0, + "jsx-a11y/anchor-has-content": 0, "react/sort-comp": 0, "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx", "ts"] }], "@typescript-eslint/interface-name-prefix": 0, - "@typescript-eslint/no-explicit-any": 0 + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/explicit-member-accessibility": 0 }, }); diff --git a/packages/editor/src/config/assets.js b/packages/editor/src/config/assets.js index ce85f883e..5724f4742 100644 --- a/packages/editor/src/config/assets.js +++ b/packages/editor/src/config/assets.js @@ -5,7 +5,10 @@ export default { 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'], + 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' } }, @@ -13,114 +16,137 @@ export default { Button: { componentName: 'Button', title: '按钮', - devMode:'proCode', + devMode: 'proCode', npm: { package: '@alifd/next', version: '1.19.18', destructuring: true, exportName: 'Button' }, - props: [{ - name: 'type', - propType: 'string' - }, { - name: 'children', - propType: 'string' - }], - configure: { - props: [{ + props: [ + { name: 'type', - setter: { - componentName: 'Input' - } - }, { + propType: 'string' + }, + { name: 'children', - setter: { - componentName: 'Input' + propType: 'string' + } + ], + configure: { + props: [ + { + name: 'type', + setter: { + componentName: 'Input' + } + }, + { + name: 'children', + setter: { + componentName: 'Input' + } } - }] + ] } }, Input: { componentName: 'Input', title: '输入框', - devMode:'proCode', + devMode: 'proCode', npm: { package: '@alifd/next', version: '1.19.18', destructuring: true, exportName: 'Input' }, - props: [{ - name: 'placeholder', - propType: 'string' - }], - configure: { - props: [{ + props: [ + { name: 'placeholder', - setter: { - componentName: 'Input' + propType: 'string' + } + ], + configure: { + props: [ + { + name: 'placeholder', + setter: { + componentName: 'Input' + } } - }] + ] } } }, - componentList: [{ - title: '基础', - icon: '', - children: [{ - componentName: 'Button', - title: '按钮', + componentList: [ + { + title: '基础', icon: '', - package: '@alife/next', - snippets: [{ - title: 'private', - screenshort: '', - schema: { + children: [ + { componentName: 'Button', - props: { - type: 'primary' - }, - children: 'Primary' + title: '按钮', + icon: '', + package: '@alife/next', + snippets: [ + { + title: 'private', + screenshort: '', + schema: { + componentName: 'Button', + props: { + type: 'primary' + }, + children: 'Primary' + } + }, + { + title: 'secondary', + screenshort: '', + schema: { + componentName: 'Button', + props: { + type: 'secondary' + }, + children: 'secondary' + } + }, + { + title: 'normal', + screenshort: '', + schema: { + componentName: 'Button', + props: { + type: 'normal' + }, + children: 'normal' + } + } + ] } - }, { - title: 'secondary', - screenshort: '', - schema: { - componentName: 'Button', - props: { - type: 'secondary' - }, - children: 'secondary' - } - }, { - title: 'normal', - screenshort: '', - schema: { - componentName: 'Button', - props: { - type: 'normal' - }, - children: 'normal' - } - }] - }] - }, { - title: '表单', - icon: '', - children: [{ - componentName: 'Input', - title: '输入框', + ] + }, + { + title: '表单', icon: '', - package: '@alife/next', - snippets: [{ - title: '普通', - screenshort: '', - schema: { + children: [ + { componentName: 'Input', - props: {} + title: '输入框', + icon: '', + package: '@alife/next', + snippets: [ + { + title: '普通', + screenshort: '', + schema: { + componentName: 'Input', + props: {} + } + } + ] } - }] - }] - }] + ] + } + ] }; diff --git a/packages/editor/src/config/setters.ts b/packages/editor/src/config/setters.ts index 122792ca6..dc3ae6cb0 100644 --- a/packages/editor/src/config/setters.ts +++ b/packages/editor/src/config/setters.ts @@ -4,13 +4,17 @@ import { registerSetter } from '../../../plugin-settings/src'; import { createElement } from 'react'; registerSetter('ClassNameSetter', () => { - return createElement('div', { - className: 'lc-block-setter' - }, '这里是类名绑定'); + return createElement( + 'div', + { + className: 'lc-block-setter' + }, + '这里是类名绑定' + ); }); registerSetter('EventsSetter', Input); -registerSetter('StringSetter', { component: Input, props: { placeholder: "请输入" } }); +registerSetter('StringSetter', { component: Input, props: { placeholder: '请输入' } }); registerSetter('NumberSetter', NumberSetter as any); diff --git a/packages/editor/src/config/skeleton.js b/packages/editor/src/config/skeleton.js index 3e4c92b6e..e633f3a47 100644 --- a/packages/editor/src/config/skeleton.js +++ b/packages/editor/src/config/skeleton.js @@ -111,7 +111,7 @@ export default { title: 'icon', icon: 'dengpao', onClick(editor) { - alert(`icon addon invoke, current activeKey: ${ editor.activeKey}`); + alert(`icon addon invoke, current activeKey: ${editor.activeKey}`); } }, config: {}, @@ -128,8 +128,8 @@ export default { title: '组件库' }, config: { - package: "@ali/iceluna-addon-component-list", - version: "^1.0.4" + package: '@ali/iceluna-addon-component-list', + version: '^1.0.4' }, pluginProps: { disableAppComponent: true @@ -218,7 +218,7 @@ export default { title: 'icon', icon: 'dengpao', onClick(editor) { - alert(`icon addon invoke, current activeKey: ${ editor.activeKey}`); + alert(`icon addon invoke, current activeKey: ${editor.activeKey}`); } }, config: {}, @@ -234,52 +234,52 @@ export default { version: '^1.0.0' }, pluginProps: {} - }, - { - pluginKey: 'rightPanel1', - type: 'TabPanel', - props: { - title: '样式' - }, - config: { - version: '^1.0.0' - }, - pluginProps: {} - }, - { - pluginKey: 'rightPanel2', - type: 'TabPanel', - props: { - title: '属性', - icon: 'dengpao' - }, - config: { - version: '^1.0.0' - }, - pluginProps: {} - }, - { - pluginKey: 'rightPanel3', - type: 'TabPanel', - props: { - title: '事件' - }, - config: { - version: '^1.0.0' - }, - pluginProps: {} - }, - { - pluginKey: 'rightPanel4', - type: 'TabPanel', - props: { - title: '数据' - }, - config: { - version: '^1.0.0' - }, - pluginProps: {} } + // { + // pluginKey: 'rightPanel1', + // type: 'TabPanel', + // props: { + // title: '样式' + // }, + // config: { + // version: '^1.0.0' + // }, + // pluginProps: {} + // }, + // { + // pluginKey: 'rightPanel2', + // type: 'TabPanel', + // props: { + // title: '属性', + // icon: 'dengpao' + // }, + // config: { + // version: '^1.0.0' + // }, + // pluginProps: {} + // }, + // { + // pluginKey: 'rightPanel3', + // type: 'TabPanel', + // props: { + // title: '事件' + // }, + // config: { + // version: '^1.0.0' + // }, + // pluginProps: {} + // }, + // { + // pluginKey: 'rightPanel4', + // type: 'TabPanel', + // props: { + // title: '数据' + // }, + // config: { + // version: '^1.0.0' + // }, + // pluginProps: {} + // } ], centerArea: [ { @@ -295,7 +295,7 @@ export default { shortCuts: [], lifeCycles: { init: function init(editor) { - const transformMaterial = (componentList) => { + const transformMaterial = componentList => { return componentList.map(category => { return { name: category.title, @@ -318,17 +318,25 @@ export default { }; const list = transformMaterial(assets.componentList); - console.log('+++++', list); editor.set({ componentsMap: assets.components, componentMaterial: { - library: [{ - name: 'Fusion组件库', - id: 1 - }], + library: [ + { + name: 'Fusion组件库', + id: 1 + } + ], list } }); + + editor.set('dndHelper', { + handleResourceDragStart: function(ev, tagName, schema) { + // 物料面板中组件snippet的dragStart回调 + // ev: 原始的domEvent;tagName: 组件的描述文案;schema: snippet的schema + } + }); } } }; diff --git a/packages/editor/src/framework/areaManager.ts b/packages/editor/src/framework/areaManager.ts index 1a943d310..28f24eb0e 100644 --- a/packages/editor/src/framework/areaManager.ts +++ b/packages/editor/src/framework/areaManager.ts @@ -22,7 +22,9 @@ export default class AreaManager { 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])); + const isUpdate = list.some( + (item): boolean => !deepEqual(pluginStatus[item.pluginKey], this.pluginStatus[item.pluginKey]) + ); this.pluginStatus = clone(pluginStatus); return isUpdate; } diff --git a/packages/editor/src/framework/definitions.ts b/packages/editor/src/framework/definitions.ts index 5780d7f41..6bc6d2653 100644 --- a/packages/editor/src/framework/definitions.ts +++ b/packages/editor/src/framework/definitions.ts @@ -106,34 +106,37 @@ export interface I18nConfig { 'ja-JP'?: I18nMessages; } -export type I18nFunction = (key: string, params: any) => string | string[]; +export type I18nFunction = (key: string, params: any) => string; export interface Utils { [key: string]: (...args) => any; } - export interface PluginProps { editor: Editor; config: PluginConfig; - i18n: I18nFunction; - ref?: React.RefObject; + i18n?: I18nFunction; + ref?: React.RefObject; [key: string]: any; } - export type Plugin = React.ReactNode & { - open?: () => boolean| void| Promise; - close?: () => boolean| void| Promise; -} + open?: () => boolean | void | Promise; + close?: () => boolean | void | Promise; +}; + +export type HOCPlugin = React.ReactNode & { + open: () => Promise; + close: () => Promise; +}; export interface PluginSet { - [key: string]: Plugin; + [key: string]: HOCPlugin; } export type PluginClass = React.ComponentType & { init?: (editor: Editor) => void; -} +}; export interface PluginClassSet { [key: string]: PluginClass; @@ -149,4 +152,3 @@ export interface PluginStatus { export interface PluginStatusSet { [key: string]: PluginStatus; } - diff --git a/packages/editor/src/framework/editor.ts b/packages/editor/src/framework/editor.ts index 31ffaf071..cf1147e2c 100644 --- a/packages/editor/src/framework/editor.ts +++ b/packages/editor/src/framework/editor.ts @@ -1,13 +1,26 @@ import Debug from 'debug'; import EventEmitter from 'events'; import store from 'store'; -import { EditorConfig, HooksConfig, LocaleType, PluginStatusSet, Utils, PluginClassSet, PluginSet } from './definitions'; +import { + EditorConfig, + HooksConfig, + LocaleType, + PluginStatusSet, + Utils, + PluginClassSet, + PluginSet +} from './definitions'; import * as editorUtils from './utils'; -const { - registShortCuts, transformToPromise, unRegistShortCuts -} = editorUtils; +const { registShortCuts, transformToPromise, unRegistShortCuts } = editorUtils; + +declare global { + interface Window { + __isDebug?: boolean; + __newFunc?: (funcStr: string) => (...args: any[]) => any; + } +} // 根据url参数设置debug选项 const debugRegRes = /_?debug=(.*?)(&|$)/.exec(location.search); @@ -16,6 +29,7 @@ if (debugRegRes && debugRegRes[1]) { window.__isDebug = true; store.storage.write('debug', debugRegRes[1] === 'true' ? '*' : debugRegRes[1]); } else { + // eslint-disable-next-line no-underscore-dangle window.__isDebug = false; store.remove('debug'); } @@ -23,13 +37,12 @@ if (debugRegRes && debugRegRes[1]) { // 重要,用于矫正画布执行new Function的window对象上下文 // eslint-disable-next-line no-underscore-dangle window.__newFunc = (funContext: string): ((...args: any[]) => any) => { - return new Function(funContext); + // eslint-disable-next-line no-new-func + return new Function(funContext) as (...args: any[]) => any; }; - - // 关闭浏览器前提醒,只有产生过交互才会生效 -window.onbeforeunload = function(e: Event): string|void { +window.onbeforeunload = function(e: Event): string | void { const ev = e || window.event; // 本地调试不生效 if (location.href.indexOf('localhost') > 0) { @@ -72,7 +85,6 @@ export default class Editor extends EventEmitter { public plugins: PluginSet; - public locale: LocaleType; public emit: (msg: string, ...args) => void; @@ -89,7 +101,7 @@ export default class Editor extends EventEmitter { super(); this.config = config; this.components = components; - this.utils = {...editorUtils, ...utils}; + this.utils = { ...editorUtils, ...utils }; instance = this; this.init(); } @@ -128,7 +140,6 @@ export default class Editor extends EventEmitter { } } catch (err) { console.warn(err); - } } diff --git a/packages/editor/src/framework/index.d.ts b/packages/editor/src/framework/index.d.ts deleted file mode 100644 index 369e95da7..000000000 --- a/packages/editor/src/framework/index.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -interface Window { - __isDebug?: boolean; - __newFunc?: (funcStr: string) => ((...args: any[]) => any); -} \ No newline at end of file diff --git a/packages/editor/src/framework/pluginFactory.tsx b/packages/editor/src/framework/pluginFactory.tsx index d5298b913..f32edd9e9 100644 --- a/packages/editor/src/framework/pluginFactory.tsx +++ b/packages/editor/src/framework/pluginFactory.tsx @@ -1,30 +1,19 @@ import React, { createRef, PureComponent } from 'react'; import EditorContext from './context'; -import { I18nFunction, PluginConfig, PluginClass, Plugin } from './definitions'; +import { I18nFunction, PluginProps, PluginClass, Plugin } from './definitions'; import Editor from './editor'; import { acceptsRef, generateI18n, isEmpty, transformToPromise } from './utils'; -export interface PluginProps { - editor: Editor; - config: PluginConfig; -} - -export interface InjectedPluginProps { - i18n?: I18nFunction; -} - -export default function pluginFactory( - Comp: PluginClass -): React.ComponentType { +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; + + public ref: React.RefObject & Plugin; private editor: Editor; @@ -39,7 +28,7 @@ export default function pluginFactory( return; } const { locale, messages, editor } = props; - this.ref = createRef(); + this.ref = createRef(); // 注册插件 this.editor = editor; this.i18n = generateI18n(locale, messages); @@ -71,7 +60,6 @@ export default function pluginFactory( return Promise.resolve(); }; - public render(): React.ReactNode { const { config } = this.props; const props = { diff --git a/packages/editor/src/framework/utils.ts b/packages/editor/src/framework/utils.ts index 13cd26f80..aced7d318 100644 --- a/packages/editor/src/framework/utils.ts +++ b/packages/editor/src/framework/utils.ts @@ -28,6 +28,17 @@ const ENV = { 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: { @@ -37,16 +48,11 @@ export interface IDEMessageParams { }; } -export interface Window { - sendIDEMessage: (msg: IDEMessageParams) => void; - is_theia?: boolean; -} - /* * 用于构造国际化字符串处理函数 */ export function generateI18n(locale: LocaleType = 'zh-CN', messages: I18nMessages = {}): I18nFunction { - return (key: string, values): string | string[] => { + return (key: string, values): string => { if (!messages || !messages[key]) { return ''; } diff --git a/packages/editor/src/index.tsx b/packages/editor/src/index.tsx index f93e9b0e5..22e76df35 100644 --- a/packages/editor/src/index.tsx +++ b/packages/editor/src/index.tsx @@ -10,12 +10,9 @@ import constants from './config/constants'; import './config/locale'; import './config/setters'; -import pkg from '../package.json'; import './global.scss'; import './config/theme.scss'; -(window as any).__pkg = pkg; - const ICE_CONTAINER = document.getElementById('ice-container'); if (!ICE_CONTAINER) { @@ -26,7 +23,7 @@ ReactDOM.render( ( + component={(props): React.ReactNode => ( { - static displayName: 'LowcodePluginDesigner'; - - constructor(props) { - super(props); - } + displayName: 'LowcodePluginDesigner'; handleDesignerMount = (designer): void => { - const {editor} = this.props; + const { editor } = this.props; editor.set('designer', designer); editor.emit('designer.ready', designer); - } + }; - render() { + render(): React.ReactNode { const { editor } = this.props; return ( = (props): React.ReactElement => { return ( ); -} +}; + +export default Logo; diff --git a/packages/editor/src/plugins/undoRedo/index.tsx b/packages/editor/src/plugins/undoRedo/index.tsx index d311eb68d..0def89cfe 100644 --- a/packages/editor/src/plugins/undoRedo/index.tsx +++ b/packages/editor/src/plugins/undoRedo/index.tsx @@ -1,70 +1,74 @@ import React, { PureComponent } from 'react'; import './index.scss'; -import Editor from '../../framework/index'; -import { PluginConfig } from '../../framework/definitions'; +import { PluginProps } from '../../framework/definitions'; import TopIcon from '../../skeleton/components/TopIcon/index'; -export interface PluginProps { - editor: Editor; - config: PluginConfig; +export interface IProps { logo?: string; } -export interface PluginState{ - backEnable: boolean; - forwardEnable: boolean; -}; +export interface IState { + undoEnable: boolean; + redoEnable: boolean; +} +export default class UndoRedo extends PureComponent { + public static display = 'LowcodeUndoRedo'; -export default class UndoRedo extends PureComponent { - static display = 'LowcodeUndoRedo'; + private history: any; constructor(props) { super(props); this.state = { - backEnable: false, - forwardEnable: false + undoEnable: false, + redoEnable: false }; if (props.editor.designer) { this.init(); } else { - props.editor.on('designer.ready', () => { + props.editor.on('designer.ready', (): void => { this.init(); }); } - } init = (): void => { - const {editor} = this.props; - this.designer = editor.designer; - this.history = this.designer.currentHistory; - editor.on('designer.history-change', (history) => { + const { editor } = this.props; + this.history = editor.designer.currentHistory; + this.updateState(this.history.getState()); + editor.on('designer.history-change', (history): void => { this.history = history; + this.history.onStateChange(this.updateState); + }); + this.history.onStateChange(this.updateState); + }; + + updateState = (state: number): void => { + console.log('++++', !!(state & 1), !!(state & 2)); + this.setState({ + undoEnable: !!(state & 1), + redoEnable: !!(state & 2) }); }; - handleBackClick = (): void => { + handleUndoClick = (): void => { if (this.history) { this.history.back(); } }; - handleForwardClick = (): void => { + handleRedoClick = (): void => { if (this.history) { this.history.forward(); } }; - render() { - const { - backEnable, - forwardEnable - } = this.state; + render(): React.ReactNode { + const { undoEnable, redoEnable } = this.state; return (
- - + +
); } diff --git a/packages/editor/src/skeleton/components/LeftPlugin/index.scss b/packages/editor/src/skeleton/components/LeftPlugin/index.scss index d237581b0..f1e7876d3 100644 --- a/packages/editor/src/skeleton/components/LeftPlugin/index.scss +++ b/packages/editor/src/skeleton/components/LeftPlugin/index.scss @@ -45,7 +45,7 @@ } &:hover { color: $color-brand1-6; - } + } } &.disabled { cursor: not-allowed; diff --git a/packages/editor/src/skeleton/components/LeftPlugin/index.tsx b/packages/editor/src/skeleton/components/LeftPlugin/index.tsx index a2cfe1571..eafe894ee 100644 --- a/packages/editor/src/skeleton/components/LeftPlugin/index.tsx +++ b/packages/editor/src/skeleton/components/LeftPlugin/index.tsx @@ -30,7 +30,7 @@ export default class LeftPlugin extends PureComponent {} + onClick: (): void => {} }; constructor(props, context) { @@ -40,7 +40,7 @@ export default class LeftPlugin extends PureComponent { + handleClose = (): void => { const { config, editor } = this.props; const pluginKey = config && config.pluginKey; const plugin = editor.plugins && editor.plugins[pluginKey]; - if (plugin) { - plugin.close().then(() => { + if (plugin && plugin.close) { + plugin.close().then((): void => { this.setState({ dialogVisible: false }); @@ -71,24 +71,26 @@ export default class LeftPlugin extends PureComponent { + handleOpen = (): void => { // todo 对话框类型的插件初始时拿不到插件实例 this.setState({ dialogVisible: true }); }; - handleShow = () => { + handleShow = (): void => { const { disabled, config, onClick, editor } = this.props; const pluginKey = config && config.pluginKey; if (disabled || !pluginKey) return; // 考虑到弹窗情况,延时发送消息 - setTimeout(() => editor.emit(`${pluginKey}.addon.activate`), 0); + setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0); this.handleOpen(); - onClick && onClick(); + if (onClick) { + onClick(); + } }; - renderIcon = clickCallback => { + renderIcon = (clickCallback): React.ReactNode => { const { active, disabled, marked, locked, onClick, config } = this.props; const { pluginKey, props } = config || {}; const { icon, title } = props || {}; @@ -100,10 +102,11 @@ export default class LeftPlugin extends PureComponent { + onClick={(): void => { if (disabled) return; // 考虑到弹窗情况,延时发送消息 clickCallback && clickCallback(); + onClick && onClick(); }} > @@ -118,7 +121,7 @@ export default class LeftPlugin extends PureComponent { + onClick={(): void => { onClick && onClick.call(null, editor); }} {...pluginProps} @@ -145,24 +148,24 @@ export default class LeftPlugin extends PureComponent - {this.renderIcon(() => { + {this.renderIcon((): void => { onClick && onClick.call(null, editor); })}
); case 'Icon': - return this.renderIcon(() => { + return this.renderIcon((): void => { onClick && onClick.call(null, editor); }); case 'DialogIcon': return ( - {this.renderIcon(() => { + {this.renderIcon((): void => { onClick && onClick.call(null, editor); this.handleOpen(); })} { + onOk={(): void => { editor.emit(`${pluginKey}.dialog.onOk`); this.handleClose(); }} @@ -171,7 +174,7 @@ export default class LeftPlugin extends PureComponent { + trigger={this.renderIcon((): void => { onClick && onClick.call(null, editor); })} align="r" @@ -194,7 +197,7 @@ export default class LeftPlugin extends PureComponent ); case 'PanelIcon': - return this.renderIcon(() => { + return this.renderIcon((): void => { onClick && onClick.call(null, editor); this.handleOpen(); }); diff --git a/packages/editor/src/skeleton/components/Panel/index.tsx b/packages/editor/src/skeleton/components/Panel/index.tsx index a1b9a9a8e..611877d46 100644 --- a/packages/editor/src/skeleton/components/Panel/index.tsx +++ b/packages/editor/src/skeleton/components/Panel/index.tsx @@ -37,7 +37,7 @@ export default class Panel extends PureComponent { }; } - render() { + render(): React.ReactNode { const { align, draggable, floatable, visible } = this.props; const { width } = this.state; return ( diff --git a/packages/editor/src/skeleton/components/TopIcon/index.tsx b/packages/editor/src/skeleton/components/TopIcon/index.tsx index 40750d03a..2c14d8d33 100644 --- a/packages/editor/src/skeleton/components/TopIcon/index.tsx +++ b/packages/editor/src/skeleton/components/TopIcon/index.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import classNames from 'classnames'; -import { Icon, Button } from '@alifd/next'; +import { Icon } from '@alifd/next'; import './index.scss'; @@ -27,22 +27,25 @@ export default class TopIcon extends PureComponent { icon: '', id: '', locked: false, - onClick: () => {}, + onClick: (): void => {}, style: {}, title: '' }; - render() { + render(): React.ReactNode { const { active, disabled, icon, locked, title, className, id, style, onClick } = this.props; return ( -
+
); diff --git a/packages/editor/src/skeleton/components/TopPlugin/index.tsx b/packages/editor/src/skeleton/components/TopPlugin/index.tsx index e51893b15..70c653f4f 100644 --- a/packages/editor/src/skeleton/components/TopPlugin/index.tsx +++ b/packages/editor/src/skeleton/components/TopPlugin/index.tsx @@ -1,4 +1,4 @@ -import React, { PureComponent, Fragment } from 'react'; +import React, { PureComponent, Fragment, CSSProperties } from 'react'; import { Balloon, Badge, Dialog } from '@alifd/next'; import TopIcon from '../TopIcon'; @@ -31,7 +31,7 @@ export default class TopPlugin extends PureComponent {} + onClick: (): void => {} }; constructor(props, context) { @@ -41,7 +41,7 @@ export default class TopPlugin extends PureComponent { + handleShow = (): void => { const { disabled, config, onClick, editor } = this.props; const pluginKey = config && config.pluginKey; if (disabled || !pluginKey) return; // 考虑到弹窗情况,延时发送消息 - setTimeout(() => editor.emit(`${pluginKey}.plugin.activate`), 0); + setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0); this.handleOpen(); onClick && onClick(); }; - 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(() => { + if (plugin && plugin.close) { + plugin.close().then((): void => { this.setState({ dialogVisible: false }); @@ -82,14 +82,14 @@ export default class TopPlugin extends PureComponent { + handleOpen = (): void => { // todo dialog类型的插件初始时拿不动插件实例 this.setState({ dialogVisible: true }); }; - renderIcon = clickCallback => { + renderIcon = (clickCallback): React.ReactNode => { const { active, disabled, marked, locked, config, onClick, editor } = this.props; const { pluginKey, props } = config || {}; const { icon, title } = props || {}; @@ -101,10 +101,10 @@ export default class TopPlugin extends PureComponent { + onClick={(): void => { if (disabled) return; // 考虑到弹窗情况,延时发送消息 - setTimeout(() => editor.emit(`${pluginKey}.plugin.activate`), 0); + setTimeout((): void => editor.emit(`${pluginKey}.plugin.activate`), 0); clickCallback && clickCallback(); onClick && onClick(); }} @@ -113,8 +113,8 @@ export default class TopPlugin extends PureComponent{node} : node; }; - render() { - const { active, marked, locked, disabled, config, editor, pluginClass: Comp } = this.props; + render(): React.ReactNode { + const { active, marked, locked, disabled, config, editor, pluginClass: Comp, style } = this.props; const { pluginKey, pluginProps, props, type } = config || {}; const { onClick, title } = props || {}; const { dialogVisible } = this.state; @@ -127,7 +127,7 @@ export default class TopPlugin extends PureComponent { + onClick={(): void => { onClick && onClick.call(null, editor); }} {...pluginProps} @@ -139,24 +139,24 @@ export default class TopPlugin extends PureComponent - {this.renderIcon(() => { + {this.renderIcon((): void => { onClick && onClick.call(null, editor); })} ); case 'Icon': - return this.renderIcon(() => { + return this.renderIcon((): void => { onClick && onClick.call(null, editor); }); case 'DialogIcon': return ( - {this.renderIcon(() => { + {this.renderIcon((): void => { onClick && onClick.call(null, editor); this.handleOpen(); })} { + onOk={(): void => { editor.emit(`${pluginKey}.dialog.onOk`); this.handleClose(); }} @@ -165,7 +165,7 @@ export default class TopPlugin extends PureComponent { + trigger={this.renderIcon((): void => { onClick && onClick.call(null, editor); })} triggerType={['click', 'hover']} diff --git a/packages/editor/src/skeleton/global.scss b/packages/editor/src/skeleton/global.scss index 8eb107e0f..72f7b8525 100644 --- a/packages/editor/src/skeleton/global.scss +++ b/packages/editor/src/skeleton/global.scss @@ -9,7 +9,6 @@ body { color: $color-text1-3; } - .next-loading { .next-loading-wrap { height: 100%; diff --git a/packages/editor/src/skeleton/index.tsx b/packages/editor/src/skeleton/index.tsx index c6eee9f53..c30a0fc88 100644 --- a/packages/editor/src/skeleton/index.tsx +++ b/packages/editor/src/skeleton/index.tsx @@ -1,10 +1,9 @@ import React, { PureComponent } from 'react'; -import { HashRouter as Router, Route } from 'react-router-dom'; import { Loading, ConfigProvider } from '@alifd/next'; import Editor from '../framework/editor'; -import { EditorConfig, Utils, PluginComponents } from '../framework/definitions'; +import { EditorConfig, Utils, PluginClassSet } from '../framework/definitions'; import { comboEditorConfig, parseSearch } from '../framework/utils'; import defaultConfig from './config/skeleton'; @@ -19,8 +18,17 @@ import './global.scss'; let renderIdx = 0; +declare global { + interface Window { + __ctx: { + editor: Editor; + appHelper: Editor; + }; + } +} + export interface SkeletonProps { - components: PluginComponents; + components: PluginClassSet; config: EditorConfig; history: object; location: object; @@ -29,15 +37,15 @@ export interface SkeletonProps { } export interface SkeletonState { - initReady: boolean; - skeletonKey: string; + initReady?: boolean; + skeletonKey?: string; __hasError?: boolean; } export default class Skeleton extends PureComponent { static displayName = 'LowcodeEditorSkeleton'; - static getDerivedStateFromError() { + static getDerivedStateFromError(): SkeletonState { return { __hasError: true }; @@ -56,11 +64,11 @@ export default class Skeleton extends PureComponent { + editor.once('editor.reset', (): void => { this.setState({ initReady: false }); @@ -85,14 +95,14 @@ export default class Skeleton extends PureComponent { + this.editor.init().then((): void => { this.setState( { initReady: true, // 刷新IDE时生成新的skeletonKey保证插件生命周期重新执行 skeletonKey: isReset ? `skeleton${++renderIdx}` : this.state.skeletonKey }, - () => { + (): void => { editor.emit('editor.ready'); editor.emit('ide.ready'); isReset && editor.emit('ide.afterReset'); @@ -101,7 +111,7 @@ export default class Skeleton extends PureComponent { static displayName = 'LowcodeCenterArea'; private editor: Editor; + private areaManager: AreaManager; constructor(props) { @@ -20,10 +21,11 @@ export default class CenterArea extends PureComponent { this.areaManager = new AreaManager(this.editor, 'centerArea'); } - componentDidMount() { + componentDidMount(): void { this.editor.on('skeleton.update', this.handleSkeletonUpdate); } - componentWillUnmount() { + + componentWillUnmount(): void { this.editor.off('skeleton.update', this.handleSkeletonUpdate); } @@ -34,14 +36,16 @@ export default class CenterArea extends PureComponent { } }; - render() { + render(): React.ReactNode { const visiblePluginList = this.areaManager.getVisiblePluginList(); return (
- {visiblePluginList.map(item => { - const Comp = this.editor.components[item.pluginKey]; - return ; - })} + {visiblePluginList.map( + (item): React.ReactNode => { + const Comp = this.editor.components[item.pluginKey]; + return ; + } + )}
); } diff --git a/packages/editor/src/skeleton/layouts/LeftArea/nav.tsx b/packages/editor/src/skeleton/layouts/LeftArea/nav.tsx index 61ba3791a..cd749073a 100644 --- a/packages/editor/src/skeleton/layouts/LeftArea/nav.tsx +++ b/packages/editor/src/skeleton/layouts/LeftArea/nav.tsx @@ -21,7 +21,7 @@ export default class LeftAreaNav extends PureComponent item.type === 'IconPanel'); @@ -42,7 +42,7 @@ export default class LeftAreaNav extends PureComponent { + nextPlugin.open().then((): void => { this.updateActiveKey(key); }); } } else if (activeKey === key) { if (prePlugin) { - prePlugin.close().then(() => { + prePlugin.close().then((): void => { this.updateActiveKey('none'); }); } - } else { + } else if (prePlugin) { // 先关后开 - if (prePlugin) { - prePlugin.close().then(() => { - if (nextPlugin) { - nextPlugin.open().then(() => { - this.updateActiveKey(key); - }); - } - }); - } + prePlugin.close().then((): void => { + if (nextPlugin) { + nextPlugin.open().then((): void => { + this.updateActiveKey(key); + }); + } + }); } }; @@ -111,9 +109,9 @@ export default class LeftAreaNav extends PureComponent { - if (key === 'none') { - this.cacheActiveKey = this.state.activeKey; - } + // if (key === 'none') { + // this.cacheActiveKey = this.state.activeKey; + // } this.editor.set('leftNav', key); this.setState({ activeKey: key }); this.editor.emit('leftPanel.show', key); @@ -121,31 +119,32 @@ export default class LeftAreaNav extends PureComponent { const { activeKey } = this.state; - return list.map((item, idx) => { - const pluginStatus = this.editor.pluginStatus[item.pluginKey]; - return ( - this.handlePluginClick(item)} - active={activeKey === item.pluginKey} - {...pluginStatus} - /> - ); - }); + return list.map( + (item): React.ReactElement => { + const pluginStatus = this.editor.pluginStatus[item.pluginKey]; + return ( + this.handlePluginClick(item)} + active={activeKey === item.pluginKey} + {...pluginStatus} + /> + ); + } + ); }; - render() { - const { activeKey } = this.state; + render(): React.ReactNode { const topList: PluginConfig[] = []; const bottomList: PluginConfig[] = []; const visiblePluginList = this.areaManager.getVisiblePluginList(); - if (isEmpty(visiblePluginList)){ + if (isEmpty(visiblePluginList)) { return null; } - visiblePluginList.forEach(item => { + visiblePluginList.forEach((item): void => { const align = item.props && item.props.align === 'bottom' ? 'bottom' : 'top'; if (align === 'bottom') { bottomList.push(item); diff --git a/packages/editor/src/skeleton/layouts/LeftArea/panel.tsx b/packages/editor/src/skeleton/layouts/LeftArea/panel.tsx index 281e23246..31f2c5343 100644 --- a/packages/editor/src/skeleton/layouts/LeftArea/panel.tsx +++ b/packages/editor/src/skeleton/layouts/LeftArea/panel.tsx @@ -16,6 +16,7 @@ export default class LeftAreaPanel extends PureComponent - {list.map((item, idx) => { - const Comp = this.editor.components[item.pluginKey]; - return ( - - - - ); - })} + {list.map( + (item): React.ReactElement => { + const Comp = this.editor.components[item.pluginKey]; + return ( + + + + ); + } + )}
); } diff --git a/packages/editor/src/skeleton/layouts/RightArea/index.scss b/packages/editor/src/skeleton/layouts/RightArea/index.scss index 563179f02..7373933b0 100644 --- a/packages/editor/src/skeleton/layouts/RightArea/index.scss +++ b/packages/editor/src/skeleton/layouts/RightArea/index.scss @@ -6,7 +6,7 @@ .right-panel { overflow: auto; - border-top: 2px solid $color-line1-1; + // border-top: 2px solid $color-line1-1; } //tab定义 diff --git a/packages/editor/src/skeleton/layouts/RightArea/index.tsx b/packages/editor/src/skeleton/layouts/RightArea/index.tsx index 8f23ba2a3..64c44af50 100644 --- a/packages/editor/src/skeleton/layouts/RightArea/index.tsx +++ b/packages/editor/src/skeleton/layouts/RightArea/index.tsx @@ -30,7 +30,7 @@ export default class RightArea extends PureComponent { + currentPlugin.close().then((): void => { this.setState( { activeKey: '' }, - () => { + (): void => { const visiblePluginList = this.areaManager.getVisiblePluginList(); const firstPlugin = visiblePluginList && visiblePluginList[0]; if (firstPlugin) { @@ -75,12 +75,12 @@ export default class RightArea extends PureComponent { const activeKey = this.state.activeKey; const plugins = this.editor.plugins || {}; - const openPlugin = () => { + const openPlugin = (): void => { if (!plugins[key]) { console.error(`plugin ${key} has not regist in the editor`); return; } - plugins[key].open().then(() => { + plugins[key].open().then((): void => { this.editor.set('rightNav', key); this.setState({ activeKey: key @@ -89,7 +89,7 @@ export default class RightArea extends PureComponent { + plugins[activeKey].close().then((): void => { openPlugin(); }); } else { @@ -109,12 +109,7 @@ export default class RightArea extends PureComponent - {!!icon && ( - - )} + {!!icon && } {title}
); @@ -124,7 +119,7 @@ export default class RightArea extends PureComponent { + renderTabPanels = (list: PluginConfig[], height: string): React.ReactNode => { if (isEmpty(list)) { return null; } @@ -138,37 +133,41 @@ export default class RightArea extends PureComponent - {list.map((item, idx) => { - const Comp = this.editor.components[item.pluginKey]; - return ( - - - - ); - })} + {list.map( + (item): React.ReactElement => { + const Comp = this.editor.components[item.pluginKey]; + return ( + + + + ); + } + )} ); - } + }; - renderPanels = (list: PluginConfig[], height: string): void => { - return list.map((item) => { - const Comp = this.editor.components[item.pluginKey]; - return ( -
- -
- ); - }); - } + renderPanels = (list: PluginConfig[], height: string): React.ReactNode => { + return list.map( + (item): React.ReactElement => { + const Comp = this.editor.components[item.pluginKey]; + return ( +
+ +
+ ); + } + ); + }; - render() { + render(): React.ReactNode { const tabList = this.areaManager.getVisiblePluginList('TabPanel'); const panelList = this.areaManager.getVisiblePluginList('Panel'); if (isEmpty(panelList) && isEmpty(tabList)) { diff --git a/packages/editor/src/skeleton/layouts/TopArea/index.scss b/packages/editor/src/skeleton/layouts/TopArea/index.scss index 10669ba51..a22456894 100644 --- a/packages/editor/src/skeleton/layouts/TopArea/index.scss +++ b/packages/editor/src/skeleton/layouts/TopArea/index.scss @@ -4,7 +4,7 @@ left: 0; width: 100%; height: 50px; - background-color: $card-background; + background-color: $card-background; border-bottom: 2px solid $color-line1-1; user-select: none; .divider { diff --git a/packages/editor/src/skeleton/layouts/TopArea/index.tsx b/packages/editor/src/skeleton/layouts/TopArea/index.tsx index 39adbb825..d6b33453c 100644 --- a/packages/editor/src/skeleton/layouts/TopArea/index.tsx +++ b/packages/editor/src/skeleton/layouts/TopArea/index.tsx @@ -25,11 +25,11 @@ export default class TopArea extends PureComponent { this.areaManager = new AreaManager(props.editor, 'topArea'); } - componentDidMount() { + componentDidMount(): void { this.editor.on('skeleton.update', this.handleSkeletonUpdate); } - componentWillUnmount() { + componentWillUnmount(): void { this.editor.off('skeleton.update', this.handleSkeletonUpdate); } @@ -41,30 +41,32 @@ export default class TopArea extends PureComponent { }; renderPluginList = (list: PluginConfig[] = []): React.ReactElement[] => { - return list.map((item, idx) => { - const isDivider = item.type === 'Divider'; - return ( - - {!isDivider && ( - - )} - - ); - }); + return list.map( + (item, idx): React.ReactElement => { + const isDivider = item.type === 'Divider'; + return ( + + {!isDivider && ( + + )} + + ); + } + ); }; - render() { + render(): React.ReactNode { const leftList: PluginConfig[] = []; const rightList: PluginConfig[] = []; const visiblePluginList = this.areaManager.getVisiblePluginList(); - visiblePluginList.forEach(item => { + visiblePluginList.forEach((item): void => { const align = item.props && item.props.align === 'right' ? 'right' : 'left'; // 分隔符不允许相邻 if (item.type === 'Divider') {