# All files / components/Toggle Toggle.js

0% Statements 0/62
0% Branches 0/16
0% Functions 0/7
0% Lines 0/23

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136

     import React from 'react';
    import PropTypes from 'prop-types';
    import generateId from '../../extensions/generateId';
    import ToggleContainer from './styles/ToggleContainer';
    import ToggleInput from './styles/ToggleInput';
    import ToggleLabel from './styles/ToggleLabel';

    class Toggle extends React.PureComponent {
      static propTypes = {
        /**
         * Adds a class name to the input element.
         */
        className: PropTypes.string,
        /**
         * Adds an id to the input element.
         */
        id: PropTypes.string,
        /**
         * The value of the toggle. DEPRECATION WARNING: this prop
         * used to be used for the 'checked' boolean state. You should use
         * `checked` for that instead.
         */
        value: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
        /**
         * Whether the toggle is 'on' or 'off'.
         */
        checked: PropTypes.bool,
        /**
         * Whether the toggle is required for form submission.
         */
        required: PropTypes.bool,
        /**
         * Whether the user is prevented from interacting with the toggle.
         */
        disabled: PropTypes.bool,
        /**
         * Adds a name to the underlying input.
         */
        name: PropTypes.string,
        /**
         * A description to display next to the toggle.
         */
        description: PropTypes.node,
        /**
         * Callback for the onChange event of the input.
         */
        onChange: PropTypes.func,
        /**
         * A component to render the container around the toggle and label
         */
        Container: PropTypes.func,
        /**
         * A component to render the input element, usually hidden
         */
        Input: PropTypes.func,
        /**
         * A component to render the label, which usually also renders the toggle itself
         */
        Label: PropTypes.func,
      };

      static defaultProps = {
        className: null,
        id: null,
        value: false,
        name: null,
        required: false,
        disabled: false,
        description: null,
        onChange: () => null,
        Container: ToggleContainer,
        Input: ToggleInput,
        Label: ToggleLabel,
      };

      defaultId = generateId('toggle');

      computeChecked = () => {
        const { value, checked } = this.props;

        if (typeof checked === 'boolean') {
          return checked;
        }

        if (typeof value === 'boolean') {
          return value;
        }

        return undefined;
      };

      computeValue = () => {
        const { value, checked } = this.props;
        // assume user is using value correctly if checked is defined
        // or if value isn't boolean
        if (checked !== undefined || typeof value !== 'boolean') {
          return value;
        }

        return undefined;
      };

      render() {
        const {
          className,
          disabled,
          required,
          name,
          description,
          onChange,
          Container,
          Input,
          Label,
        } = this.props;
        const id = this.props.id || this.defaultId;
        return (
          <Container>
            <Input
              id={id}
              className={className}
              name={name}
              type="checkbox"
              disabled={disabled}
              checked={this.computeChecked()}
              value={this.computeValue()}
              required={required}
              onChange={onChange}
            />
            <Label htmlFor={id}>{description}</Label>
          </Container>
        );
      }
    }

    export default Toggle;