@carbon/react
Version:
React components for the Carbon Design System
67 lines (62 loc) • 1.9 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.
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import PropTypes from 'prop-types';
import React, { useRef, useState } from 'react';
import cx from 'classnames';
import { selectorTabbable } from '../../internal/keyboard/navigation.js';
import useIsomorphicEffect from '../../internal/useIsomorphicEffect.js';
import { usePrefix } from '../../internal/usePrefix.js';
/**
* Determine if the node within the provided ref contains content that is tabbable.
*/
function useTabbableContent(ref) {
const [hasTabbableContent, setHasTabbableContent] = useState(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
useIsomorphicEffect(() => {
if (ref.current) {
setHasTabbableContent(!!ref.current.querySelector(selectorTabbable));
}
});
return hasTabbableContent;
}
function TabContent(props) {
const {
className,
selected,
children,
...other
} = props;
const prefix = usePrefix();
const tabContentClasses = cx(`${prefix}--tab-content`, className);
const ref = useRef(null);
const hasTabbableContent = useTabbableContent(ref);
return /*#__PURE__*/React.createElement("div", _extends({
role: "tabpanel"
}, other, {
className: tabContentClasses,
selected: selected,
hidden: !selected,
ref: ref,
tabIndex: hasTabbableContent ? undefined : 0
}), children);
}
TabContent.propTypes = {
/**
* Pass in content to render inside the TabContent
*/
children: PropTypes.node,
/**
* Provide a className for the tab content container
*/
className: PropTypes.string,
/**
* Specify whether the TabContent is selected
*/
selected: PropTypes.bool
};
export { TabContent as default };