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    
@doodle/components / src / components / controls / CustomRadioButtons / CustomRadioButtons.js
Size: Mime:
/* eslint-disable jsx-a11y/label-has-for */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';

/**
 * For now this component is only used in web-billing as the currency and number of users switcher.
 * Feel free to use it anywhere else in the Doodleverse.
 * Pitfalls: For now the max-width for the radio buttons are 4 letters. If you need more, or an adaptive width, some refactoring needs to be done.
 */
class CustomRadioButtons extends Component {
  static propTypes = {
    /**
     * A unique name. It will be used as the id of the CustomRadioButtons
     * and a prefix for the input id and their names
     */
    name: PropTypes.string.isRequired,
    /**
     * An array of options.
     */
    options: PropTypes.arrayOf(PropTypes.string).isRequired,
    /**
     * If using the component controlled by some external state this will take precedence over the internal selected state
     * If set to a value that is not part of the options array all buttons will be unchecked
     */
    selected: PropTypes.string,
    /**
     * onChange will be called when the onChange event on a radio input is triggered
     */
    onChange: PropTypes.func.isRequired,
    /**
     * Title for the component
     */
    title: PropTypes.string,
    /**
     * Optional tooltip
     */
    tooltip: PropTypes.any,
  };

  static defaultProps = {
    title: null,
    tooltip: null,
    selected: null,
  };

  constructor(props) {
    super(props);
    this.state = {
      selected: null,
      maxOptionWidth: null,
    };
    this.onChange = this.onChange.bind(this);
  }

  onChange(event) {
    const selected = event.target.value;
    this.setState({ selected });
    this.props.onChange(selected);
  }

  render() {
    const { options, title, name, tooltip } = this.props;
    const { maxOptionWidth } = this.state;
    const selected = this.props.selected || this.state.selected;

    return (
      <div id={name} className="CustomRadioButtons-container">
        <div className="CustomRadioButtons-title">
          {title && <p>{title}</p>}
          {tooltip}
        </div>
        <div className="CustomRadioButtons">
          {options.map((option, index) => {
            const isSingle = options.length === 1;
            const isFirstOption = !isSingle && index === 0;
            const isLastOption = !isSingle && index === options.length - 1;
            const classNames = classnames('CustomRadioButtons-option', {
              'CustomRadioButtons-option--single': isSingle,
              'CustomRadioButtons-option--last': isLastOption,
              'CustomRadioButtons-option--first': isFirstOption,
              'CustomRadioButtons-option--middle': !isSingle && !isLastOption && !isFirstOption,
            });
            const style = maxOptionWidth ? { width: maxOptionWidth } : null;
            return (
              <div style={style} key={option} className={classNames}>
                <input
                  onChange={this.onChange}
                  checked={selected === option}
                  id={`${name}-option-${index}`}
                  type="radio"
                  name={option}
                  value={option}
                />
                <label htmlFor={`${name}-option-${index}`}>{option}</label>
              </div>
            );
          })}
        </div>
      </div>
    );
  }
}

export default CustomRadioButtons;