Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
import React, { Component } from 'react';
import PropTypes from 'prop-types';

import classnames from 'classnames';

export const buttonVariants = [
  'accent',
  'flatAccent',
  'green',
  'blue',
  'white',
  'whiteWithBorder',
  'yellow',
  'linkBlue',
  'linkWhite',
  'linkDark',
  'linkRed',
  'linkBanner',
];
export const buttonTargets = ['_blank', '_self', '_top', '_parent'];
export const defaultButtonVariant = 'accent';
export const buttonDimensions = ['small', 'compact', 'very-compact'];

class Button extends Component {
  static propTypes = {
    children: PropTypes.any,
    variant: PropTypes.oneOf(buttonVariants),
    modifier: PropTypes.string,
    className: PropTypes.string,
    dimension: PropTypes.oneOf(buttonDimensions),
    type: PropTypes.oneOf(['button', 'submit', 'reset']),
    focus: PropTypes.bool,
    hover: PropTypes.bool,
    active: PropTypes.bool,
    inputButtonClass: PropTypes.oneOf(['inputButton', 'loading']),
    responsive: PropTypes.bool,
    target: PropTypes.oneOf(buttonTargets),
    /** Renders the button as an \<a\> tag with this value as href attribute. If possible, it's preferable to use the <a href="#link">Link</a> component */
    href: (props, propName) => {
      if (props[propName]) {
        // Only allow the default value
        if (props.type !== Button.defaultProps.type) {
          return new Error('Buttons with an href cannot have a type property because they will be rendered as links');
        }
        if (typeof props[propName] !== 'string') {
          return new Error(`The property ${propName} must be a string`);
        }
      }
    },
  };
  static defaultProps = {
    children: null,
    variant: defaultButtonVariant,
    modifier: null,
    className: null,
    dimension: null,
    type: 'button',
    focus: false,
    hover: false,
    active: false,
    inputButtonClass: null,
    responsive: null,
    href: null,
    target: '_self',
  };

  componentDidMount() {
    // Normalises the behaviour so that button is focused on click also on Safari and Firefox on Mac.
    // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
    this.button.addEventListener('mousedown', () => {
      // set timeout required as the component might be re-rendered
      this.focusTimeout = setTimeout(() => {
        if (this.button) {
          this.button.focus();
        }
      });
    });
  }
  componentDidUnMount() {
    if (this.focusTimeout) {
      clearTimeout(this.focusTimeout);
    }
  }

  render() {
    const {
      responsive,
      variant,
      modifier,
      className,
      dimension,
      type,
      focus,
      hover,
      active,
      inputButtonClass,
      href,
      target,
      ...props
    } = this.props;

    const componentClassName = classnames(
      'Button',
      {
        [`Button--${variant}`]: variant,
        [`Button--${modifier}`]: modifier,
        [`Button--${dimension}`]: dimension,
        [`Button--${inputButtonClass}`]: inputButtonClass,
        'Button--responsive': responsive,
        'Button--focus': focus,
        'Button--hover': hover,
        'Button--active': active,
      },
      className
    );

    return href ? (
      <a
        ref={button => {
          this.button = button;
        }}
        className={componentClassName}
        href={href}
        target={target}
        rel="noopener noreferrer"
        {...props}
      >
        <span className="Button-contentWrapper">{this.props.children}</span>
      </a>
    ) : (
      <button
        ref={button => {
          this.button = button;
        }}
        className={componentClassName}
        type={type}
        {...props}
      >
        <span className="Button-contentWrapper">{this.props.children}</span>
      </button>
    );
  }
}

export default Button;