index.tsx 6.24 KB
import React from 'react';
import { Button, Tooltip, Dropdown, Menu } from 'antd';
import './index.less';
import {
  CloseCircleOutlined,
  CloseOutlined,
  DeleteOutlined,
  EditOutlined,
  EllipsisOutlined,
  MinusCircleOutlined,
  MinusOutlined,
  PlusCircleOutlined,
  PlusOutlined,
  ToolOutlined,
  SettingOutlined,
  CheckOutlined,
  CopyOutlined,
  ImportOutlined,
  ExportOutlined,
  FileTextOutlined,
  PlayCircleOutlined,
  PauseCircleOutlined,
  AppstoreOutlined,
  BarsOutlined,
  AlertOutlined,
  EyeOutlined,
  // DownOutlined,
  PrinterOutlined,
} from '@ant-design/icons';
import QxIcon from './icon';
import type { DropDownProps as DropdownProps, ButtonProps, TooltipProps } from 'antd/lib';

export const BUTTON_ICONS_MAP: { [index: string]: React.ReactElement } = {
  PlusOutlined: <PlusOutlined />,
  MinusOutlined: <MinusOutlined />,
  PlusCircleOutlined: <PlusCircleOutlined />,
  MinusCircleOutlined: <MinusCircleOutlined />,
  CloseCircleOutlined: <CloseCircleOutlined />,
  CloseOutlined: <CloseOutlined />,
  CheckOutlined: <CheckOutlined />,
  DeleteOutlined: <DeleteOutlined />,
  EyeOutlined: <EyeOutlined />,
  EditOutlined: <EditOutlined />,
  FileTextOutlined: <FileTextOutlined />,
  EllipsisOutlined: <EllipsisOutlined />,
  SettingOutlined: <SettingOutlined />,
  ToolOutlined: <ToolOutlined />,
  CopyOutlined: <CopyOutlined />,
  ImportOutlined: <ImportOutlined />,
  ExportOutlined: <ExportOutlined />,
  PlayCircleOutlined: <PlayCircleOutlined />,
  PauseCircleOutlined: <PauseCircleOutlined />,
  AppstoreOutlined: <AppstoreOutlined />,
  BarsOutlined: <BarsOutlined />,
  AlertOutlined: <AlertOutlined />,
  PrinterOutlined: <PrinterOutlined />,
};
export const BUTTON_COLORS = {
  blue: '#1764FF',
  green: '#52c41a',
  orange: '#faad14',
  red: '#f5222d',
  purple: '#722ed1',
  cyan: '#13c2c2',
};

//'#1890ff' primary
//'#52c41a' success
//'#faad14' Warning
// #f5222d  error
/*@purple-base: #722ed1;
@cyan-base: #13c2c2;*/

export interface DropdownMenuItem {
  code?: string;
  name?: string;
  icon?: string;
}

export interface QxButtonProps extends ButtonProps {
  name?: string;
  color?: string;
  batch?: boolean; //冗余属性
  flag?: string; //冗余属性
  action?: string; //冗余属性
  line?: boolean; //冗余属性
  code?: string; //冗余属性
  needConfirm?: boolean; //冗余属性
  tooltip?: string;
  /**
   * 下拉菜单选项
   */
  dropdownMenuItems?: DropdownMenuItem[];
  /**
   * 下拉菜单点击事件
   */
  handleMenuClick?: (...args: any) => void;
  /**
   * 下拉菜单参数
   */
  dropdownProps?: DropdownProps;
  /**
   * 是否显示下拉菜单,默认 true
   */
  showDropdown?: boolean;
  // 提示框相关参数
  tooltipProps?: TooltipProps | undefined;
  extraDom?: React.ReactNode | undefined; // 额外标签
}

const Icon = ({ name }) => {
  if (name?.$$typeof) return name;
  return name ? (
    String(name).indexOf('http') > -1 ? (
      <img
        src={String(name)}
        style={{
          width: '16px',
          height: '16px',
          marginRight: '4px',
          verticalAlign: 'text-bottom',
          borderRadius: '50%',
        }}
        alt=""
      />
    ) : String(name).indexOf('-') > -1 ? (
      <QxIcon type={String(name)} />
    ) : (
      BUTTON_ICONS_MAP[name + ''] || <PlusOutlined />
    )
  ) : null;
};

export const QxButton: React.FC<QxButtonProps> = (props) => {
  const {
    name,
    style,
    icon,
    batch,
    line,
    needConfirm,
    className = '',
    flag,
    color,
    tooltip = '',
    dropdownMenuItems = [],
    handleMenuClick,
    dropdownProps = {},
    showDropdown = true,
    tooltipProps,
    extraDom,
    ...rest
  } = props;
  const showMenu = Array.isArray(dropdownMenuItems) && dropdownMenuItems?.length && showDropdown;

  const getMenuItem = (_menuItems: any) =>
    _menuItems?.map((menu) => {
      return {
        ...menu,
        label: menu?.label || menu?.name,
        key: menu?.key || menu?.code,
        children: getMenuItem(menu?.dropdownMenuItems),
      };
    });

  const generateMenu = (items: any) => {
    return getMenuItem(items)?.map((item) => {
      if (item.children?.length) {
        return (
          <Menu.SubMenu
            icon={
              <span>
                <Icon name={item.icon} />
              </span>
            }
            title={item.label}
            key={item.key}
            disabled={!!item?.disabled}
          >
            {generateMenu(item.children)}
          </Menu.SubMenu>
        );
      } else {
        return (
          <Menu.Item
            icon={
              <span>
                <Icon name={item.icon} />
              </span>
            }
            key={item.key}
            onClick={() => handleMenuClick(item)}
            disabled={!!item?.disabled}
          >
            {item.label}
          </Menu.Item>
        );
      }
    });
  };

  const menu = () => <Menu>{generateMenu(dropdownMenuItems)}</Menu>;
  const btnChildren = name ? name : props.children;

  const button = !!extraDom ? (
    <Button
      className={'qx-btn ' + className + ' ' + (color ? `qx-btn-${color}` : '')}
      {...rest}
      icon={<Icon name={icon} />}
    >
      {showMenu && btnChildren && props?.type !== 'link' ? (
        <>
          <QxIcon type={'icon-common-arrow'} className={'qx-core-dropdown-arrow'} />
          {btnChildren}
        </>
      ) : (
        btnChildren
      )}
      {extraDom}
    </Button>
  ) : (
    <Button
      className={'qx-btn ' + className + ' ' + (color ? `qx-btn-${color}` : '')}
      {...rest}
      icon={<Icon name={icon} />}
    >
      {showMenu && btnChildren && props?.type !== 'link' ? (
        <>
          <QxIcon type={'icon-common-arrow'} className={'qx-core-dropdown-arrow'} />
          {btnChildren}
        </>
      ) : (
        btnChildren
      )}
    </Button>
  );

  const _dropdownProps: Omit<DropdownProps, 'overlay'> = {
    overlayClassName: 'qx-core-drop_down',
    ...dropdownProps,
  };

  const content = showMenu ? (
    <Dropdown overlay={menu} {..._dropdownProps}>
      {button}
    </Dropdown>
  ) : (
    button
  );

  // extraDom 有额外标签时  tooltip不生效
  if (tooltip && !extraDom) {
    return (
      <Tooltip {...(tooltipProps || {})} title={tooltip}>
        {content}
      </Tooltip>
    );
  }

  return content;
};