lucid-ui
Version:
A UI component library from AppNexus.
130 lines (113 loc) • 6.46 kB
JavaScript
import _keys from "lodash/keys";
import _findLastIndex from "lodash/findLastIndex";
import _isFunction from "lodash/isFunction";
import _map from "lodash/map";
import _get from "lodash/get";
import _noop from "lodash/noop";
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames, uniqueName } from '../../util/style-helpers';
import { getFirst, findTypes, rejectTypes, omitProps } from '../../util/component-types';
import reducers from './RadioGroup.reducers';
import { buildModernHybridComponent } from '../../util/state-management';
import RadioButtonLabeled from '../RadioButtonLabeled/RadioButtonLabeled';
import RadioButton from '../RadioButton/RadioButton';
var cx = lucidClassNames.bind('&-RadioGroup');
var func = PropTypes.func,
node = PropTypes.node,
number = PropTypes.number,
string = PropTypes.string,
bool = PropTypes.bool;
var RadioGroupLabel = function RadioGroupLabel(props) {
return null;
};
RadioGroupLabel.peek = {
description: "\n Support radio button labels as `RadioGroup.Label` component which\n can be provided as a child of a `RadioGroup.RadioButton`\n component.\n "
};
RadioGroupLabel.propTypes = {
children: node
};
RadioGroupLabel.displayName = 'RadioGroup.Label';
var defaultProps = {
name: uniqueName("".concat(cx('&'), "-")),
onSelect: _noop,
selectedIndex: 0,
isDisabled: false
};
var RadioGroup = function RadioGroup(props) {
var children = props.children,
className = props.className,
name = props.name,
selectedIndex = props.selectedIndex,
isDisabled = props.isDisabled,
passThroughs = _objectWithoutProperties(props, ["children", "className", "name", "selectedIndex", "isDisabled"]);
var handleSelected = function handleSelected(isSelected, _ref) {
var event = _ref.event,
childProps = _ref.props;
var callbackId = childProps.callbackId;
if (callbackId !== undefined) {
var clickedRadioButtonProps = _get(_map(findTypes(props, RadioGroup.RadioButton), 'props'), callbackId); // If the `RadioGroup.RadioButton` child has an `onSelect` prop that is
// a function, call that prior to calling the group's `onSelect` prop.
if (_isFunction(clickedRadioButtonProps.onSelect)) {
clickedRadioButtonProps.onSelect(isSelected, {
event: event,
props: childProps
});
}
props.onSelect(callbackId, {
event: event,
props: childProps
});
}
};
var radioButtonChildProps = _map(findTypes(props, RadioGroup.RadioButton), 'props');
var selectedIndexFromChildren = _findLastIndex(radioButtonChildProps, {
isSelected: true
}); // If there are any `RadioGroup.RadioButton` children with `isSelected`
// equal to true, then the index of the last one should override the
// value of the `selectedIndex` prop.
var actualSelectedIndex = selectedIndexFromChildren !== -1 ? selectedIndexFromChildren : selectedIndex;
return /*#__PURE__*/React.createElement("span", _extends({}, omitProps(passThroughs, undefined, _keys(RadioGroup.propTypes)), {
className: cx('&', className)
}), _map(radioButtonChildProps, function (radioButtonChildProp, index) {
return /*#__PURE__*/React.createElement(RadioButtonLabeled, _extends({}, radioButtonChildProp, {
isDisabled: isDisabled || radioButtonChildProp.isDisabled,
isSelected: actualSelectedIndex === index,
key: index,
callbackId: index,
name: name,
onSelect: handleSelected,
Label: _get(getFirst(radioButtonChildProp, RadioGroup.Label), 'props', null)
}));
}), rejectTypes(children, RadioGroup.RadioButton));
};
RadioGroup.displayName = 'RadioGroup';
RadioGroup.propTypes = {
children: node,
className: string,
name: string,
onSelect: func,
selectedIndex: number,
isDisabled: bool
};
RadioGroup.peek = {
description: "\n\t\tThis is a composite of the `RadioButton` component and the native\n\t\t`label` element.\n",
notes: {
overview: "\n\t\t\tA round two-state toggle with a label that explains the action or selection. This is a composite of `RadioButton` and the native\n\t\t\t`label` element.\t\t",
intendedUse: "\n\t\t\t- Use radio button to allow users to select one item. Commonly used to select filters or settings. For interactions where users can select mutiple options, use `CheckboxLabeled`. \n\t\t\t- Use radio buttons for 2-3 options where you want to expose all options.\n\t\t\t- Use `SingleSelect` for 3-10 options where it is not a priority to expose all options.\n\t\t\t- Use `RadioGroup` for horizontal lists of options. Use `RadioButtonLabeled` for vertical lists of options.\n\t",
technicalRecommendations: "\n\t\t\t- Use the styles on the parent container of `RadioGroup` to ensure only the radio buttons and their labels are clickable.\n\t\t\t- Any props that are not explicitly defined in `propTypes` are passed to the native radio button control.\n\t\t"
},
categories: ['controls', 'toggles'],
madeFrom: ['RadioButton']
};
RadioGroup.defaultProps = defaultProps;
RadioGroup.reducers = reducers;
RadioGroup.RadioButton = RadioButton;
RadioGroup.Label = RadioGroupLabel;
export default buildModernHybridComponent(RadioGroup, {
reducers: reducers
});
export { RadioGroup as RadioGroupDumb };