UNPKG

@carbon/react

Version:

React components for the Carbon Design System

118 lines (110 loc) 4 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var React = require('react'); var cx = require('classnames'); var usePrefix = require('../../internal/usePrefix.js'); var useMergedRefs = require('../../internal/useMergedRefs.js'); var PropTypes = require('prop-types'); var AriaPropTypes = require('../../prop-types/AriaPropTypes.js'); var SwitcherItem = require('./SwitcherItem.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx); var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes); const Switcher = /*#__PURE__*/React.forwardRef(function Switcher(props, forwardRef) { const switcherRef = React.useRef(null); const ref = useMergedRefs.useMergedRefs([switcherRef, forwardRef]); const prefix = usePrefix.usePrefix(); const { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, className: customClassName, children, expanded } = props; const accessibilityLabel = { 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy }; const className = cx__default["default"](`${prefix}--switcher`, { [customClassName || '']: !!customClassName }); const handleSwitcherItemFocus = ({ currentIndex, direction }) => { const enabledIndices = React__default["default"].Children.toArray(children).reduce((acc, curr, i) => { if (/*#__PURE__*/React__default["default"].isValidElement(curr) && Object.keys(curr.props).length !== 0 && curr.type === SwitcherItem["default"]) { acc.push(i); } return acc; }, []); const nextValidIndex = (() => { const nextIndex = enabledIndices.indexOf(currentIndex) + direction; switch (enabledIndices[nextIndex]) { case undefined: if (direction === -1) { return enabledIndices[enabledIndices.length - 1]; } return enabledIndices[0]; case 0: if (direction === 1) { return enabledIndices[1]; } default: return enabledIndices[nextIndex]; } })(); const switcherItem = switcherRef.current?.children[nextValidIndex]?.children[0]; if (switcherItem) { switcherItem.focus(); } }; const childrenWithProps = React__default["default"].Children.toArray(children).map((child, index) => { // only setup click handlers if onChange event is passed if (/*#__PURE__*/React__default["default"].isValidElement(child) && child.type === SwitcherItem["default"]) { return /*#__PURE__*/React__default["default"].cloneElement(child, { handleSwitcherItemFocus, index, key: index, expanded }); } return /*#__PURE__*/React__default["default"].cloneElement(child, { index, key: index, expanded }); }); return /*#__PURE__*/React__default["default"].createElement("ul", _rollupPluginBabelHelpers["extends"]({ ref: ref, className: className }, accessibilityLabel), childrenWithProps); }); Switcher.displayName = 'Switcher'; Switcher.propTypes = { /** * Required props for accessibility label on the underlying menu */ ...AriaPropTypes.AriaLabelPropType, /** * expects to receive <SwitcherItem /> */ children: PropTypes__default["default"].node.isRequired, /** * Optionally provide a custom class to apply to the underlying `<ul>` node */ className: PropTypes__default["default"].string, /** * Specify whether the panel is expanded */ expanded: PropTypes__default["default"].bool }; exports["default"] = Switcher;