@sparkpost/matchbox
Version: 
A React UI component library
132 lines (108 loc) • 3.08 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { Error as ErrorIcon, CheckCircle, InfoOutline, Close } from '@sparkpost/matchbox-icons';
import styles from './Banner.module.scss';
import { buttonFrom } from '../Button';
const actionOverrides = { outline: true, size: 'small' };
const IconSection = ({ status }) => {
  const icons = {
    success: CheckCircle,
    info: InfoOutline,
    warning: ErrorIcon,
    danger: ErrorIcon
  };
  if (status === 'default' || !icons[status]) {
    return null;
  }
  const iconClasses = classnames(
    styles.Icon,
    status && styles[`${status}Icon`]
  );
  const Icon = icons[status];
  return (
    <div className={styles.IconWrapper}>
      <Icon size={30} className={iconClasses} />
      <div className={styles.IconBackdrop} />
    </div>
  );
};
class Banner extends Component {
  static displayName = 'Banner';
  static propTypes = {
    /**
     * The type of banner. 'default' | 'success' | 'warning' | 'danger' | 'info'
     */
    status: PropTypes.oneOf(['default', 'success', 'warning', 'danger', 'info']),
    /**
     * The banner's title
     */
    title: PropTypes.string,
    /**
     * Callback when dismiss button is clicked. Button hidden without callback.
     */
    onDismiss: PropTypes.func,
    /**
     * Action that build a button. Most button props will work in here.
     * e.g. { content: 'button label', onClick: callback() }
     */
    action: PropTypes.shape({ content: PropTypes.string.isRequired }),
    /**
     * List of actions that build buttons. Most button props will work in here.
     * Overrides `action`
     */
    actions: PropTypes.arrayOf(PropTypes.shape({
      content: PropTypes.string.isRequired
    })),
    /**
     * Banner Content
     */
    children: PropTypes.node
  };
  static defaultProps = {
    status: 'default'
  };
  render() {
    const {
      children,
      title,
      status,
      action,
      actions,
      onDismiss,
      ...rest
    } = this.props;
    const titleMarkup = title
      ? <h5 className={styles.Title}>{title}</h5>
      : null;
    let actionMarkup = action
      ? <div className={styles.Actions}>{buttonFrom(action, actionOverrides)}</div>
      : null;
    if (actions) {
      actionMarkup = (
        <div className={styles.Actions}>
          {actions.map((action, i) => buttonFrom(action, actionOverrides, i))}
        </div>
      );
    }
    const dismissMarkup = onDismiss
      ? <a className={styles.Dismiss} onClick={onDismiss}><Close size={24} className={styles.DismissIcon} /></a>
      : null;
    const bannerStyles = classnames(
      styles.Banner,
      styles[`${status}`]
    );
    return (
      <div className={bannerStyles} {...rest}>
        <IconSection status={status} />
        <div className={styles.Content}>
          {dismissMarkup}
          {titleMarkup}
          <div className={styles.Children}>{children}</div>
          {actionMarkup}
        </div>
      </div>
    );
  }
}
export default Banner;