index.tsx 3.6 KB
Newer Older
1 2
import * as React from 'react';
import * as ReactDOM from 'react-dom';
J
jljsj 已提交
3
import Animate from 'rc-animate';
A
afc163 已提交
4
import Icon from '../icon';
A
afc163 已提交
5
import classNames from 'classnames';
Z
zhujun24 已提交
6

7
function noop() { }
B
Benjy Cui 已提交
8

B
Benjy Cui 已提交
9
export interface AlertProps {
A
afc163 已提交
10 11 12
  /**
   * Type of Alert styles, options:`success`, `info`, `warning`, `error`
   */
D
ddcat1115 已提交
13
  type?: 'success' | 'info' | 'warning' | 'error';
A
afc163 已提交
14 15 16 17 18 19 20 21 22
  /** Whether Alert can be closed */
  closable?: boolean;
  /** Close text to show */
  closeText?: React.ReactNode;
  /** Content of Alert */
  message: React.ReactNode;
  /** Additional content of Alert */
  description?: React.ReactNode;
  /** Callback when close Alert */
23
  onClose?: React.MouseEventHandler<HTMLAnchorElement>;
H
Hughen 已提交
24
  /** Trigger when animation ending of Alert */
W
Wei Zhu 已提交
25
  afterClose?: () => void;
A
afc163 已提交
26 27
  /** Whether to show icon */
  showIcon?: boolean;
28
  iconType?: string;
A
afc163 已提交
29 30
  style?: React.CSSProperties;
  prefixCls?: string;
A
afc163 已提交
31
  className?: string;
D
ddcat1115 已提交
32
  banner?: boolean;
A
afc163 已提交
33 34 35
}

export default class Alert extends React.Component<AlertProps, any> {
36
  constructor(props: AlertProps) {
37 38
    super(props);
    this.state = {
J
jljsj 已提交
39
      closing: true,
B
Benjy Cui 已提交
40
      closed: false,
A
afc163 已提交
41
    };
42
  }
43
  handleClose = (e: React.MouseEvent<HTMLAnchorElement>) => {
44
    e.preventDefault();
A
afc163 已提交
45
    let dom = ReactDOM.findDOMNode(this) as HTMLElement;
46
    dom.style.height = `${dom.offsetHeight}px`;
J
jljsj 已提交
47
    // Magic code
A
afc163 已提交
48
    // 重复一次后才能正确设置 height
49
    dom.style.height = `${dom.offsetHeight}px`;
J
jljsj 已提交
50 51

    this.setState({
B
Benjy Cui 已提交
52
      closing: false,
J
jljsj 已提交
53
    });
B
Benjy Cui 已提交
54
    (this.props.onClose || noop)(e);
55 56
  }
  animationEnd = () => {
Z
zhujun24 已提交
57
    this.setState({
J
jljsj 已提交
58
      closed: true,
B
Benjy Cui 已提交
59
      closing: true,
Z
zhujun24 已提交
60
    });
H
Hughen 已提交
61
    (this.props.afterClose || noop)();
62
  }
J
jljsj 已提交
63
  render() {
A
afc163 已提交
64
    let {
B
Benjy Cui 已提交
65
      closable, description, type, prefixCls = 'ant-alert', message, closeText, showIcon, banner,
66
      className = '', style, iconType,
A
afc163 已提交
67 68
    } = this.props;

D
ddcat1115 已提交
69
    // banner模式默认有 Icon
70
    showIcon = banner && showIcon === undefined ? true : showIcon;
D
ddcat1115 已提交
71
    // banner模式默认为警告
72
    type = banner && type === undefined ? 'warning' : type || 'info';
D
ddcat1115 已提交
73

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    if (!iconType) {
      switch (type) {
        case 'success':
          iconType = 'check-circle';
          break;
        case 'info':
          iconType = 'info-circle';
          break;
        case 'error':
          iconType = 'cross-circle';
          break;
        case 'warning':
          iconType = 'exclamation-circle';
          break;
        default:
          iconType = 'default';
      }
A
afc163 已提交
91

92 93 94 95
      // use outline icon in alert with description
      if (!!description) {
        iconType += '-o';
      }
96 97
    }

98
    let alertCls = classNames(prefixCls, {
99 100 101 102
      [`${prefixCls}-${type}`]: true,
      [`${prefixCls}-close`]: !this.state.closing,
      [`${prefixCls}-with-description`]: !!description,
      [`${prefixCls}-no-icon`]: !showIcon,
D
ddcat1115 已提交
103
      [`${prefixCls}-banner`]: !!banner,
104
    }, className);
A
afc163 已提交
105

106
    // closeable when closeText is assigned
A
afc163 已提交
107 108
    if (closeText) {
      closable = true;
Z
zhujun24 已提交
109
    }
A
afc163 已提交
110

W
Wei Zhu 已提交
111 112 113 114 115 116
    const closeIcon = closable ? (
      <a onClick={this.handleClose} className={`${prefixCls}-close-icon`}>
        {closeText || <Icon type="cross" />}
      </a>
    ) : null;

A
afc163 已提交
117
    return this.state.closed ? null : (
A
afc163 已提交
118 119
      <Animate
        component=""
A
afc163 已提交
120
        showProp="data-show"
J
jiang 已提交
121
        transitionName={`${prefixCls}-slide-up`}
122 123
        onEnd={this.animationEnd}
      >
A
afc163 已提交
124
        <div data-show={this.state.closing} className={alertCls} style={style}>
125
          {showIcon ? <Icon className={`${prefixCls}-icon`} type={iconType} /> : null}
126 127
          <span className={`${prefixCls}-message`}>{message}</span>
          <span className={`${prefixCls}-description`}>{description}</span>
W
Wei Zhu 已提交
128
          {closeIcon}
A
afc163 已提交
129 130 131
        </div>
      </Animate>
    );
Z
zhujun24 已提交
132
  }
133
}