@carbon/react
Version:
React components for the Carbon Design System
118 lines (110 loc) • 4 kB
JavaScript
/**
* 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.
*/
;
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;