index.tsx 3.77 KB
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import { useSetState } from 'ahooks';
import {Button, Dropdown, Input } from 'antd';
import type { InputProps } from 'antd/lib/input';
import cls from 'classnames';
import React, { useImperativeHandle } from 'react';
import type {
  DropdownContentOptions,
  DropdownContentProps,
} from './dropdown-content';
import DropdownContent from './dropdown-content';

import './styles.less';
import {QxBaseIcon} from "@qx/common";

const prefix = 'qx-input-select';

/**
 * 下拉选择
 */
export const QxInputSelect = React.forwardRef<any, InputSelectProps>(
  (props, ref) => {
    const {
      className,
      options = [],
      dropdownProps,
      onChange,
      disabled,
      from,
      ...rest
    } = props;

    const [state, setState] = useSetState<InputSelectState>({
      visible: false,
    });

    const inputSuffix = (
      <div className={`${prefix}__input-suffix`}>
        {state.visible ? <UpOutlined /> : <DownOutlined />}
      </div>
    );

    const handleChange = (val: DropdownContentOptions) => {
      onChange?.(val);
      setState({ visible: false });
    };

    /**
     * 菜单显示状态改变时调用
     */
    const onVisibleChange = (visible: boolean) => {
      setState({ visible });
    };

    useImperativeHandle(ref, () => ({
      closeDropdown: () => {
        setState({ visible: false });
      },
      openDropdown: () => {
        setState({ visible: true });
      },
    }));

    return (
      <div className={cls(prefix, className)}>
        <Dropdown
          open={state.visible}
          destroyPopupOnHide
          trigger={['click']}
          className={`${prefix}__dropdown`}
          dropdownRender={() => (
            <DropdownContent
              options={options}
              onChange={handleChange}
              {...dropdownProps}
            />
          )}
          getPopupContainer={(triggerNode) => {
            if (props?.popupOnBody) {
              return document.body;
            } else {
              return triggerNode;
            }
          }}
          onOpenChange={onVisibleChange}
          disabled={true}
        >
          <>
            {
              from === 'FORM'?
                <Button
                  disabled={disabled}
                  className={`qx-input-select__button`}
                  tabIndex={1}
                  onClick={() => setState({ visible: !state.visible })}
                >
                  {props?.prefix}
                  { !props?.value ?
                    <span className={'qx-input-select__button-main qx-input-select__button-placeholder'}>{props?.placeholder}</span>:
                    <span className={'qx-input-select__button-main'}>
                      <span>{props?.appName}</span>
                      <QxBaseIcon
                        type="qx-icon-left"
                        className={'qx-input-select__button-svg'}
                      />
                      <span>{props?.value}</span>
                    </span>
                  }
                  {inputSuffix}
                </Button>:
                <Input
                  placeholder="请选择"
                  readOnly
                  suffix={inputSuffix}
                  onClick={() => setState({ visible: !state.visible })}
                  {...rest}
                  className={`${prefix}__input`}
                />
            }
          </>
        </Dropdown>
      </div>
    );
  },
);

export interface InputSelectProps extends Omit<InputProps, 'onChange'> {
  onChange?: (args: DropdownContentOptions) => void;
  options?: DropdownContentOptions[];
  dropdownProps?: DropdownContentProps;
  disabled?: boolean;
  popupOnBody?: boolean;
  from?: string;
  appName?: string;
}
export interface InputSelectState {
  visible: boolean;
}