UNPKG

wix-style-react

Version:
130 lines (111 loc) 3.15 kB
import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; import { st, classes } from './Radio.st.css'; import Text from '../Text'; import { generateDataAttr } from '../utils/generateDataAttr'; import { generateID } from '../utils/generateId'; import { dataHooks } from './constants'; import { withFocusable } from 'wix-ui-core/dist/src/hocs/Focusable/FocusableHOC'; const Radio = ({ dataHook, checked, disabled, label, id, name, value, focusableOnFocus, focusableOnBlur, onChange, alignItems, className, style, }) => { const defaultId = generateID(); const _onClick = event => { if (!disabled && !checked) { onChange({ value, ...event }); } }; const renderLabel = useMemo(() => { return ( <Text tagName="div" size="medium" weight="thin" secondary> {label} </Text> ); }, [label]); const radioId = id || defaultId; return ( <div className={st( classes.root, { checked, disabled, alignItems, }, className, )} {...generateDataAttr({ checked, disabled }, ['checked', 'disabled'])} style={style} data-hook={dataHook} onClick={_onClick} aria-checked={!!checked} > <input type="radio" className={classes.input} data-hook={dataHooks.input} disabled={disabled} checked={checked} value={value} name={name} id={radioId} onChange={() => null} onFocus={focusableOnFocus} onBlur={focusableOnBlur} /> <span className={classes.icon} data-hook={dataHooks.icon}></span> {label && ( <label className={classes.label} data-hook={dataHooks.label} htmlFor={radioId} onClick={e => e.stopPropagation()} > {renderLabel} </label> )} </div> ); }; Radio.displayName = 'Radio'; Radio.propTypes = { /** Applies a data-hook HTML attribute that can be used in tests */ dataHook: PropTypes.string, /** Specifies a CSS class name to be appended to the component’s root element */ className: PropTypes.string, /** Specifies whether a radio is selected */ checked: PropTypes.bool, /** Specifies whether radio should be disabled */ disabled: PropTypes.bool, /** Sets the label on the right side of a radio. The default accepted value is a text string, but it can be overridden to any other component. */ label: PropTypes.node, /** Sets a unique name for the radio */ name: PropTypes.node, /** Assigns an unique identifier for the radio */ id: PropTypes.string, /** Sets the value that the radio represents */ value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Defines a callback function which is called when radio is selected */ onChange: PropTypes.func, /** Control radio alignment with a label */ alignItems: PropTypes.oneOf(['top', 'center']), }; Radio.defaultProps = { checked: false, disabled: false, alignItems: 'center', onChange: () => null, }; export default withFocusable(Radio);