@carbon/react
Version:
React components for the Carbon Design System
83 lines (81 loc) • 3.43 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const require_runtime = require("../../_virtual/_rolldown/runtime.js");
const require_usePrefix = require("../../internal/usePrefix.js");
const require_utils = require("../../internal/utils.js");
const require_useMergedRefs = require("../../internal/useMergedRefs.js");
const require_AriaPropTypes = require("../../prop-types/AriaPropTypes.js");
const require_SwitcherItem = require("./SwitcherItem.js");
const require_SwitcherDivider = require("./SwitcherDivider.js");
let classnames = require("classnames");
classnames = require_runtime.__toESM(classnames);
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
let react_jsx_runtime = require("react/jsx-runtime");
//#region src/components/UIShell/Switcher.tsx
/**
* Copyright IBM Corp. 2016, 2026
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const Switcher = (0, react.forwardRef)((props, forwardRef) => {
const switcherRef = (0, react.useRef)(null);
const ref = require_useMergedRefs.useMergedRefs([switcherRef, forwardRef]);
const prefix = require_usePrefix.usePrefix();
const { "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className: customClassName, children, expanded } = props;
const accessibilityLabel = {
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy
};
const className = (0, classnames.default)(`${prefix}--switcher`, { [customClassName || ""]: !!customClassName });
const handleSwitcherItemFocus = ({ currentIndex, direction }) => {
const enabledIndices = react.Children.toArray(children).reduce((acc, child, i) => {
if (require_utils.isComponentElement(child, require_SwitcherItem.default) && Object.keys(child.props).length) acc.push(i);
return acc;
}, []);
const nextValidIndex = (() => {
const nextIndex = enabledIndices.indexOf(currentIndex) + direction;
switch (enabledIndices[nextIndex]) {
case void 0:
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 instanceof HTMLElement) switcherItem.focus();
};
const childrenWithProps = react.Children.toArray(children).map((child, index) => {
if (require_utils.isComponentElement(child, require_SwitcherItem.default)) return (0, react.cloneElement)(child, {
handleSwitcherItemFocus,
index,
key: index,
expanded
});
if (require_utils.isComponentElement(child, require_SwitcherDivider.default)) return (0, react.cloneElement)(child, { key: index });
return child;
});
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
ref,
className,
...accessibilityLabel,
children: childrenWithProps
});
});
Switcher.displayName = "Switcher";
Switcher.propTypes = {
...require_AriaPropTypes.AriaLabelPropType,
children: prop_types.default.node.isRequired,
className: prop_types.default.string,
expanded: prop_types.default.bool
};
//#endregion
exports.default = Switcher;