UNPKG

lucid-ui

Version:

A UI component library from AppNexus.

130 lines (113 loc) 6.46 kB
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 };