alibaba / GGEditor

A visual graph editor based on G6 and React
https://ggeditor.com
MIT License
3.41k stars 573 forks source link

Command有没有办法告诉它的父(祖先)组件当前命令不可用? #77

Open Yeung2017 opened 5 years ago

Yeung2017 commented 5 years ago

问题描述:

因为我的右键菜单会有二级菜单,故选用了antd.Menu来实现相关功能. 而目前Command作为Menu.Item的子组件,当Command为不可用状态时,Menu.Item不能知道Command当前的状态. 虽然Command组件上会添上disable类,可以通过css来修改样式,但是在这种情况下修改的样式过多,且很可能破坏Menu.Item的样式.

问题截图:

image

理想的状态是:

Menu.Item能够知道Command当前不可用,从而直接设置Menu.Item的disabled属性为true

次理想的状态:

当Command不能用的时候,能够在父(祖先)添加对应的类,从而更方便的书写css代码.

相关代码

ProcessEditorContextMenu.js

// 库引入
import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import classNames from 'classnames';
import { ContextMenu, NodeMenu, CanvasMenu, EdgeMenu, Command } from 'gg-editor';
import { Menu, Icon } from 'antd';

//组件引入
import { IconFont } from '../../../../components/IconFont';

// 样式引入
import styles from './style.module.less';

// 一些值
const { Item: MenuItem } = Menu;

/**
 * Editor的右键菜单
 * 考虑到可能会有二级菜单,故使用antd.Menu
 */
@observer
class ProcessEditorContextMenu extends Component {
  render() {
    return (
      <ContextMenu className={ classNames(styles.processEditorContextMenu, this.props.className) } style={ this.props.style }>
        {/* 节点的右键菜单 */ }
        <NodeMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="copy"><Icon type="copy" theme="outlined" /><span>复制</span></Command></MenuItem>
            <MenuItem><Command name="delete"><Icon type="delete" theme="outlined" /><span>删除</span></Command></MenuItem>
          </Menu>
        </NodeMenu>
        {/* 画布的右键菜单 */ }
        <CanvasMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="undo"><Icon type="undo" theme="outlined" /><span>撤销</span></Command></MenuItem>
            <MenuItem><Command name="redo"><Icon type="redo" theme="outlined" /><span>重做</span></Command></MenuItem>
            <MenuItem><Command name="pasteHere"><IconFont type="icon-paste" /><span>粘贴</span></Command></MenuItem>
          </Menu>
        </CanvasMenu>
        {/* 连线的右键菜单 */ }
        <EdgeMenu>
          <Menu
            mode="vertical"
            selectable={ false }>
            <MenuItem><Command name="delete"><Icon type="delete" theme="outlined" /><span>删除</span></Command></MenuItem>
          </Menu>
        </EdgeMenu>
      </ContextMenu>
    );
  }
}

ProcessEditorContextMenu.defaultProps = {
};

const InjectProcessEditorContextMenu = inject(({ someStore = {} }) => ({ someProps: someStore.attribute }))(ProcessEditorContextMenu);

export {
  ProcessEditorContextMenu,
  InjectProcessEditorContextMenu
};

style.module.less

.processEditorContextMenu {
  // 默认是不可见的,除非右键点击
  display: none;
  :global {
    .ant-menu {
      border: none;
      border-radius: 4px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
    }
    // :has不管用现在
    .ant-menu-item:has(.disable) {
      color: red;
    }
  }
}
Yeung2017 commented 5 years ago

目前还是采用的直接修改css的办法控制不可用样式

.processEditorContextMenu {
  // 默认是不可见的,除非右键点击
  display: none;
  :global {
    .ant-menu {
      border: none;
      border-radius: 4px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, .15);
    }
    .ant-menu-item {
      padding: 0;
      .command {
        padding: 0 16px;
        &.disable {
          // 命令按钮不可用的样式
          color: rgba(0, 0, 0, 0.25);
          background-color: #fff;
          cursor: not-allowed;
        }
      }
    }
  }
}
tdida commented 5 years ago

@Yeung2017 请问下找到解决方案了吗