UNPKG

chakra-ui

Version:

Responsive and accessible React UI components built with React and Emotion

124 lines (103 loc) 3.56 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; /** @jsx jsx */ import { jsx } from "@emotion/core"; import { Children, cloneElement, useState, useRef } from "react"; import { genId } from "../utils"; import Box from "../Box"; var RadioButtonGroup = function RadioButtonGroup(_ref) { var id = _ref.id, name = _ref.name, children = _ref.children, defaultValue = _ref.defaultValue, controlledValue = _ref.value, onChange = _ref.onChange, _ref$spacing = _ref.spacing, spacing = _ref$spacing === void 0 ? "12px" : _ref$spacing, isInline = _ref.isInline, rest = _objectWithoutProperties(_ref, ["id", "name", "children", "defaultValue", "value", "onChange", "spacing", "isInline"]); var isControlled = controlledValue != null; var _useState = useState(defaultValue || null), _useState2 = _slicedToArray(_useState, 2), value = _useState2[0], setValue = _useState2[1]; var _value = isControlled ? controlledValue : value; var allNodes = useRef([]); var focusableValues = Children.map(children, function (child) { return child.props.isDisabled === true ? null : child.props.value; }).filter(function (val) { return val != null; }); var allValues = Children.map(children, function (child) { return child.props.value; }); var updateIndex = function updateIndex(index) { var childValue = focusableValues[index]; var _index = allValues.indexOf(childValue); allNodes.current[_index].focus(); !isControlled && setValue(childValue); onChange && onChange(childValue); }; var handleKeyDown = function handleKeyDown(event) { var count = focusableValues.length; var enabledCheckedIndex = focusableValues.indexOf(_value); if (enabledCheckedIndex === -1) { enabledCheckedIndex = 0; } switch (event.key) { case "ArrowRight": case "ArrowDown": { var nextIndex = (enabledCheckedIndex + 1) % count; updateIndex(nextIndex); break; } case "ArrowLeft": case "ArrowUp": { var _nextIndex = (enabledCheckedIndex - 1 + count) % count; updateIndex(_nextIndex); break; } default: break; } }; var clones = Children.map(children, function (child, index) { var isLastChild = children.length === index + 1; var isFirstChild = index === 0; var spacingProps = isInline ? { mr: spacing } : { mb: spacing }; var isChecked = child.props.value === _value; var handleClick = function handleClick() { setValue(child.props.value); }; var getTabIndex = function getTabIndex() { // If a RadioGroup has no radio selected the first enabled radio should be focusable if (_value == null) { return isFirstChild ? 0 : -1; } else { return isChecked ? 0 : -1; } }; return cloneElement(child, _extends({ ref: function ref(node) { return allNodes.current[index] = node; }, name: name || genId("radio"), onClick: handleClick, tabIndex: getTabIndex(), isChecked: isChecked }, !isLastChild && spacingProps)); }); return jsx(Box, _extends({ role: "radiogroup", onKeyDown: handleKeyDown, "aria-labelledby": id }, rest), clones); }; export default RadioButtonGroup;