@carbon/react
Version:
React components for the Carbon Design System
122 lines (120 loc) • 5.05 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_keys = require("../../internal/keyboard/keys.js");
const require_match = require("../../internal/keyboard/match.js");
const require_navigation = require("../../internal/keyboard/navigation.js");
const require_deprecate = require("../../prop-types/deprecate.js");
const require_utils = require("../../internal/utils.js");
const require_events = require("../../tools/events.js");
const require_index = require("../Layout/index.js");
const require_IconSwitch = require("../Switch/IconSwitch.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/ContentSwitcher/ContentSwitcher.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 ContentSwitcher = ({ children, className, light, lowContrast, selectedIndex: selectedIndexProp = 0, selectionMode = "automatic", size, onChange, ...other }) => {
const prefix = (0, react.useContext)(require_usePrefix.PrefixContext);
const [selectedIndex, setSelectedIndex] = (0, react.useState)(selectedIndexProp);
const prevSelectedIndexRef = (0, react.useRef)(selectedIndexProp);
const switchRefs = (0, react.useRef)([]);
const childrenArray = react.Children.toArray(children);
(0, react.useEffect)(() => {
if (prevSelectedIndexRef.current !== selectedIndexProp) {
setSelectedIndex(selectedIndexProp);
prevSelectedIndexRef.current = selectedIndexProp;
}
}, [selectedIndexProp]);
const handleItemRef = (index) => (ref) => {
if (ref) switchRefs.current[index] = ref;
};
const focusSwitch = (index) => {
const ref = switchRefs.current[index];
if (ref) ref.focus();
};
const isKeyboardEvent = (event) => event && typeof event === "object" && "key" in event;
const handleChildChange = (event) => {
if (typeof event.index === "undefined") return;
const { index } = event;
if (isKeyboardEvent(event) && require_match.matches(event, [require_keys.ArrowRight, require_keys.ArrowLeft])) {
const nextIndex = require_navigation.getNextIndex(event.key, index, childrenArray.length);
if (typeof nextIndex !== "number") return;
focusSwitch(nextIndex);
if (selectionMode !== "manual") {
const child = childrenArray[nextIndex];
setSelectedIndex(nextIndex);
if ((0, react.isValidElement)(child)) onChange({
...event,
index: nextIndex,
name: child.props.name,
text: child.props.text
});
}
} else if (selectedIndex !== index && (isKeyboardEvent(event) ? require_match.matches(event, [require_keys.Enter, require_keys.Space]) : true)) {
setSelectedIndex(index);
focusSwitch(index);
onChange(event);
}
};
const isIconOnly = react.Children.map(children, (child) => {
return require_utils.isComponentElement(child, require_IconSwitch.default);
})?.every((val) => val === true);
const classes = (0, classnames.default)(`${prefix}--content-switcher`, className, {
[`${prefix}--content-switcher--light`]: light,
[`${prefix}--content-switcher--${size}`]: size,
[`${prefix}--layout--size-${size}`]: size,
[`${prefix}--content-switcher--icon-only`]: isIconOnly,
[`${prefix}--content-switcher--low-contrast`]: lowContrast
});
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_index.LayoutConstraint, {
size: {
default: "md",
min: "sm",
max: "lg"
},
...other,
className: classes,
role: "tablist",
onChange: void 0,
children: children && react.Children.map(children, (child, index) => (0, react.cloneElement)(child, {
index,
onClick: require_events.composeEventHandlers([handleChildChange, child.props.onClick]),
onKeyDown: require_events.composeEventHandlers([handleChildChange, child.props.onKeyDown]),
selected: index === selectedIndex,
ref: handleItemRef(index),
size
}))
});
};
ContentSwitcher.displayName = "ContentSwitcher";
ContentSwitcher.propTypes = {
children: prop_types.default.node,
className: prop_types.default.string,
light: require_deprecate.deprecate(prop_types.default.bool, "The `light` prop for `ContentSwitcher` is no longer needed and has been deprecated. It will be removed in the next major release."),
lowContrast: prop_types.default.bool,
onChange: prop_types.default.func.isRequired,
selectedIndex: prop_types.default.number,
selectionMode: prop_types.default.oneOf(["automatic", "manual"]),
size: prop_types.default.oneOf([
"sm",
"md",
"lg"
])
};
//#endregion
exports.ContentSwitcher = ContentSwitcher;