Start sharing components as a team!Share components as a team!Join Bit to build your applications faster.Get Started Free

radios

v0.1.3arrow_drop_down
v0.1.3
v0.1.2
v0.1.0
STATUS
Passing
DOWNLOADS
39
LICENSE
MIT
VISIBILITY
Public
PUBLISHED
A year ago
SIZE
29 KB
1 contributor
Install radios as a package?
Copied
npm i @bit/ans.base-ui.radios
Set Bit as a scoped registryLearn more
npm config set '@bit:registry' https://node.bit.dev
Files
index.js
64 Lines(52 sloc)
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
import radioStyles from './radio.module.scss'
import _ from 'lodash'
import classNames from 'classnames'
import React, { useState, useEffect, forwardRef } from 'react'
import PropTypes from 'prop-types'

const Radios = forwardRef(({ className, type, disabled, options, value, onChange, ...otherProps }, ref) => {
  const [selected, selectItem] = useState(value ? { value } : (typeof options[0] === 'string' ? { value: options[0] } : options[0]))
  const handleSelect = selectedValue => () => {
    if (value || disabled) return
    selectItem(selectedValue)
    if (onChange) {
      onChange(selectedValue.value)
    }
  }

  useEffect(() => {
    if (value) {
      selectItem({ value })
    }
  }, [value])

  const classes = classNames(
    { [radioStyles.radioStyle]: type === 'radio' },
    { [radioStyles.buttonStyle]: type === 'button' },
    { [radioStyles.disabled]: disabled }
  )

  const renderOption = option => {
    option = typeof option === 'string' ? { text: option, value: option } : option
    const isSelected = selected && selected.value === option.value

    return (
      <label key={option.value} onClick={handleSelect(option)} className={isSelected ? radioStyles.selected : ''}>
        {option.text}
        <input style={{ display: 'none' }} type="radio" checked={isSelected} value={option.value} ref={ref} {...otherProps} />
      </label>
    )
  }

  return (
    <div className={`${className || ''} ${classes}`}>
      {options && options.map(renderOption)}
    </div>
  )
})

Radios.defaultProps = {
  type: 'button'
}

Radios.propTypes = {
  /** Array of strings or objects {text, value} representing the options */
  options: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.string),
    PropTypes.arrayOf(PropTypes.object)
  ]).isRequired,
  /** The type: either traditional radio buttons or modern buttons */
  type: PropTypes.oneOf(['radio', 'button']),
  /** Control the value - should match an option */
  value: PropTypes.string
}

export default Radios