import React, { PureComponent, Fragment } from 'react'; import { Balloon, Badge, Dialog } from '@alifd/next'; import Editor from '@ali/lowcode-editor-framework'; import { PluginConfig, PluginClass, } from '@ali/lowcode-editor-framework/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; } } }