wix-style-react
Version:
wix-style-react
105 lines • 5.25 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import uniqueId from 'lodash/uniqueId';
import Radio from '../Radio/Radio';
import { st, classes } from './RadioGroup.st.css';
import { dataHooks } from './constants';
/**
* component for easy radio group creation.
*
* similar to HTML `<input type="radio"/>` except you don't need to handle `name` or click handlers
*/
class RadioGroup extends React.PureComponent {
_getSpacing(index) {
const { display: orientation, spacing, fullWidth } = this.props;
if (index > 0) {
if (orientation === 'vertical') {
return { marginTop: spacing };
}
if (orientation === 'horizontal' && !fullWidth) {
return { marginInlineStart: spacing };
}
}
return {};
}
render() {
const { dataHook, className, name, onChange, disabledRadios, value, vAlign, display: orientation, selectionArea, selectionAreaSkin, selectionAreaPadding, fullWidth, } = this.props;
const uniqueName = name || uniqueId('RadioGroup_');
return (React.createElement("div", { role: "radiogroup", "data-hook": dataHook, className: st(classes.root, {
orientation,
fullWidth,
}, className), "data-display": orientation, style: fullWidth && orientation === 'horizontal'
? {
gridTemplateColumns: `repeat(${this.props.children?.length}, 1fr)`,
columnGap: this.props?.spacing ?? '6px',
}
: null }, React.Children.map(this.props.children, (radio, index) => {
if (!radio) {
return radio;
}
const checked = radio.props.value === value;
const radioName = radio.props.name || uniqueName;
const disabled = this.props.disabled ||
disabledRadios.indexOf(radio.props.value) !== -1;
const radioDataHook = `${dataHooks.RadioContainer}-${radio.props.value}`;
return (React.createElement("div", { className: st(classes.optionContainer, {
selectionArea,
selectionAreaSkin,
checked,
disabled,
}), "data-hook": dataHooks.RadioOptionContainer, style: this._getSpacing(index) },
React.createElement("div", { className: classes.radioContainer, "data-hook": radioDataHook },
React.createElement(Radio, { style: {
minHeight: '24px',
padding: selectionAreaPadding,
}, className: classes.radio, dataHook: radio.props.dataHook, value: radio.props.value, name: radioName, id: uniqueId(`${radioName}_`), onChange: () => onChange(radio.props.value), onMouseEnter: radio.props.onMouseEnter, onMouseLeave: radio.props.onMouseLeave, alignItems: vAlign, disabled: disabled, checked: checked, label: radio.props.children })),
radio.props.content && (React.createElement("div", { className: classes.content, "data-hook": dataHooks.RadioContent }, radio.props.content))));
})));
}
}
RadioGroup.propTypes = {
/** Applies a data-hook HTML attribute that can be used in the tests */
dataHook: PropTypes.string,
/** Specifies a CSS class name to be appended to the component’s root element */
className: PropTypes.string,
/** Defines a callback function which is called every time user selects a different value */
onChange: PropTypes.func,
/** Specifies the selected radio value */
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Specify the values of the disabled radio buttons */
disabledRadios: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
/** Controls radio alignment to the label on Y axis */
vAlign: PropTypes.oneOf(['center', 'top']),
/** Disables the entire group */
disabled: PropTypes.bool,
/** Control options direction */
display: PropTypes.oneOf(['vertical', 'horizontal']),
/** Controls selection area highlight visibility */
selectionArea: PropTypes.oneOf(['none', 'hover', 'always']),
/** Sets the design of the selection area */
selectionAreaSkin: PropTypes.oneOf(['filled', 'outlined']),
/** Sets the amount of white space around the radio label in pixels */
selectionAreaPadding: PropTypes.string,
/** Lists RadioGroup items. You're recommended to use it with <RadioGroup.Radio/>. */
children: PropTypes.node,
/** Controls the distance between options */
spacing: PropTypes.string,
/** Sets a unique name of a radio group */
name: PropTypes.string,
/** Makes component full width and divides all available horizontal space into even parts for each radio button */
fullWidth: PropTypes.bool,
};
RadioGroup.defaultProps = {
disabledRadios: [],
onChange: () => { },
value: '',
vAlign: 'center',
display: 'vertical',
selectionArea: 'none',
selectionAreaSkin: 'filled',
fullWidth: false,
};
RadioGroup.Radio = Radio;
RadioGroup.displayName = 'RadioGroup';
export default RadioGroup;
//# sourceMappingURL=RadioGroup.js.map