UNPKG

@carbon/react

Version:

React components for the Carbon Design System

139 lines (133 loc) 4.34 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'); require('./Content.js'); require('./Header.js'); require('./HeaderContainer.js'); require('./HeaderGlobalAction.js'); require('./HeaderGlobalBar.js'); require('./HeaderMenu.js'); require('./HeaderMenuButton.js'); require('./HeaderMenuItem.js'); require('./HeaderName.js'); require('./HeaderNavigation.js'); require('./HeaderPanel.js'); require('./HeaderSideNavItems.js'); var SwitcherItem = require('./SwitcherItem.js'); var SwitcherDivider = require('./SwitcherDivider.js'); require('./SkipToContent.js'); require('./SideNav.js'); require('./SideNavDetails.js'); require('./SideNavDivider.js'); require('./SideNavFooter.js'); require('./SideNavHeader.js'); require('./SideNavIcon.js'); require('./SideNavItem.js'); require('./SideNavItems.js'); require('./SideNavLink.js'); require('./SideNavLinkText.js'); require('./SideNavMenu.js'); require('./SideNavMenuItem.js'); require('./SideNavSwitcher.js'); 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(`${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]; } 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;