UNPKG

@carbon/react

Version:

React components for the Carbon Design System

114 lines (108 loc) 3.65 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'); var SwitcherDivider = require('./SwitcherDivider.js'); const Switcher = /*#__PURE__*/React.forwardRef((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(`${prefix}--switcher`, { [customClassName || '']: !!customClassName }); const handleSwitcherItemFocus = ({ currentIndex, direction }) => { const enabledIndices = React.Children.toArray(children).reduce((acc, child, i) => { if (/*#__PURE__*/React.isValidElement(child) && child.type === SwitcherItem.default && Object.keys(child.props).length) { 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]; } // eslint-disable-next-line no-fallthrough -- https://github.com/carbon-design-system/carbon/issues/20452 default: return enabledIndices[nextIndex]; } })(); const switcherItem = switcherRef.current?.children[nextValidIndex]?.children[0]; if (switcherItem) { switcherItem.focus(); } }; const childrenWithProps = React.Children.toArray(children).map((child, index) => { if (/*#__PURE__*/React.isValidElement(child) && child.type === SwitcherItem.default) { return /*#__PURE__*/React.cloneElement(child, { handleSwitcherItemFocus, index, key: index, expanded }); } if (/*#__PURE__*/React.isValidElement(child) && child.type === SwitcherDivider.default) { return /*#__PURE__*/React.cloneElement(child, { key: index }); } return child; }); return /*#__PURE__*/React.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.node.isRequired, /** * Optionally provide a custom class to apply to the underlying `<ul>` node */ className: PropTypes.string, /** * Specify whether the panel is expanded */ expanded: PropTypes.bool }; exports.default = Switcher;